Compare commits

...

11 Commits

Author SHA1 Message Date
meilin.huang
adc65439e4 feat: redis支持flushdb、菜单资源支持拖拽排序、禁用等 2023-06-15 19:18:29 +08:00
Coder慌
445cf3716b !44 feat: sql字段提示优化
Merge pull request !44 from zongyangleo/dev_20230613
2023-06-13 09:03:53 +00:00
刘宗洋
f4b59b8503 feat:单表查询支持无别名提示字段 2023-06-13 17:01:39 +08:00
刘宗洋
4f08975df2 fix:修复数据库schema提示 2023-06-13 15:57:08 +08:00
刘宗洋
570db453d7 feat:sql字段提示优化 2023-06-13 14:54:52 +08:00
meilin.huang
b93984bf6f refactor: json tag完善 2023-06-11 19:59:35 +08:00
meilin.huang
e483db1b97 fix: 哨兵节点密码调整 2023-06-06 20:51:54 +08:00
meilin.huang
17d96acceb refactor: interface{} -> any
feat: 新增外链菜单
2023-06-01 12:31:32 +08:00
meilin.huang
9900b236ef refactor: 组件升级、代码优化 2023-05-24 12:32:17 +08:00
Coder慌
4fa52412c1 !42 fix:修改表sql,如果是修改的主键,sql bug修复
Merge pull request !42 from zongyangleo/dev_20230417
2023-04-17 09:40:11 +00:00
刘宗洋
0076869deb fix:修改表:如果修改的字段是主键 2023-04-17 16:21:06 +08:00
147 changed files with 2175 additions and 1449 deletions

View File

@@ -115,7 +115,7 @@ function buildxDocker() {
echo_yellow "-------------------docker buildx构建镜像开始-------------------"
imageVersion=$1
cd ${server_folder}
imageName="mayflygo/mayfly-go:${imageVersion}"
imageName="ccr.ccs.tencentyun.com/mayfly/mayfly-go:${imageVersion}"
docker buildx build --push --platform linux/amd64,linux/arm64 -t "${imageName}" .
echo_green "docker多版本镜像构建完成->[${imageName}]"
echo_yellow "-------------------docker buildx构建镜像结束-------------------"

View File

@@ -10,27 +10,27 @@
},
"dependencies": {
"@element-plus/icons-vue": "^2.1.0",
"asciinema-player": "^3.2.0",
"axios": "^1.3.4",
"asciinema-player": "^3.3.0",
"axios": "^1.4.0",
"countup.js": "^2.0.7",
"cropperjs": "^1.5.11",
"echarts": "^5.4.0",
"element-plus": "^2.3.2",
"element-plus": "^2.3.5",
"jsencrypt": "^3.3.1",
"lodash": "^4.17.21",
"mitt": "^3.0.0",
"monaco-editor": "^0.37.1",
"monaco-editor": "^0.38.0",
"monaco-sql-languages": "^0.11.0",
"monaco-themes": "^0.4.2",
"monaco-themes": "^0.4.4",
"nprogress": "^0.2.0",
"pinia": "^2.0.33",
"pinia": "^2.1.3",
"screenfull": "^6.0.2",
"sortablejs": "^1.13.0",
"sql-formatter": "^12.1.2",
"vue": "^3.2.47",
"vue": "^3.3.4",
"vue-clipboard3": "^1.0.1",
"vue-router": "^4.1.6",
"xterm": "^5.1.0",
"vue-router": "^4.2.2",
"xterm": "^5.2.1",
"xterm-addon-fit": "^0.7.0"
},
"devDependencies": {
@@ -46,11 +46,11 @@
"eslint": "^8.35.0",
"eslint-plugin-vue": "^8.2.0",
"prettier": "^2.3.0",
"sass": "^1.58.0",
"sass": "^1.62.0",
"sass-loader": "^13.2.0",
"typescript": "^5.0.2",
"vite": "^4.2.0",
"vue-eslint-parser": "^8.0.1"
"vite": "^4.3.9",
"vue-eslint-parser": "^9.1.1"
},
"browserslist": [
"> 1%",

View File

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

View File

@@ -2,7 +2,7 @@
<div class="monaco-editor" style="border: 1px solid #ccc;">
<div class="monaco-editor-content" ref="monacoTextarea" :style="{ height: height }"></div>
<el-select v-if="canChangeMode" class="code-mode-select" v-model="languageMode" @change="changeLanguage">
<el-option v-for="mode in languages" :key="mode.value" :label="mode.label" :value="mode.value"> </el-option>
<el-option v-for="mode in languageArr" :key="mode.value" :label="mode.label" :value="mode.value"> </el-option>
</el-select>
</div>
</template>
@@ -54,7 +54,7 @@ const props = defineProps({
//定义事件
const emit = defineEmits(['update:modelValue'])
const languages = [
const languageArr = [
{
value: 'shell',
label: 'Shell',

View File

@@ -7,7 +7,7 @@
if (el) columnsAsideOffsetTopRefs[k] = el;
}
" :class="{ 'layout-columns-active': state.liIndex === k }" :title="v.meta.title">
<div class="layout-columns-aside-li-box" v-if="!v.meta.link || (v.meta.link && v.meta.isIframe)">
<div class="layout-columns-aside-li-box" v-if="!v.meta.link || (v.meta.link && v.meta.linkType == 1)">
<i :class="v.meta.icon"></i>
<div class="layout-columns-aside-li-box-title font12">
{{ v.meta.title && v.meta.title.length >= 4 ? v.meta.title.substr(0, 4) : v.meta.title }}

View File

@@ -1,15 +1,15 @@
<template>
<el-main class="layout-main">
<el-scrollbar class="layout-scrollbar" ref="layoutScrollbarRef"
v-show="!state.currentRouteMeta.link && !state.currentRouteMeta.isIframe"
v-show="!state.currentRouteMeta.link && state.currentRouteMeta.linkType != 1"
:style="{ minHeight: `calc(100vh - ${state.headerHeight}` }">
<LayoutParentView />
<Footer v-if="themeConfig.isFooter" />
</el-scrollbar>
<Link :style="{ height: `calc(100vh - ${state.headerHeight}` }" :meta="state.currentRouteMeta"
v-if="state.currentRouteMeta.link && !state.currentRouteMeta.isIframe" />
v-if="state.currentRouteMeta.link && state.currentRouteMeta.linkType == 2" />
<Iframes :style="{ height: `calc(100vh - ${state.headerHeight}` }" :meta="state.currentRouteMeta"
v-if="state.currentRouteMeta.link && state.currentRouteMeta.isIframe && state.isShowLink"
v-if="state.currentRouteMeta.link && state.currentRouteMeta.linkType == 1 && state.isShowLink"
@getCurrentRouteMeta="onGetCurrentRouteMeta" />
</el-main>
</template>

View File

@@ -1,8 +1,8 @@
<template>
<div class="layout-footer mt15" v-show="isDelayFooter">
<div class="layout-footer-warp">
<div>vue-next-adminMade by lyt with </div>
<div class="mt5">mayfly</div>
<div>Made by mayfly with </div>
<div class="mt5">mayfly-go</div>
</div>
</div>
</template>

View File

@@ -7,7 +7,7 @@
<script setup lang="ts" name="layout">
import { onBeforeMount, onUnmounted } from 'vue';
import { getLocal, setLocal } from '@/common/utils/storage.ts';
import { getLocal, setLocal } from '@/common/utils/storage';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '@/store/themeConfig';
import Defaults from '@/views/layout/main/defaults.vue';

View File

@@ -87,7 +87,7 @@ const getRoutes = (routes: any) => {
// 当前菜单选中时
const onHandleSelect = (item: any) => {
let { path, redirect } = item;
if (item.meta.link && !item.meta.isIframe) window.open(item.meta.link);
if (item.meta.link && item.meta.linkType == 2) window.open(item.meta.link);
else if (redirect) router.push(redirect);
else router.push(path);
closeSearch();

View File

@@ -38,7 +38,7 @@ import { useRoute, useRouter, onBeforeRouteUpdate } from 'vue-router';
import screenfull from 'screenfull';
import { storeToRefs } from 'pinia';
import { useThemeConfig } from '@/store/themeConfig';
import { getSession, setSession, removeSession } from '@/common/utils/storage.ts';
import { getSession, setSession, removeSession } from '@/common/utils/storage';
import mittBus from '@/common/utils/mitt';
import Sortable from 'sortablejs';
import Contextmenu from '@/views/layout/navBars/tagsView/contextmenu.vue';
@@ -99,13 +99,14 @@ const addTagsView = (path: string, to: any = null) => {
if (!to) {
to = route;
}
path = decodeURI(path);
for (let tv of state.tagsViewList) {
if (tv.fullPath === path) {
return false;
}
}
const tagView = { ...to }
// 防止Converting circular structure to JSON错误
tagView.matched = null;

View File

@@ -4,15 +4,15 @@
<el-menu router :default-active="state.defaultActive" background-color="transparent" mode="horizontal"
@select="onHorizontalSelect">
<template v-for="val in menuLists">
<el-submenu :index="val.path" v-if="val.children && val.children.length > 0" :key="val.path">
<el-sub-menu :index="val.path" v-if="val.children && val.children.length > 0" :key="val.path">
<template #title>
<SvgIcon :name="val.meta.icon"/>
<span>{{ val.meta.title }}</span>
</template>
<SubItem :chil="val.children" />
</el-submenu>
</el-sub-menu>
<el-menu-item :index="val.path" :key="val?.path" v-else>
<template #title v-if="!val.meta.link || (val.meta.link && val.meta.isIframe)">
<template #title v-if="!val.meta.link || (val.meta.link && val.meta.linkType == 1)">
<SvgIcon :name="val.meta.icon"/>
{{ val.meta.title }}
</template>
@@ -58,15 +58,15 @@ const menuLists = computed(() => {
// 设置横向滚动条可以鼠标滚轮滚动
const onElMenuHorizontalScroll = (e: any) => {
const eventDelta = e.wheelDelta || -e.deltaY * 40;
proxy.$refs.elMenuHorizontalScrollRef.$refs.wrap.scrollLeft =
proxy.$refs.elMenuHorizontalScrollRef.$refs.wrap.scrollLeft + eventDelta / 4;
proxy.$refs.elMenuHorizontalScrollRef.$refs.wrapRef.scrollLeft =
proxy.$refs.elMenuHorizontalScrollRef.$refs.wrapRef.scrollLeft + eventDelta / 4;
};
// 初始化数据,页面刷新时,滚动条滚动到对应位置
const initElMenuOffsetLeft = () => {
nextTick(() => {
let els: any = document.querySelector('.el-menu.el-menu--horizontal li.is-active');
if (!els) return false;
proxy.$refs.elMenuHorizontalScrollRef.$refs.wrap.scrollLeft = els.offsetLeft;
proxy.$refs.elMenuHorizontalScrollRef.$refs.wrapRef.scrollLeft = els.offsetLeft;
});
};
// 设置页面当前路由高亮

View File

@@ -8,7 +8,7 @@
<sub-item :chil="val.children" />
</el-sub-menu>
<el-menu-item :index="val.path" :key="val?.path" v-else>
<template v-if="!val.meta.link || (val.meta.link && val.meta.isIframe)">
<template v-if="!val.meta.link || (val.meta.link && val.meta.linkType == 1)">
<SvgIcon :name="val.meta.icon"/>
<span>{{ val.meta.title }}</span>
</template>

View File

@@ -11,7 +11,7 @@
</el-sub-menu>
<el-menu-item :index="val.path" :key="val?.path" v-else>
<SvgIcon :name="val.meta.icon"/>
<template #title v-if="!val.meta.link || (val.meta.link && val.meta.isIframe)">
<template #title v-if="!val.meta.link || (val.meta.link && val.meta.linkType == 1)">
<span>{{ val.meta.title }}</span>
</template>
<template #title v-else>

View File

@@ -48,14 +48,17 @@ const showTagInfo = async () => {
const tagPaths = [];
let nowTag = '';
for (let tagStr of tagStrs) {
if (nowTag) {
nowTag = `${nowTag}/${tagStr}`
} else {
nowTag = tagStr
if (!tagStr) {
continue;
}
tagPaths.push(nowTag)
if (nowTag) {
nowTag = `${nowTag}${tagStr}/`;
} else {
nowTag = tagStr + '/';
}
tagPaths.push(nowTag);
}
state.tags = await tagApi.listByQuery.request({ tagPaths: tagPaths.join(',') })
state.tags = await tagApi.listByQuery.request({ tagPaths: tagPaths.join(',') });
}
</script>

View File

@@ -677,7 +677,7 @@ const showCreateDdl = async (row: any) => {
db: state.db,
tableName: row.tableName,
});
state.ddlDialog.ddl = res[0]['Create Table'];
state.ddlDialog.ddl = res;
state.ddlDialog.visible = true;
};

View File

@@ -2,7 +2,8 @@
<div>
<el-row>
<el-col :span="4">
<el-button type="primary" icon="plus" @click="addQueryTab({ id: nowDbInst.id }, state.db)"
<el-button type="primary" icon="plus"
@click="addQueryTab({ id: nowDbInst.id, dbs: nowDbInst.databases }, state.db)"
size="small">新建查询</el-button>
</el-col>
<el-col :span="20" v-if="state.db">
@@ -23,7 +24,8 @@
</el-row>
<el-row type="flex">
<el-col :span="4" style="border-left: 1px solid #eee; margin-top: 10px">
<tag-tree ref="tagTreeRef" @node-click="nodeClick" :load="loadNode" :load-contextmenu-items="getContextmenuItems" @current-contextmenu-click="onCurrentContextmenuClick"
<tag-tree ref="tagTreeRef" @node-click="nodeClick" :load="loadNode"
:load-contextmenu-items="getContextmenuItems" @current-contextmenu-click="onCurrentContextmenuClick"
:height="state.tagTreeHeight">
<template #prefix="{ data }">
<span v-if="data.type == NodeType.DbInst">
@@ -245,8 +247,8 @@ const nodeClick = async (data: any) => {
const nodeKey = data.key;
const dataType = data.type;
// 点击数据库,修改当前数据库信息
if (dataType === NodeType.Db || dataType === NodeType.SqlMenu || dataType === NodeType.TableMenu) {
changeSchema({ id: params.id, name: params.name, type: params.type, tagPath: params.tagPath }, params.db);
if (dataType === NodeType.Db || dataType === NodeType.SqlMenu || dataType === NodeType.TableMenu || dataType === NodeType.DbInst) {
changeSchema({ id: params.id, name: params.name, type: params.type, tagPath: params.tagPath, databases: params.database }, params.db);
return;
}
@@ -296,9 +298,9 @@ const getTables = async (params: any) => {
/**
* 加载用户保存的sql脚本
*
* @param inst
* @param schema
*
* @param inst
* @param schema
*/
const loadSqls = async (id: any, db: string, dbs: any) => {
const sqls = await dbApi.getSqlNames.request({ id: id, db: db, })
@@ -440,7 +442,7 @@ const reloadTables = (nodeKey: string) => {
const registerSqlCompletionItemProvider = () => {
// 参考 https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-completion-provider-example
self.completionItemProvider = self.completionItemProvider || monaco.languages.registerCompletionItemProvider('sql', {
triggerCharacters: ['.'],
triggerCharacters: ['.', ' '],
provideCompletionItems: async (model: editor.ITextModel, position: Position): Promise<languages.CompletionList | null | undefined> => {
let word = model.getWordUntilPosition(position);
const nowTab = state.tabs.get(state.activeName);
@@ -490,16 +492,46 @@ const registerSqlCompletionItemProvider = () => {
// // const nextToken = nextTokens[0].toLowerCase()
const tokens = textBeforePointer.trim().split(/\s+/)
const lastToken = tokens[tokens.length - 1].toLowerCase()
const secondToken = tokens.length > 2 && tokens[tokens.length - 2].toLowerCase() || ''
const dbs = nowTab.params && nowTab.params.dbs;
const dbs = nowTab.params?.dbs?.split(' ') || [];
// console.log("光标前文本:=>" + textBeforePointerMulti)
// console.log("最后输入的:=>" + lastToken)
if (lastToken.endsWith('.')) {
let suggestions: languages.CompletionItem[] = []
const tables = await dbInst.loadTables(db);
async function hintTableColumns(tableName: any, db: any) {
let dbHits = await dbInst.loadDbHints(db)
let columns = dbHits[tableName]
let suggestions: languages.CompletionItem[] = []
columns?.forEach((a: string, index: any) => {
// 字段数据格式 字段名 字段注释, 如: create_time [datetime][创建时间]
const nameAndComment = a.split(" ")
const fieldName = nameAndComment[0]
suggestions.push({
label: {
label: a,
description: 'column'
},
kind: monaco.languages.CompletionItemKind.Property,
detail: '', // 不显示detail, 否则选中时备注等会被遮挡
insertText: fieldName + ' ', // create_time
range,
sortText: 100 + index + '' // 使用表字段声明顺序排序,排序需为字符串类型
});
})
return suggestions
}
if (lastToken.indexOf('.') > -1 || secondToken.indexOf('.') > -1) {
// 如果是.触发代码提示,则进行【 库.表名联想 】 或 【 表别名.表字段联想 】
let str = lastToken.substring(0, lastToken.lastIndexOf('.'))
// 库.表名联想
if (lastToken.trim().startsWith('.')) {
str = secondToken
}
// 库.表名联想
if (dbs && dbs.filter((a: any) => a === str)?.length > 0) {
let tables = await dbInst.loadTables(str)
let suggestions: languages.CompletionItem[] = []
@@ -522,36 +554,43 @@ const registerSqlCompletionItemProvider = () => {
// 表别名.表字段联想
let tableInfo = getTableByAlias(sql, db, str)
if (tableInfo.tableName) {
let table = tableInfo.tableName
let tableName = tableInfo.tableName
let db = tableInfo.dbName;
// 取出表名并提示
let dbHits = await dbInst.loadDbHints(db)
let columns = dbHits[table]
let suggestions: languages.CompletionItem[] = []
columns?.forEach((a: string, index: any) => {
// 字段数据格式 字段名 字段注释, 如: create_time [datetime][创建时间]
const nameAndComment = a.split(" ")
const fieldName = nameAndComment[0]
suggestions.push({
label: {
label: a,
description: 'column'
},
kind: monaco.languages.CompletionItemKind.Property,
detail: '', // 不显示detail, 否则选中时备注等会被遮挡
insertText: fieldName + ' ', // create_time
range,
sortText: 100 + index + '' // 使用表字段声明顺序排序,排序需为字符串类型
});
})
return { suggestions }
let suggestions = await hintTableColumns(tableName, db);
if (suggestions.length > 0) {
return { suggestions };
}
}
return { suggestions: [] }
} else {
// 如果sql里含有表名则提示表字段
let mat = textBeforePointerMulti.match(/from\n*\s+\n*(\w+)\n*\s+\n*/i)
if (mat && mat.length > 1) {
let tableName = mat[1]
// 取出表名并提示
let addSuggestions = await hintTableColumns(tableName, db);
if (addSuggestions.length > 0) {
suggestions = suggestions.concat(addSuggestions)
}
}
}
// 名联想
// 名联想
tables.forEach((tableMeta: any) => {
const { tableName, tableComment } = tableMeta;
suggestions.push({
label: {
label: tableName + ' - ' + tableComment,
description: 'table'
},
kind: monaco.languages.CompletionItemKind.File,
detail: tableComment,
insertText: tableName + ' ',
range
});
});
let suggestions: languages.CompletionItem[] = []
// mysql关键字
sqlLanguage.keywords.forEach((item: any) => {
suggestions.push({
@@ -602,7 +641,7 @@ const registerSqlCompletionItemProvider = () => {
})
// 库名提示
if (dbs) {
if (dbs && dbs.length > 0) {
dbs.forEach((a: any) => {
suggestions.push({
label: {
@@ -616,22 +655,6 @@ const registerSqlCompletionItemProvider = () => {
})
}
const tables = await dbInst.loadTables(db);
// 表名联想
tables.forEach((tableMeta: any) => {
const { tableName, tableComment } = tableMeta
suggestions.push({
label: {
label: tableName + ' - ' + tableComment,
description: 'table'
},
kind: monaco.languages.CompletionItemKind.File,
detail: tableComment,
insertText: tableName + ' ',
range
});
})
// 默认提示
return {
suggestions: suggestions

View File

@@ -268,6 +268,10 @@ const submitUpdateFields = () => {
let primaryKeyName = a.primaryKeyName;
a.fields.forEach(f => {
sql += ` ${f.fieldName} = ${DbInst.wrapColumnValue(f.fieldType, f.newValue)},`
// 如果修改的字段是主键
if(f.fieldName === primaryKeyName){
primaryKey = f.oldValue
}
divs.push(f.div)
})
sql = sql.substring(0, sql.length - 1)

View File

@@ -101,7 +101,7 @@
</el-dialog>
<el-dialog v-model="addDataDialog.visible" :title="addDataDialog.title" :destroy-on-close="true" width="600px">
<el-form ref="dataForm" :model="addDataDialog.data" label-width="160px">
<el-form ref="dataForm" :model="addDataDialog.data" label-width="160px" size="small">
<el-form-item v-for="column in columns" class="w100" :prop="column.columnName" :label="column.columnName"
:required="column.nullable != 'YES' && column.columnKey != 'PRI'">
<el-input-number v-if="DbInst.isNumber(column.columnType)"

View File

@@ -30,6 +30,9 @@ export class DbInst {
*/
dbs: Map<string, Db> = new Map()
/** 数据库schema多个用空格隔开 */
databases: string
/**
* 默认查询分页数量
*/
@@ -124,7 +127,7 @@ export class DbInst {
/**
* 执行sql
*
*
* @param sql sql
* @param remark 执行备注
*/
@@ -186,7 +189,7 @@ export class DbInst {
return `DELETE FROM ${table} WHERE ${primaryKeyColumnName} IN (${ids})`;
}
/*
/*
* 弹框提示是否执行sql
*/
promptExeSql = (db: string, sql: string, cancelFunc: any = null, successFunc: any = null) => {
@@ -216,6 +219,7 @@ export class DbInst {
dbInst.id = inst.id;
dbInst.name = inst.name;
dbInst.type = inst.type;
dbInst.databases = inst.databases;
dbInstCache.set(dbInst.id, dbInst);
return dbInst;
@@ -283,14 +287,14 @@ export class DbInst {
/**
* 判断字段类型是否为数字类型
* @param columnType 字段类型
* @returns
* @returns
*/
static isNumber(columnType: string) {
return columnType.match(/int|double|float|nubmer|decimal|byte|bit/gi);
};
/**
*
*
* @param str 字符串
* @param tableData 表数据
* @param flag 标志
@@ -483,4 +487,4 @@ export type FieldsMeta = {
oldValue: string
// 新值
newValue: string
}
}

View File

@@ -4,11 +4,11 @@
:show-close="true" :destroy-on-close="true" width="900px">
<el-form :model="form" ref="scriptForm" label-width="50px" size="small">
<el-form-item prop="method" label="名称">
<el-input v-model.trim="form.name" placeholder="请输入名称"></el-input>
<el-input v-model="form.name" placeholder="请输入名称"></el-input>
</el-form-item>
<el-form-item prop="description" label="描述">
<el-input v-model.trim="form.description" placeholder="请输入描述"></el-input>
<el-input v-model="form.description" placeholder="请输入描述"></el-input>
</el-form-item>
<el-form-item prop="type" label="类型">
@@ -24,13 +24,13 @@
<el-form-item :key="param" v-for="(param, index) in params" prop="params" :label="`参数${index + 1}`">
<el-row>
<el-col :span="5">
<el-input v-model="param.model" placeholder="内容中用{{.model}}替换"></el-input>
<el-input v-model.trim="param.model" placeholder="内容中用{{.model}}替换"></el-input>
</el-col>
<span :span="1">
<el-divider direction="vertical" border-style="dashed" />
</span>
<el-col :span="4">
<el-input v-model="param.name" placeholder="字段名"></el-input>
<el-input v-model.trim="param.name" placeholder="字段名"></el-input>
</el-col>
<span :span="1">
<el-divider direction="vertical" border-style="dashed" />

View File

@@ -48,6 +48,7 @@
<el-button @click="scan()" icon="bottom" plain>scan</el-button>
<el-button @click="showNewKeyDialog" type="primary" icon="plus" plain
v-auth="'redis:data:save'"></el-button>
<el-button @click="flushDb" type="danger" plain v-auth="'redis:data:save'">flush</el-button>
</el-form-item>
<div style="float: right">
<span>keys: {{ state.dbsize }}</span>
@@ -338,11 +339,6 @@ const showKeyDetail = async (row: any) => {
state.keyDetailDialog.visible = true;
};
const closeKeyDetail = () => {
// state.keyDetailDialog.visible = false;
}
const showNewKeyDialog = () => {
notNull(state.scanParam.id, '请先选择redis');
notNull(state.scanParam.db, "请选择要操作的库")
@@ -350,6 +346,24 @@ const showNewKeyDialog = () => {
state.newKeyDialog.visible = true;
}
const flushDb = () => {
ElMessageBox.confirm(`确定清空[${state.scanParam.db}]库的所有key?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}).then(() => {
redisApi.flushDb
.request({
id: state.scanParam.id,
db: state.scanParam.db,
})
.then(() => {
ElMessage.success('清除成功!');
searchKey();
});
}).catch(() => { });
}
const cancelNewKey = () => {
resetKeyDetailInfo();
state.newKeyDialog.visible = false;

View File

@@ -33,6 +33,7 @@ export const redisApi = {
del: Api.newDelete("/redis/{id}/{db}/scan/{cursor}/{count}"),
delKey: Api.newDelete("/redis/{id}/{db}/key"),
flushDb: Api.newDelete("/redis/{id}/{db}/flushdb"),
lrem: Api.newPost("/redis/{id}/{db}/lrem"),
getListValue: Api.newGet("/redis/{id}/{db}/list-value"),

View File

@@ -6,7 +6,8 @@ export const resourceApi = {
save: Api.newPost("/sys/resources"),
update: Api.newPut("/sys/resources/{id}"),
del: Api.newDelete("/sys/resources/{id}"),
changeStatus: Api.newPut("/sys/resources/{id}/{status}")
changeStatus: Api.newPut("/sys/resources/{id}/{status}"),
sort: Api.newPost("/sys/resources/sort")
}
export const roleApi = {

View File

@@ -1,7 +1,7 @@
<template>
<div class="system-menu-dialog-container layout-pd">
<el-dialog :title="title" :destroy-on-close="true" v-model="dialogVisible" width="800px">
<el-form :model="form" :inline="true" ref="menuForm" :rules="rules" label-width="95px">
<el-form :model="form" :inline="true" ref="menuForm" :rules="rules" label-width="100px">
<el-row :gutter="35">
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item class="w100" prop="type" label="类型" required>
@@ -19,31 +19,60 @@
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item class="w100" prop="code" label="path|code">
<template #label>
path|code
<el-tooltip effect="dark" content="菜单类型则为访问路径(若菜单路径不以'/'开头则访问地址会自动拼接父菜单路径)、否则为资源唯一编码"
placement="top">
<el-icon>
<question-filled />
</el-icon>
</el-tooltip>
</template>
<el-input v-model.trim="form.code" placeholder="菜单不以'/'开头则自动拼接父菜单路径"></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20">
<el-form-item class="w100" label="序号" prop="weight" required>
<el-input v-model.trim="form.weight" type="number" placeholder="请输入序号"></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20" v-if="form.type === menuTypeValue">
<el-form-item class="w100" label="图标">
<icon-selector v-model="form.meta.icon" />
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20" v-if="form.type === menuTypeValue">
<el-form-item class="w100" prop="code" label="路由名">
<el-form-item class="w100">
<template #label>
路由名
<el-tooltip effect="dark" content="与vue的组件名一致才可使组件缓存生效如ResourceList" placement="top">
<el-icon>
<question-filled />
</el-icon>
</el-tooltip>
</template>
<el-input v-model.trim="form.meta.routeName" placeholder="请输入路由名称"></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20" v-if="form.type === menuTypeValue">
<el-form-item class="w100" prop="code" label="组件路径">
<el-form-item class="w100" prop="code">
<template #label>
组件路径
<el-tooltip effect="dark" content="访问的组件路径,如:`system/resource/ResourceList`,默认在`views`目录下"
placement="top">
<el-icon>
<question-filled />
</el-icon>
</el-tooltip>
</template>
<el-input v-model.trim="form.meta.component" placeholder="请输入组件路径"></el-input>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20" v-if="form.type === menuTypeValue">
<el-form-item class="w100" prop="code" label="是否缓存">
<el-form-item class="w100" prop="isKeepAlive">
<template #label>
是否缓存
<el-tooltip effect="dark" content="选择是则会被`keep-alive`缓存(重新进入页面不会刷新页面及重新请求数据)需要路由名与vue的组件名一致" placement="top">
<el-icon>
<question-filled />
</el-icon>
</el-tooltip>
</template>
<el-select v-model="form.meta.isKeepAlive" placeholder="请选择" class="w100">
<el-option v-for="item in trueFalseOption" :key="item.value" :label="item.label"
:value="item.value"> </el-option>
@@ -51,7 +80,15 @@
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20" v-if="form.type === menuTypeValue">
<el-form-item class="w100" prop="code" label="是否隐藏">
<el-form-item class="w100">
<template #label>
是否隐藏
<el-tooltip effect="dark" content="选择隐藏则路由将不会出现在菜单栏中,但仍然可以访问。禁用则不可访问与操作" placement="top">
<el-icon>
<question-filled />
</el-icon>
</el-tooltip>
</template>
<el-select v-model="form.meta.isHide" placeholder="请选择" class="w100">
<el-option v-for="item in trueFalseOption" :key="item.value" :label="item.label"
:value="item.value"> </el-option>
@@ -67,17 +104,26 @@
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20" v-if="form.type === menuTypeValue">
<el-form-item class="w100" prop="code" label="是否iframe">
<el-select class="w100" @change="changeIsIframe" v-model="form.meta.isIframe" placeholder="请选择">
<el-option v-for="item in trueFalseOption" :key="item.value" :label="item.label"
:value="item.value"> </el-option>
<el-form-item class="w100" prop="linkType">
<template #label>
外链
<el-tooltip effect="dark" content="内嵌: 以iframe展示、外链: 新标签打开" placement="top">
<el-icon>
<question-filled />
</el-icon>
</el-tooltip>
</template>
<el-select class="w100" @change="changeIsIframe" v-model="form.meta.linkType" placeholder="请选择">
<el-option :key="0" label="否" :value="0"> </el-option>
<el-option :key="1" label="内嵌" :value="1"> </el-option>
<el-option :key="2" label="外链" :value="2"> </el-option>
</el-select>
</el-form-item>
</el-col>
<el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12" class="mb20"
v-if="form.type === menuTypeValue && form.meta.isIframe">
<el-form-item prop="code" label="iframe地址" class="w100">
<el-input v-model.trim="form.meta.link" placeholder="请输入iframe urlhttp://xxx.com"></el-input>
v-if="form.type === menuTypeValue && form.meta.linkType > 0">
<el-form-item prop="code" label="链接地址" class="w100">
<el-input v-model.trim="form.meta.link" placeholder="外链/内嵌的链接地址http://xxx.com"></el-input>
</el-form-item>
</el-col>
</el-row>
@@ -131,7 +177,7 @@ const defaultMeta = {
isKeepAlive: true,
isHide: false,
isAffix: false,
isIframe: false,
linkType: 0,
link: '',
};
@@ -143,13 +189,6 @@ const rules = {
trigger: ['change', 'blur'],
},
],
weight: [
{
required: true,
message: '请输入序号',
trigger: ['change', 'blur'],
},
],
}
const trueFalseOption = [
@@ -171,7 +210,6 @@ const state = reactive({
pid: null,
code: null,
type: null,
weight: 0,
meta: {
routeName: '',
icon: '',
@@ -180,7 +218,7 @@ const state = reactive({
isKeepAlive: true,
isHide: false,
isAffix: false,
isIframe: false,
linkType: 0,
link: '',
},
},
@@ -210,7 +248,7 @@ watch(props, (newValue: any) => {
state.form.meta.isKeepAlive = meta.isKeepAlive ? true : false;
state.form.meta.isHide = meta.isHide ? true : false;
state.form.meta.isAffix = meta.isAffix ? true : false;
state.form.meta.isIframe = meta.isIframe ? true : false;
state.form.meta.linkType = meta.linkType;
});
// 改变iframe字段如果为是则设置默认的组件
@@ -230,7 +268,6 @@ const btnOk = () => {
} else {
submitForm.meta = null as any;
}
submitForm.weight = parseInt(submitForm.weight as any);
menuForm.value.validate((valid: any) => {
if (valid) {
resourceApi.save.request(submitForm).then(() => {
@@ -263,8 +300,8 @@ const parseMenuMeta = (meta: any) => {
if (meta.isAffix) {
metaForm.isAffix = true;
}
if (meta.isIframe) {
metaForm.isIframe = true;
if (meta.linkType) {
metaForm.linkType = meta.linkType;
}
if (meta.link) {
metaForm.link = meta.link;

View File

@@ -3,19 +3,20 @@
<div class="toolbar">
<div>
<span style="font-size: 14px">
<SvgIcon name="info-filled" />红色字体表示禁用状态
<SvgIcon name="info-filled" />红色橙色字体表示禁用状态
</span>
</div>
<el-button v-auth="'resource:add'" type="primary" icon="plus" @click="addResource(false)">添加</el-button>
</div>
<el-tree class="none-select" :indent="38" node-key="id" :props="props" :data="data"
@node-expand="handleNodeExpand" @node-collapse="handleNodeCollapse"
:default-expanded-keys="defaultExpandedKeys" :expand-on-click-node="false">
<el-tree class="none-select" :indent="38" node-key="id" :props="props" :data="data" @node-expand="handleNodeExpand"
@node-collapse="handleNodeCollapse" :default-expanded-keys="defaultExpandedKeys" :expand-on-click-node="false"
draggable :allow-drop="allowDrop" @node-drop="handleDrop">
<template #default="{ data }">
<span class="custom-tree-node">
<span style="font-size: 13px" v-if="data.type === menuTypeValue">
<span style="color: #3c8dbc"></span>
{{ data.name }}
<span v-if="data.status == 1">{{ data.name }}</span>
<span v-if="data.status == -1" style="color: #e6a23c;">{{ data.name }}</span>
<span style="color: #3c8dbc"></span>
<el-tag v-if="data.children !== null" size="small">{{ data.children.length }}</el-tag>
</span>
@@ -31,21 +32,17 @@
<el-link v-auth="'resource:update'" @click.prevent="editResource(data)" class="ml5" type="primary"
icon="edit" :underline="false" />
<el-link v-auth="'resource:add'" @click.prevent="addResource(data)"
v-if="data.type === menuTypeValue" icon="circle-plus" :underline="false"
type="success" class="ml5" />
<el-link v-auth="'resource:add'" @click.prevent="addResource(data)" v-if="data.type === menuTypeValue"
icon="circle-plus" :underline="false" type="success" class="ml5" />
<el-link v-auth="'resource:changeStatus'" @click.prevent="changeStatus(data, -1)"
v-if="data.status === 1 && data.type === permissionTypeValue"
icon="circle-close" :underline="false" type="warning" class="ml5" />
v-if="data.status === 1" icon="circle-close" :underline="false" type="warning" class="ml5" />
<el-link v-auth="'resource:changeStatus'" @click.prevent="changeStatus(data, 1)"
v-if="data.status === -1 && data.type === permissionTypeValue"
type="success" icon="circle-check" :underline="false" plain class="ml5" />
v-if="data.status === -1" type="success" icon="circle-check" :underline="false" plain class="ml5" />
<el-link v-auth="'resource:delete'" v-if="data.children == null && data.name !== '首页'"
@click.prevent="deleteMenu(data)" type="danger" icon="delete" :underline="false" plain
class="ml5" />
<el-link v-auth="'resource:delete'" @click.prevent="deleteMenu(data)" type="danger" icon="delete"
:underline="false" plain class="ml5" />
</span>
</template>
</el-tree>
@@ -61,7 +58,9 @@
</el-descriptions-item>
<el-descriptions-item label="名称">{{ infoDialog.data.name }}</el-descriptions-item>
<el-descriptions-item label="code[菜单path]">{{ infoDialog.data.code }}</el-descriptions-item>
<el-descriptions-item label="序号">{{ infoDialog.data.weight }}</el-descriptions-item>
<el-descriptions-item v-if="infoDialog.data.type == menuTypeValue" label="图标">
<SvgIcon :name="infoDialog.data.meta.icon" />
</el-descriptions-item>
<el-descriptions-item v-if="infoDialog.data.type == menuTypeValue" label="路由名">
{{ infoDialog.data.meta.routeName }}
</el-descriptions-item>
@@ -77,11 +76,11 @@
<el-descriptions-item v-if="infoDialog.data.type == menuTypeValue" label="tag不可删除">
{{ infoDialog.data.meta.isAffix ? '' : '' }}
</el-descriptions-item>
<el-descriptions-item v-if="infoDialog.data.type == menuTypeValue" label="是否iframe">
{{ infoDialog.data.meta.isIframe ? '' : '' }}
<el-descriptions-item v-if="infoDialog.data.type == menuTypeValue" label="外链">
{{ infoDialog.data.meta.linkType ? '' : '' }}
</el-descriptions-item>
<el-descriptions-item v-if="infoDialog.data.type == menuTypeValue && infoDialog.data.meta.isIframe"
label="iframe url">
<el-descriptions-item v-if="infoDialog.data.type == menuTypeValue && infoDialog.data.meta.linkType > 0"
label="外链">
{{ infoDialog.data.meta.link }}
</el-descriptions-item>
@@ -117,7 +116,7 @@ const state = reactive({
type: null,
title: '',
visible: false,
data: { pid: 0, type: 1, weight: 1 },
data: { pid: 0, type: 1 },
// 资源类型选择是否选
typeDisabled: true,
},
@@ -134,7 +133,6 @@ const state = reactive({
modifier: '',
createTime: '',
updateTime: '',
weight: null,
code: '',
},
},
@@ -182,7 +180,7 @@ const deleteMenu = (data: any) => {
const addResource = (data: any) => {
let dialog = state.dialogForm;
dialog.data = { pid: 0, type: 1, weight: 1 };
dialog.data = { pid: 0, type: 1 };
// 添加顶级菜单情况
if (!data) {
dialog.typeDisabled = true;
@@ -213,7 +211,6 @@ const addResource = (data: any) => {
} else {
dialog.data.type = menuTypeValue;
}
dialog.data.weight = data.children.length + 1;
}
dialog.visible = true;
};
@@ -242,7 +239,7 @@ const changeStatus = async (data: any, status: any) => {
id: data.id,
status: status,
});
data.status = status;
search();
ElMessage.success((status === 1 ? '启用' : '禁用') + '成功!');
};
@@ -271,6 +268,51 @@ const handleNodeCollapse = (data: any, node: any) => {
}
};
const allowDrop = (draggingNode: any, dropNode: any, type: any) => {
// 如果是插入至目标节点
if (type === 'inner') {
// 只有目标节点下没有子节点才允许移动
if (!dropNode.data.children || dropNode.data.children == 0) {
// 只有权限节点可移动至菜单节点下 或者移动菜单
return (draggingNode.data.type == permissionTypeValue && dropNode.data.type == menuTypeValue) ||
(draggingNode.data.type == menuTypeValue && dropNode.data.type == menuTypeValue)
}
return false;
}
return draggingNode.data.type === dropNode.data.type;
}
const handleDrop = async (
draggingNode: any,
dropNode: any,
dropType: any,
) => {
const draggingData = draggingNode.data;
const dropData = dropNode.data;
if (draggingData.pid !== dropData.pid) {
draggingData.pid = dropData.pid;
}
if (dropType === 'inner') {
draggingData.weight = 1;
draggingData.pid = dropData.id;
}
if (dropType === 'before') {
draggingData.weight = dropData.weight - 1;
}
if (dropType === 'after') {
draggingData.weight = dropData.weight + 1;
}
await resourceApi.sort.request([
{
id: draggingData.id,
name: draggingData.name,
pid: draggingData.pid,
weight: draggingData.weight
},
])
}
const removeDeafultExpandId = (id: any) => {
let index = state.defaultExpandedKeys.indexOf(id);
if (index > -1) {

View File

@@ -10,8 +10,8 @@
node.label
}}</span>
<el-link @click.prevent="info(data)" style="margin-left: 25px" icon="InfoFilled" type="info"
:underline="false" />
<!-- <el-link @click.prevent="info(data)" style="margin-left: 25px" icon="InfoFilled" type="info"
:underline="false" /> -->
</span>
</template>
</el-tree>

View File

@@ -7,12 +7,17 @@
resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.19.1.tgz"
integrity sha512-h7RCSorm1DdTVGJf3P2Mhj3kdnkmF/EiysUkzS2TdgAYqyjFdMQJbVuXOBej2SBJaXan/lIVtT6KkGbyyq753A==
"@babel/runtime@^7.15.4":
version "7.19.0"
resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.19.0.tgz"
integrity sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA==
"@babel/parser@^7.20.15", "@babel/parser@^7.21.3":
version "7.21.8"
resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.21.8.tgz#642af7d0333eab9c0ad70b14ac5e76dbde7bfdf8"
integrity sha512-6zavDGdzG3gUqAdWvlLFfk+36RilI+Pwyuuh7HItyeScCWP3k6i8vKclAQ0bM/0y/Kz/xiwvxhMv9MgTJP5gmA==
"@babel/runtime@^7.21.0":
version "7.21.5"
resolved "https://registry.npmmirror.com/@babel/runtime/-/runtime-7.21.5.tgz#8492dddda9644ae3bda3b45eabe87382caee7200"
integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q==
dependencies:
regenerator-runtime "^0.13.4"
regenerator-runtime "^0.13.11"
"@ctrl/tinycolor@^3.4.1":
version "3.4.1"
@@ -190,6 +195,11 @@
resolved "https://registry.npmmirror.com/@humanwhocodes/object-schema/download/@humanwhocodes/object-schema-1.2.1.tgz"
integrity sha1-tSBSnsIdjllFoYUd/Rwy6U45/0U=
"@jridgewell/sourcemap-codec@^1.4.13":
version "1.4.15"
resolved "https://registry.npmmirror.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32"
integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
resolved "https://registry.nlark.com/@nodelib/fs.scandir/download/@nodelib/fs.scandir-2.1.5.tgz?cache=0&sync_timestamp=1622792738877&other_urls=https%3A%2F%2Fregistry.nlark.com%2F%40nodelib%2Ffs.scandir%2Fdownload%2F%40nodelib%2Ffs.scandir-2.1.5.tgz"
@@ -348,15 +358,15 @@
estree-walker "^2.0.2"
source-map "^0.6.1"
"@vue/compiler-core@3.2.47":
version "3.2.47"
resolved "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.2.47.tgz#3e07c684d74897ac9aa5922c520741f3029267f8"
integrity sha512-p4D7FDnQb7+YJmO2iPEv0SQNeNzcbHdGByJDsT4lynf63AFkOTFN07HsiRSvjGo0QrxR/o3d0hUyNCUnBU2Tig==
"@vue/compiler-core@3.3.4":
version "3.3.4"
resolved "https://registry.npmmirror.com/@vue/compiler-core/-/compiler-core-3.3.4.tgz#7fbf591c1c19e1acd28ffd284526e98b4f581128"
integrity sha512-cquyDNvZ6jTbf/+x+AgM2Arrp6G4Dzbb0R64jiG804HRMfRiFXWI6kqUVqZ6ZR0bQhIoQjB4+2bhNtVwndW15g==
dependencies:
"@babel/parser" "^7.16.4"
"@vue/shared" "3.2.47"
"@babel/parser" "^7.21.3"
"@vue/shared" "3.3.4"
estree-walker "^2.0.2"
source-map "^0.6.1"
source-map-js "^1.0.2"
"@vue/compiler-dom@3.2.39":
version "3.2.39"
@@ -366,29 +376,29 @@
"@vue/compiler-core" "3.2.39"
"@vue/shared" "3.2.39"
"@vue/compiler-dom@3.2.47":
version "3.2.47"
resolved "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.2.47.tgz#a0b06caf7ef7056939e563dcaa9cbde30794f305"
integrity sha512-dBBnEHEPoftUiS03a4ggEig74J2YBZ2UIeyfpcRM2tavgMWo4bsEfgCGsu+uJIL/vax9S+JztH8NmQerUo7shQ==
"@vue/compiler-dom@3.3.4":
version "3.3.4"
resolved "https://registry.npmmirror.com/@vue/compiler-dom/-/compiler-dom-3.3.4.tgz#f56e09b5f4d7dc350f981784de9713d823341151"
integrity sha512-wyM+OjOVpuUukIq6p5+nwHYtj9cFroz9cwkfmP9O1nzH68BenTTv0u7/ndggT8cIQlnBeOo6sUT/gvHcIkLA5w==
dependencies:
"@vue/compiler-core" "3.2.47"
"@vue/shared" "3.2.47"
"@vue/compiler-core" "3.3.4"
"@vue/shared" "3.3.4"
"@vue/compiler-sfc@3.2.47":
version "3.2.47"
resolved "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.2.47.tgz#1bdc36f6cdc1643f72e2c397eb1a398f5004ad3d"
integrity sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ==
"@vue/compiler-sfc@3.3.4":
version "3.3.4"
resolved "https://registry.npmmirror.com/@vue/compiler-sfc/-/compiler-sfc-3.3.4.tgz#b19d942c71938893535b46226d602720593001df"
integrity sha512-6y/d8uw+5TkCuzBkgLS0v3lSM3hJDntFEiUORM11pQ/hKvkhSKZrXW6i69UyXlJQisJxuUEJKAWEqWbWsLeNKQ==
dependencies:
"@babel/parser" "^7.16.4"
"@vue/compiler-core" "3.2.47"
"@vue/compiler-dom" "3.2.47"
"@vue/compiler-ssr" "3.2.47"
"@vue/reactivity-transform" "3.2.47"
"@vue/shared" "3.2.47"
"@babel/parser" "^7.20.15"
"@vue/compiler-core" "3.3.4"
"@vue/compiler-dom" "3.3.4"
"@vue/compiler-ssr" "3.3.4"
"@vue/reactivity-transform" "3.3.4"
"@vue/shared" "3.3.4"
estree-walker "^2.0.2"
magic-string "^0.25.7"
magic-string "^0.30.0"
postcss "^8.1.10"
source-map "^0.6.1"
source-map-js "^1.0.2"
"@vue/compiler-sfc@^3.0.11":
version "3.2.39"
@@ -414,18 +424,13 @@
"@vue/compiler-dom" "3.2.39"
"@vue/shared" "3.2.39"
"@vue/compiler-ssr@3.2.47":
version "3.2.47"
resolved "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.2.47.tgz#35872c01a273aac4d6070ab9d8da918ab13057ee"
integrity sha512-wVXC+gszhulcMD8wpxMsqSOpvDZ6xKXSVWkf50Guf/S+28hTAXPDYRTbLQ3EDkOP5Xz/+SY37YiwDquKbJOgZw==
"@vue/compiler-ssr@3.3.4":
version "3.3.4"
resolved "https://registry.npmmirror.com/@vue/compiler-ssr/-/compiler-ssr-3.3.4.tgz#9d1379abffa4f2b0cd844174ceec4a9721138777"
integrity sha512-m0v6oKpup2nMSehwA6Uuu+j+wEwcy7QmwMkVNVfrV9P2qE5KshC6RwOCq8fjGS/Eak/uNb8AaWekfiXxbBB6gQ==
dependencies:
"@vue/compiler-dom" "3.2.47"
"@vue/shared" "3.2.47"
"@vue/devtools-api@^6.4.5":
version "6.4.5"
resolved "https://registry.npmmirror.com/@vue/devtools-api/-/devtools-api-6.4.5.tgz"
integrity sha512-JD5fcdIuFxU4fQyXUu3w2KpAJHzTVdN+p4iOX2lMWSHMOoQdMAcpFLZzm9Z/2nmsoZ1a96QEhZ26e50xLBsgOQ==
"@vue/compiler-dom" "3.3.4"
"@vue/shared" "3.3.4"
"@vue/devtools-api@^6.5.0":
version "6.5.0"
@@ -443,58 +448,58 @@
estree-walker "^2.0.2"
magic-string "^0.25.7"
"@vue/reactivity-transform@3.2.47":
version "3.2.47"
resolved "https://registry.npmmirror.com/@vue/reactivity-transform/-/reactivity-transform-3.2.47.tgz#e45df4d06370f8abf29081a16afd25cffba6d84e"
integrity sha512-m8lGXw8rdnPVVIdIFhf0LeQ/ixyHkH5plYuS83yop5n7ggVJU+z5v0zecwEnX7fa7HNLBhh2qngJJkxpwEEmYA==
"@vue/reactivity-transform@3.3.4":
version "3.3.4"
resolved "https://registry.npmmirror.com/@vue/reactivity-transform/-/reactivity-transform-3.3.4.tgz#52908476e34d6a65c6c21cd2722d41ed8ae51929"
integrity sha512-MXgwjako4nu5WFLAjpBnCj/ieqcjE2aJBINUNQzkZQfzIZA4xn+0fV1tIYBJvvva3N3OvKGofRLvQIwEQPpaXw==
dependencies:
"@babel/parser" "^7.16.4"
"@vue/compiler-core" "3.2.47"
"@vue/shared" "3.2.47"
"@babel/parser" "^7.20.15"
"@vue/compiler-core" "3.3.4"
"@vue/shared" "3.3.4"
estree-walker "^2.0.2"
magic-string "^0.25.7"
magic-string "^0.30.0"
"@vue/reactivity@3.2.47":
version "3.2.47"
resolved "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.2.47.tgz#1d6399074eadfc3ed35c727e2fd707d6881140b6"
integrity sha512-7khqQ/75oyyg+N/e+iwV6lpy1f5wq759NdlS1fpAhFXa8VeAIKGgk2E/C4VF59lx5b+Ezs5fpp/5WsRYXQiKxQ==
"@vue/reactivity@3.3.4":
version "3.3.4"
resolved "https://registry.npmmirror.com/@vue/reactivity/-/reactivity-3.3.4.tgz#a27a29c6cd17faba5a0e99fbb86ee951653e2253"
integrity sha512-kLTDLwd0B1jG08NBF3R5rqULtv/f8x3rOFByTDz4J53ttIQEDmALqKqXY0J+XQeN0aV2FBxY8nJDf88yvOPAqQ==
dependencies:
"@vue/shared" "3.2.47"
"@vue/shared" "3.3.4"
"@vue/runtime-core@3.2.47":
version "3.2.47"
resolved "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.2.47.tgz#406ebade3d5551c00fc6409bbc1eeb10f32e121d"
integrity sha512-RZxbLQIRB/K0ev0K9FXhNbBzT32H9iRtYbaXb0ZIz2usLms/D55dJR2t6cIEUn6vyhS3ALNvNthI+Q95C+NOpA==
"@vue/runtime-core@3.3.4":
version "3.3.4"
resolved "https://registry.npmmirror.com/@vue/runtime-core/-/runtime-core-3.3.4.tgz#4bb33872bbb583721b340f3088888394195967d1"
integrity sha512-R+bqxMN6pWO7zGI4OMlmvePOdP2c93GsHFM/siJI7O2nxFRzj55pLwkpCedEY+bTMgp5miZ8CxfIZo3S+gFqvA==
dependencies:
"@vue/reactivity" "3.2.47"
"@vue/shared" "3.2.47"
"@vue/reactivity" "3.3.4"
"@vue/shared" "3.3.4"
"@vue/runtime-dom@3.2.47":
version "3.2.47"
resolved "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.2.47.tgz#93e760eeaeab84dedfb7c3eaf3ed58d776299382"
integrity sha512-ArXrFTjS6TsDei4qwNvgrdmHtD930KgSKGhS5M+j8QxXrDJYLqYw4RRcDy1bz1m1wMmb6j+zGLifdVHtkXA7gA==
"@vue/runtime-dom@3.3.4":
version "3.3.4"
resolved "https://registry.npmmirror.com/@vue/runtime-dom/-/runtime-dom-3.3.4.tgz#992f2579d0ed6ce961f47bbe9bfe4b6791251566"
integrity sha512-Aj5bTJ3u5sFsUckRghsNjVTtxZQ1OyMWCr5dZRAPijF/0Vy4xEoRCwLyHXcj4D0UFbJ4lbx3gPTgg06K/GnPnQ==
dependencies:
"@vue/runtime-core" "3.2.47"
"@vue/shared" "3.2.47"
csstype "^2.6.8"
"@vue/runtime-core" "3.3.4"
"@vue/shared" "3.3.4"
csstype "^3.1.1"
"@vue/server-renderer@3.2.47":
version "3.2.47"
resolved "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.2.47.tgz#8aa1d1871fc4eb5a7851aa7f741f8f700e6de3c0"
integrity sha512-dN9gc1i8EvmP9RCzvneONXsKfBRgqFeFZLurmHOveL7oH6HiFXJw5OGu294n1nHc/HMgTy6LulU/tv5/A7f/LA==
"@vue/server-renderer@3.3.4":
version "3.3.4"
resolved "https://registry.npmmirror.com/@vue/server-renderer/-/server-renderer-3.3.4.tgz#ea46594b795d1536f29bc592dd0f6655f7ea4c4c"
integrity sha512-Q6jDDzR23ViIb67v+vM1Dqntu+HUexQcsWKhhQa4ARVzxOY2HbC7QRW/ggkDBd5BU+uM1sV6XOAP0b216o34JQ==
dependencies:
"@vue/compiler-ssr" "3.2.47"
"@vue/shared" "3.2.47"
"@vue/compiler-ssr" "3.3.4"
"@vue/shared" "3.3.4"
"@vue/shared@3.2.39":
version "3.2.39"
resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.2.39.tgz"
integrity sha512-D3dl2ZB9qE6mTuWPk9RlhDeP1dgNRUKC3NJxji74A4yL8M2MwlhLKUC/49WHjrNzSPug58fWx/yFbaTzGAQSBw==
"@vue/shared@3.2.47":
version "3.2.47"
resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.2.47.tgz#e597ef75086c6e896ff5478a6bfc0a7aa4bbd14c"
integrity sha512-BHGyyGN3Q97EZx0taMQ+OLNuZcW3d37ZEVmEAyeoA9ERdGvm9Irc/0Fua8SNyOtV1w6BS4q25wbMzJujO9HIfQ==
"@vue/shared@3.3.4":
version "3.3.4"
resolved "https://registry.npmmirror.com/@vue/shared/-/shared-3.3.4.tgz#06e83c5027f464eef861c329be81454bc8b70780"
integrity sha512-7OjdcV8vQ74eiz1TZLzZP4JwqM5fA94K6yntPS5Z25r9HDuGNzaGdgvwKYq6S+MxwF0TFRwe50fIR/MYnakdkQ==
"@vueuse/core@^9.1.0":
version "9.2.0"
@@ -578,12 +583,12 @@ array-union@^2.1.0:
resolved "https://registry.npm.taobao.org/array-union/download/array-union-2.1.0.tgz?cache=0&sync_timestamp=1614624262896&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Farray-union%2Fdownload%2Farray-union-2.1.0.tgz"
integrity sha1-t5hCCtvrHego2ErNii4j0+/oXo0=
asciinema-player@^3.2.0:
version "3.2.0"
resolved "https://registry.npmmirror.com/asciinema-player/-/asciinema-player-3.2.0.tgz#9db608a2d81ff4ac235d50a88b498258bf7087fb"
integrity sha512-fV3Coe/UGieUy+5KCrh1qZf1lFWkuj12a6KcKrr84b61UFfUOpAZfyem4UnpczuP6cjrV3w5t0u8Wd1kTz/e7g==
asciinema-player@^3.3.0:
version "3.3.0"
resolved "https://registry.npmmirror.com/asciinema-player/-/asciinema-player-3.3.0.tgz#45616fa8dc3950c2be12b51d0a365ea2b9a845c2"
integrity sha512-4uyCGe83+5gZ06jgIGyV4vl0TS3egBgW0NXyCpDuDDvmzDGHEG8OICChrTecmTvajgLyq8YQet9nI7SYkVt8vQ==
dependencies:
"@babel/runtime" "^7.15.4"
"@babel/runtime" "^7.21.0"
solid-js "^1.3.0"
async-validator@^4.2.5:
@@ -596,10 +601,10 @@ asynckit@^0.4.0:
resolved "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz"
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
axios@^1.3.4:
version "1.3.4"
resolved "https://registry.npmmirror.com/axios/-/axios-1.3.4.tgz#f5760cefd9cfb51fd2481acf88c05f67c4523024"
integrity sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==
axios@^1.4.0:
version "1.4.0"
resolved "https://registry.npmmirror.com/axios/-/axios-1.4.0.tgz#38a7bf1224cd308de271146038b551d725f0be1f"
integrity sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==
dependencies:
follow-redirects "^1.15.0"
form-data "^4.0.0"
@@ -715,16 +720,16 @@ cross-spawn@^7.0.2:
shebang-command "^2.0.0"
which "^2.0.1"
csstype@^2.6.8:
version "2.6.21"
resolved "https://registry.npmmirror.com/csstype/-/csstype-2.6.21.tgz"
integrity sha512-Z1PhmomIfypOpoMjRQB70jfvy/wxT50qW08YXO5lMIJkrdq4yOTR+AW7FqutScmB9NkLwxo+jU+kZLbofZZq/w==
csstype@^3.1.0:
version "3.1.1"
resolved "https://registry.npmmirror.com/csstype/-/csstype-3.1.1.tgz"
integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==
csstype@^3.1.1:
version "3.1.2"
resolved "https://registry.npmmirror.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b"
integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==
dayjs@^1.11.3:
version "1.11.3"
resolved "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.3.tgz"
@@ -737,6 +742,13 @@ debug@^4.1.1, debug@^4.3.1, debug@^4.3.2:
dependencies:
ms "2.1.2"
debug@^4.3.4:
version "4.3.4"
resolved "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
dependencies:
ms "2.1.2"
deep-is@^0.1.3:
version "0.1.4"
resolved "https://registry.nlark.com/deep-is/download/deep-is-0.1.4.tgz"
@@ -792,10 +804,10 @@ echarts@^5.4.0:
tslib "2.3.0"
zrender "5.4.0"
element-plus@^2.3.2:
version "2.3.2"
resolved "https://registry.npmmirror.com/element-plus/-/element-plus-2.3.2.tgz#93abe96bcd5d00e96ef281e8d148391d698fb6e3"
integrity sha512-NIK0QckKKagdlMm3eLoVoD4Lkfj5ECzpZAxwrRLdm1Yi5qiTU9Guor33+IbIa52z4gHMuhMxgSVS2xAGmjLHsw==
element-plus@^2.3.5:
version "2.3.5"
resolved "https://registry.npmmirror.com/element-plus/-/element-plus-2.3.5.tgz#5b04de44fd0ee1bd29ad6ed971d9155982cc1295"
integrity sha512-g27DHm2C5/tPwte9H6Juu+JOdzT9z1ALHTIvia6MwnBdCrI4kd77o6KcYdodU15/tYiPBoCEmobhl/7GUDb+1Q==
dependencies:
"@ctrl/tinycolor" "^3.4.1"
"@element-plus/icons-vue" "^2.0.6"
@@ -907,6 +919,11 @@ eslint-visitor-keys@^3.3.0:
resolved "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826"
integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==
eslint-visitor-keys@^3.4.0:
version "3.4.0"
resolved "https://registry.npmmirror.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.0.tgz#c7f0f956124ce677047ddbc192a68f999454dedc"
integrity sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==
eslint@^8.35.0:
version "8.35.0"
resolved "https://registry.npmmirror.com/eslint/-/eslint-8.35.0.tgz#fffad7c7e326bae606f0e8f436a6158566d42323"
@@ -962,6 +979,15 @@ espree@^9.0.0:
acorn-jsx "^5.3.1"
eslint-visitor-keys "^3.1.0"
espree@^9.3.1:
version "9.5.1"
resolved "https://registry.npmmirror.com/espree/-/espree-9.5.1.tgz#4f26a4d5f18905bf4f2e0bd99002aab807e96dd4"
integrity sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==
dependencies:
acorn "^8.8.0"
acorn-jsx "^5.3.2"
eslint-visitor-keys "^3.4.0"
espree@^9.4.0:
version "9.4.1"
resolved "https://registry.npmmirror.com/espree/-/espree-9.4.1.tgz#51d6092615567a2c2cff7833445e37c28c0065bd"
@@ -1038,10 +1064,10 @@ fast-levenshtein@^2.0.6:
resolved "https://registry.nlark.com/fast-levenshtein/download/fast-levenshtein-2.0.6.tgz"
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
fast-plist@^0.1.2:
version "0.1.2"
resolved "https://registry.npmmirror.com/fast-plist/-/fast-plist-0.1.2.tgz"
integrity sha512-2HxzrqJhmMoxVzARjYFvkzkL2dCBB8sogU5sD8gqcZWv5UCivK9/cXM9KIPDRwU+eD3mbRDN/GhW8bO/4dtMfg==
fast-plist@^0.1.3:
version "0.1.3"
resolved "https://registry.npmmirror.com/fast-plist/-/fast-plist-0.1.3.tgz#328cd9335e93a2479ac90814a1302437574ea925"
integrity sha512-d9cEfo/WcOezgPLAC/8t8wGb6YOD6JTCPMw2QcG2nAdFmyY+9rTUizCTaGjIZAloWENTEUMAPpkUAIJJJ0i96A==
fastq@^1.6.0:
version "1.13.0"
@@ -1109,11 +1135,6 @@ fsevents@~2.3.2:
resolved "https://registry.npmmirror.com/fsevents/download/fsevents-2.3.2.tgz"
integrity sha1-ilJveLj99GI7cJ4Ll1xSwkwC/Ro=
function-bind@^1.1.1:
version "1.1.1"
resolved "https://registry.nlark.com/function-bind/download/function-bind-1.1.1.tgz"
integrity sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=
functional-red-black-tree@^1.0.1:
version "1.0.1"
resolved "https://registry.npm.taobao.org/functional-red-black-tree/download/functional-red-black-tree-1.0.1.tgz?cache=0&sync_timestamp=1577806294691&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffunctional-red-black-tree%2Fdownload%2Ffunctional-red-black-tree-1.0.1.tgz"
@@ -1181,13 +1202,6 @@ has-flag@^4.0.0:
resolved "https://registry.nlark.com/has-flag/download/has-flag-4.0.0.tgz?cache=0&sync_timestamp=1626715907927&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fhas-flag%2Fdownload%2Fhas-flag-4.0.0.tgz"
integrity sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s=
has@^1.0.3:
version "1.0.3"
resolved "https://registry.nlark.com/has/download/has-1.0.3.tgz"
integrity sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y=
dependencies:
function-bind "^1.1.1"
ignore@^5.1.4, ignore@^5.1.8:
version "5.1.9"
resolved "https://registry.npmmirror.com/ignore/download/ignore-5.1.9.tgz?cache=0&sync_timestamp=1635926740448&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fignore%2Fdownload%2Fignore-5.1.9.tgz"
@@ -1236,13 +1250,6 @@ is-binary-path@~2.1.0:
dependencies:
binary-extensions "^2.0.0"
is-core-module@^2.9.0:
version "2.11.0"
resolved "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144"
integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==
dependencies:
has "^1.0.3"
is-extglob@^2.1.1:
version "2.1.1"
resolved "https://registry.npm.taobao.org/is-extglob/download/is-extglob-2.1.1.tgz"
@@ -1351,6 +1358,13 @@ magic-string@^0.25.7:
dependencies:
sourcemap-codec "^1.4.8"
magic-string@^0.30.0:
version "0.30.0"
resolved "https://registry.npmmirror.com/magic-string/-/magic-string-0.30.0.tgz#fd58a4748c5c4547338a424e90fa5dd17f4de529"
integrity sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ==
dependencies:
"@jridgewell/sourcemap-codec" "^1.4.13"
memoize-one@^6.0.0:
version "6.0.0"
resolved "https://registry.npmmirror.com/memoize-one/download/memoize-one-6.0.0.tgz?cache=0&sync_timestamp=1634697208428&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fmemoize-one%2Fdownload%2Fmemoize-one-6.0.0.tgz"
@@ -1400,10 +1414,10 @@ mitt@^3.0.0:
resolved "https://registry.npmmirror.com/mitt/download/mitt-3.0.0.tgz"
integrity sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==
monaco-editor@^0.37.1:
version "0.37.1"
resolved "https://registry.npmmirror.com/monaco-editor/-/monaco-editor-0.37.1.tgz#d6f5ffb593e019e74e19bf8a2bdef5a691876f4e"
integrity sha512-jLXEEYSbqMkT/FuJLBZAVWGuhIb4JNwHE9kPTorAVmsdZ4UzHAfgWxLsVtD7pLRFaOwYPhNG9nUCpmFL1t/dIg==
monaco-editor@^0.38.0:
version "0.38.0"
resolved "https://registry.npmmirror.com/monaco-editor/-/monaco-editor-0.38.0.tgz#7b3cd16f89b1b8867fcd3c96e67fccee791ff05c"
integrity sha512-11Fkh6yzEmwx7O0YoLxeae0qEGFwmyPRlVxpg7oF9czOOCB/iCjdJrG5I67da5WiXK3YJCxoz9TJFE8Tfq/v9A==
monaco-sql-languages@^0.11.0:
version "0.11.0"
@@ -1412,12 +1426,12 @@ monaco-sql-languages@^0.11.0:
dependencies:
dt-sql-parser "^4.0.0-beta.3.2"
monaco-themes@^0.4.2:
version "0.4.2"
resolved "https://registry.npmmirror.com/monaco-themes/-/monaco-themes-0.4.2.tgz"
integrity sha512-T3kp6SC5MPJvwYGXZENCd0UOIKVgUVV5SjsiXLBhgEZBnScY+6gEbwNRK1oYmfwbf+dGVqF1bSLN5YcrFu3HmA==
monaco-themes@^0.4.4:
version "0.4.4"
resolved "https://registry.npmmirror.com/monaco-themes/-/monaco-themes-0.4.4.tgz#28ab13e538c4867a9bc89dc67f15dfaf3fc69de1"
integrity sha512-Hbb9pvRrpSi0rZezcB/IOdQnpx10o55Lx4zFdRAAVpFMa1HP7FgaqEZdKffb4ovd90fETCixeFO9JPYFMAq+TQ==
dependencies:
fast-plist "^0.1.2"
fast-plist "^0.1.3"
moo@^0.5.0:
version "0.5.2"
@@ -1434,10 +1448,10 @@ nanoid@^3.1.30:
resolved "https://registry.npmmirror.com/nanoid/download/nanoid-3.1.30.tgz"
integrity sha1-Y/k8xUjSoRPcXfvGO/oJ4rm2Q2I=
nanoid@^3.3.4:
version "3.3.4"
resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.4.tgz"
integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
nanoid@^3.3.6:
version "3.3.6"
resolved "https://registry.npmmirror.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c"
integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==
natural-compare@^1.4.0:
version "1.4.0"
@@ -1529,11 +1543,6 @@ path-key@^3.1.0:
resolved "https://registry.nlark.com/path-key/download/path-key-3.1.1.tgz"
integrity sha1-WB9q3mWMu6ZaDTOA3ndTKVBU83U=
path-parse@^1.0.7:
version "1.0.7"
resolved "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz"
integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
path-type@^4.0.0:
version "4.0.0"
resolved "https://registry.nlark.com/path-type/download/path-type-4.0.0.tgz"
@@ -1549,13 +1558,13 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3:
resolved "https://registry.nlark.com/picomatch/download/picomatch-2.3.0.tgz?cache=0&sync_timestamp=1621648246651&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fpicomatch%2Fdownload%2Fpicomatch-2.3.0.tgz"
integrity sha1-8fBh3o9qS/AiiS4tEoI0+5gwKXI=
pinia@^2.0.33:
version "2.0.33"
resolved "https://registry.npmmirror.com/pinia/-/pinia-2.0.33.tgz#b70065be697874d5824e9792f59bd5d87ddb5e7d"
integrity sha512-HOj1yVV2itw6rNIrR2f7+MirGNxhORjrULL8GWgRwXsGSvEqIQ+SE0MYt6cwtpegzCda3i+rVTZM+AM7CG+kRg==
pinia@^2.1.3:
version "2.1.3"
resolved "https://registry.npmmirror.com/pinia/-/pinia-2.1.3.tgz#50c70c7b4c94c109fade0ed4122231cbba72f8c5"
integrity sha512-XNA/z/ye4P5rU1pieVmh0g/hSuDO98/a5UC8oSP0DNdvt6YtetJNHTrXwpwsQuflkGT34qKxAEcp7lSxXNjf/A==
dependencies:
"@vue/devtools-api" "^6.5.0"
vue-demi "*"
vue-demi ">=0.14.5"
postcss@^8.1.10:
version "8.4.5"
@@ -1566,12 +1575,12 @@ postcss@^8.1.10:
picocolors "^1.0.0"
source-map-js "^1.0.1"
postcss@^8.4.21:
version "8.4.21"
resolved "https://registry.npmmirror.com/postcss/-/postcss-8.4.21.tgz#c639b719a57efc3187b13a1d765675485f4134f4"
integrity sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==
postcss@^8.4.23:
version "8.4.23"
resolved "https://registry.npmmirror.com/postcss/-/postcss-8.4.23.tgz#df0aee9ac7c5e53e1075c24a3613496f9e6552ab"
integrity sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==
dependencies:
nanoid "^3.3.4"
nanoid "^3.3.6"
picocolors "^1.0.0"
source-map-js "^1.0.2"
@@ -1620,10 +1629,10 @@ readdirp@~3.6.0:
dependencies:
picomatch "^2.2.1"
regenerator-runtime@^0.13.4:
version "0.13.9"
resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz"
integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
regenerator-runtime@^0.13.11:
version "0.13.11"
resolved "https://registry.npmmirror.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
regexpp@^3.1.0, regexpp@^3.2.0:
version "3.2.0"
@@ -1635,15 +1644,6 @@ resolve-from@^4.0.0:
resolved "https://registry.nlark.com/resolve-from/download/resolve-from-4.0.0.tgz"
integrity sha1-SrzYUq0y3Xuqv+m0DgCjbbXzkuY=
resolve@^1.22.1:
version "1.22.1"
resolved "https://registry.npmmirror.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
dependencies:
is-core-module "^2.9.0"
path-parse "^1.0.7"
supports-preserve-symlinks-flag "^1.0.0"
ret@~0.1.10:
version "0.1.15"
resolved "https://registry.npmmirror.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc"
@@ -1661,10 +1661,10 @@ rimraf@^3.0.2:
dependencies:
glob "^7.1.3"
rollup@^3.18.0:
version "3.19.1"
resolved "https://registry.npmmirror.com/rollup/-/rollup-3.19.1.tgz#2b3a31ac1ff9f3afab2e523fa687fef5b0ee20fc"
integrity sha512-lAbrdN7neYCg/8WaoWn/ckzCtz+jr70GFfYdlf50OF7387HTg+wiuiqJRFYawwSPpqfqDNYqK7smY/ks2iAudg==
rollup@^3.21.0:
version "3.21.3"
resolved "https://registry.npmmirror.com/rollup/-/rollup-3.21.3.tgz#b3f1920a9d35a9de70f120a1d085753e41997941"
integrity sha512-VnPfEG51nIv2xPLnZaekkuN06q9ZbnyDcLkaBdJa/W7UddyhOfMP2yOPziYQfeY7k++fZM8FdQIummFN5y14kA==
optionalDependencies:
fsevents "~2.3.2"
@@ -1683,10 +1683,10 @@ sass-loader@^13.2.0:
klona "^2.0.4"
neo-async "^2.6.2"
sass@^1.58.0:
version "1.58.0"
resolved "https://registry.npmmirror.com/sass/-/sass-1.58.0.tgz#ee8aea3ad5ea5c485c26b3096e2df6087d0bb1cc"
integrity sha512-PiMJcP33DdKtZ/1jSjjqVIKihoDc6yWmYr9K/4r3fVVIEDAluD0q7XZiRKrNJcPK3qkLRF/79DND1H5q1LBjgg==
sass@^1.62.0:
version "1.62.0"
resolved "https://registry.npmmirror.com/sass/-/sass-1.62.0.tgz#3686b2195b93295d20765135e562366b33ece37d"
integrity sha512-Q4USplo4pLYgCi+XlipZCWUQz5pkg/ruSSgJ0WRDSb/+3z9tXUOkQ7QPYn4XrhZKYAK4HlpaQecRwKLJX6+DBg==
dependencies:
chokidar ">=3.0.0 <4.0.0"
immutable "^4.0.0"
@@ -1709,6 +1709,13 @@ semver@^7.3.5:
dependencies:
lru-cache "^6.0.0"
semver@^7.3.6:
version "7.5.0"
resolved "https://registry.npmmirror.com/semver/-/semver-7.5.0.tgz#ed8c5dc8efb6c629c88b23d41dc9bf40c1d96cd0"
integrity sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==
dependencies:
lru-cache "^6.0.0"
shebang-command@^2.0.0:
version "2.0.0"
resolved "https://registry.nlark.com/shebang-command/download/shebang-command-2.0.0.tgz"
@@ -1785,11 +1792,6 @@ supports-color@^7.1.0:
dependencies:
has-flag "^4.0.0"
supports-preserve-symlinks-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz"
integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
text-table@^0.2.0:
version "0.2.0"
resolved "https://registry.npm.taobao.org/text-table/download/text-table-0.2.0.tgz"
@@ -1848,15 +1850,14 @@ uri-js@^4.2.2:
dependencies:
punycode "^2.1.0"
vite@^4.2.0:
version "4.2.0"
resolved "https://registry.npmmirror.com/vite/-/vite-4.2.0.tgz#d4e6eafbc034f3faf0ab376bd5b76ac15775eb99"
integrity sha512-AbDTyzzwuKoRtMIRLGNxhLRuv1FpRgdIw+1y6AQG73Q5+vtecmvzKo/yk8X/vrHDpETRTx01ABijqUHIzBXi0g==
vite@^4.3.9:
version "4.3.9"
resolved "https://registry.npmmirror.com/vite/-/vite-4.3.9.tgz#db896200c0b1aa13b37cdc35c9e99ee2fdd5f96d"
integrity sha512-qsTNZjO9NoJNW7KnOrgYwczm0WctJ8m/yqYAMAK9Lxt4SoySUfS5S8ia9K7JHpa3KEeMfyF8LoJ3c5NeBJy6pg==
dependencies:
esbuild "^0.17.5"
postcss "^8.4.21"
resolve "^1.22.1"
rollup "^3.18.0"
postcss "^8.4.23"
rollup "^3.21.0"
optionalDependencies:
fsevents "~2.3.2"
@@ -1872,6 +1873,11 @@ vue-demi@*:
resolved "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.13.11.tgz"
integrity sha512-IR8HoEEGM65YY3ZJYAjMlKygDQn25D5ajNFNoKh9RSDMQtlzCxtfQjdQgv9jjK+m3377SsJXY8ysq8kLCZL25A==
vue-demi@>=0.14.5:
version "0.14.5"
resolved "https://registry.npmmirror.com/vue-demi/-/vue-demi-0.14.5.tgz#676d0463d1a1266d5ab5cba932e043d8f5f2fbd9"
integrity sha512-o9NUVpl/YlsGJ7t+xuqJKx8EBGf1quRhCiT6D/J0pfwmk9zUwYkC7yrF4SZCe6fETvSM3UNL2edcbYrSyc4QHA==
vue-eslint-parser@^8.0.1:
version "8.0.1"
resolved "https://registry.npmmirror.com/vue-eslint-parser/download/vue-eslint-parser-8.0.1.tgz"
@@ -1885,23 +1891,36 @@ vue-eslint-parser@^8.0.1:
lodash "^4.17.21"
semver "^7.3.5"
vue-router@^4.1.6:
version "4.1.6"
resolved "https://registry.npmmirror.com/vue-router/-/vue-router-4.1.6.tgz"
integrity sha512-DYWYwsG6xNPmLq/FmZn8Ip+qrhFEzA14EI12MsMgVxvHFDYvlr4NXpVF5hrRH1wVcDP8fGi5F4rxuJSl8/r+EQ==
vue-eslint-parser@^9.1.1:
version "9.1.1"
resolved "https://registry.npmmirror.com/vue-eslint-parser/-/vue-eslint-parser-9.1.1.tgz#3f4859be7e9bb7edaa1dc7edb05abffee72bf3dd"
integrity sha512-C2aI/r85Q6tYcz4dpgvrs4wH/MqVrRAVIdpYedrxnATDHHkb+TroeRcDpKWGZCx/OcECMWfz7tVwQ8e+Opy6rA==
dependencies:
"@vue/devtools-api" "^6.4.5"
debug "^4.3.4"
eslint-scope "^7.1.1"
eslint-visitor-keys "^3.3.0"
espree "^9.3.1"
esquery "^1.4.0"
lodash "^4.17.21"
semver "^7.3.6"
vue@^3.2.47:
version "3.2.47"
resolved "https://registry.npmmirror.com/vue/-/vue-3.2.47.tgz#3eb736cbc606fc87038dbba6a154707c8a34cff0"
integrity sha512-60188y/9Dc9WVrAZeUVSDxRQOZ+z+y5nO2ts9jWXSTkMvayiWxCWOWtBQoYjLeccfXkiiPZWAHcV+WTPhkqJHQ==
vue-router@^4.2.2:
version "4.2.2"
resolved "https://registry.npmmirror.com/vue-router/-/vue-router-4.2.2.tgz#b0097b66d89ca81c0986be03da244c7b32a4fd81"
integrity sha512-cChBPPmAflgBGmy3tBsjeoe3f3VOSG6naKyY5pjtrqLGbNEXdzCigFUHgBvp9e3ysAtFtEx7OLqcSDh/1Cq2TQ==
dependencies:
"@vue/compiler-dom" "3.2.47"
"@vue/compiler-sfc" "3.2.47"
"@vue/runtime-dom" "3.2.47"
"@vue/server-renderer" "3.2.47"
"@vue/shared" "3.2.47"
"@vue/devtools-api" "^6.5.0"
vue@^3.3.4:
version "3.3.4"
resolved "https://registry.npmmirror.com/vue/-/vue-3.3.4.tgz#8ed945d3873667df1d0fcf3b2463ada028f88bd6"
integrity sha512-VTyEYn3yvIeY1Py0WaYGZsXnz3y5UnGi62GjVEqvEGPl6nxbOrCXbVOTQWBEJUqAyTUk2uJ5JLVnYJ6ZzGbrSw==
dependencies:
"@vue/compiler-dom" "3.3.4"
"@vue/compiler-sfc" "3.3.4"
"@vue/runtime-dom" "3.3.4"
"@vue/server-renderer" "3.3.4"
"@vue/shared" "3.3.4"
which@^2.0.1:
version "2.0.2"
@@ -1925,10 +1944,10 @@ xterm-addon-fit@^0.7.0:
resolved "https://registry.npmmirror.com/xterm-addon-fit/-/xterm-addon-fit-0.7.0.tgz#b8ade6d96e63b47443862088f6670b49fb752c6a"
integrity sha512-tQgHGoHqRTgeROPnvmtEJywLKoC/V9eNs4bLLz7iyJr1aW/QFzRwfd3MGiJ6odJd9xEfxcW36/xRU47JkD5NKQ==
xterm@^5.1.0:
version "5.1.0"
resolved "https://registry.npmmirror.com/xterm/-/xterm-5.1.0.tgz#3e160d60e6801c864b55adf19171c49d2ff2b4fc"
integrity sha512-LovENH4WDzpwynj+OTkLyZgJPeDom9Gra4DMlGAgz6pZhIDCQ+YuO7yfwanY+gVbn/mmZIStNOnVRU/ikQuAEQ==
xterm@^5.2.1:
version "5.2.1"
resolved "https://registry.npmmirror.com/xterm/-/xterm-5.2.1.tgz#b3fea7bdb55b9be1d4b31f4cd1091f26ac42afb8"
integrity sha512-cs5Y1fFevgcdoh2hJROMVIWwoBHD80P1fIP79gopLHJIE4kTzzblanoivxTiQ4+92YM9IxS36H1q0MxIJXQBcA==
yallist@^4.0.0:
version "4.0.0"

View File

@@ -22,7 +22,7 @@ DROP TABLE IF EXISTS `t_db`;
CREATE TABLE `t_db` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '数据库实例名称',
`host` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`host` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`port` int(8) NOT NULL,
`username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
@@ -30,7 +30,6 @@ CREATE TABLE `t_db` (
`database` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '数据库,空格分割多个数据库',
`params` varchar(125) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '其他连接参数',
`network` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`enable_ssh_tunnel` tinyint(2) DEFAULT NULL COMMENT '是否启用ssh隧道',
`ssh_tunnel_machine_id` bigint(20) DEFAULT NULL COMMENT 'ssh隧道的机器id',
`remark` varchar(125) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '备注,描述等',
`tag_id` bigint(20) DEFAULT NULL COMMENT '标签id',
@@ -105,6 +104,23 @@ CREATE TABLE `t_db_sql_exec` (
BEGIN;
COMMIT;
DROP TABLE IF EXISTS `t_auth_cert`;
CREATE TABLE `t_auth_cert` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`auth_method` tinyint NOT NULL COMMENT '1.密码 2.秘钥',
`password` varchar(4200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '密码or私钥',
`passphrase` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '私钥口令',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`create_time` datetime NOT NULL,
`creator` varchar(16) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`creator_id` bigint NOT NULL,
`update_time` datetime NOT NULL,
`modifier` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`modifier_id` bigint NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='授权凭证';
-- ----------------------------
-- Table structure for t_machine
-- ----------------------------
@@ -116,8 +132,8 @@ CREATE TABLE `t_machine` (
`port` int(12) NOT NULL,
`username` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL,
`auth_method` tinyint(2) DEFAULT NULL COMMENT '1.密码登录2.publickey登录',
`password` varchar(3200) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`enable_ssh_tunnel` tinyint(2) DEFAULT NULL COMMENT '是否启用ssh隧道',
`password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`auth_cert_id` bigint(20) DEFAULT NULL COMMENT '授权凭证id',
`ssh_tunnel_machine_id` bigint(20) DEFAULT NULL COMMENT 'ssh隧道的机器id',
`enable_recorder` tinyint(2) DEFAULT NULL COMMENT '是否启用终端回放记录',
`status` tinyint(2) NOT NULL COMMENT '状态: 1:启用; -1:禁用',
@@ -226,7 +242,6 @@ CREATE TABLE `t_mongo` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '名称',
`uri` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL COMMENT '连接uri',
`enable_ssh_tunnel` tinyint(2) DEFAULT NULL COMMENT '是否启用ssh隧道',
`ssh_tunnel_machine_id` bigint(20) DEFAULT NULL COMMENT 'ssh隧道的机器id',
`tag_id` bigint(20) DEFAULT NULL COMMENT '标签id',
`tag_path` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '标签路径',
@@ -256,7 +271,6 @@ CREATE TABLE `t_redis` (
`password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`db` varchar(64) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '库号: 多个库用,分割',
`mode` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL,
`enable_ssh_tunnel` tinyint(2) DEFAULT NULL COMMENT '是否启用ssh隧道',
`ssh_tunnel_machine_id` bigint(20) DEFAULT NULL COMMENT 'ssh隧道的机器id',
`remark` varchar(125) COLLATE utf8mb4_bin DEFAULT NULL,
`tag_id` bigint(20) DEFAULT NULL COMMENT '标签id',
@@ -352,6 +366,8 @@ CREATE TABLE `t_sys_config` (
BEGIN;
INSERT INTO `t_sys_config` VALUES (1, '是否启用登录验证码', 'UseLoginCaptcha', NULL, '1', '1: 启用、0: 不启用', '2022-08-25 22:27:17', 1, 'admin', '2022-08-26 10:26:56', 1, 'admin');
INSERT INTO `t_sys_config` VALUES (2, '是否启用水印', 'UseWartermark', NULL, '1', '1: 启用、0: 不启用', '2022-08-25 23:36:35', 1, 'admin', '2022-08-26 10:02:52', 1, 'admin');
INSERT INTO `t_sys_config` VALUES (3, '数据库查询最大结果集', 'DbQueryMaxCount', '[]', '200', '允许sql查询的最大结果集数。注: 0=不限制', '2023-02-11 14:29:03', 1, 'admin', '2023-02-11 14:40:56', 1, 'admin');
INSERT INTO `t_sys_config` VALUES (4, '数据库是否记录查询SQL', 'DbSaveQuerySQL', '[]', '0', '1: 记录、0:不记录', '2023-02-11 16:07:14', 1, 'admin', '2023-02-11 16:44:17', 1, 'admin');
COMMIT;
-- ----------------------------
@@ -424,78 +440,85 @@ CREATE TABLE `t_sys_resource` (
-- Records of t_sys_resource
-- ----------------------------
BEGIN;
INSERT INTO `t_sys_resource` VALUES (1, 0, 1, 1, '首页', '/home', 1, '{\"component\":\"Home\",\"icon\":\"HomeFilled\",\"isAffix\":true,\"isKeepAlive\":true,\"routeName\":\"Home\"}', 1, 'admin', 1, 'admin', '2021-05-25 16:44:41', '2021-05-27 09:12:56');
INSERT INTO `t_sys_resource` VALUES (2, 0, 1, 1, '机器管理', '/machine', 4, '{\"icon\":\"Monitor\",\"isKeepAlive\":true,\"redirect\":\"machine/list\",\"routeName\":\"Machine\"}', 1, 'admin', 1, 'admin', '2021-05-25 16:48:16', '2022-10-06 14:58:49');
INSERT INTO `t_sys_resource` VALUES (3, 2, 1, 1, '机器列表', 'machines', 2, '{\"component\":\"MachineList\",\"icon\":\"Menu\",\"isKeepAlive\":true,\"routeName\":\"MachineList\"}', 2, 'admin', 1, 'admin', '2021-05-25 16:50:04', '2021-06-30 16:20:08');
INSERT INTO `t_sys_resource` VALUES (4, 0, 1, 1, '系统管理', '/sys', 8, '{\"icon\":\"Setting\",\"isKeepAlive\":true,\"redirect\":\"/sys/resources\",\"routeName\":\"sys\"}', 1, 'admin', 1, 'admin', '2021-05-26 15:20:20', '2022-10-06 14:59:53');
INSERT INTO `t_sys_resource` VALUES (5, 4, 1, 1, '资源管理', 'resources', 3, '{\"component\":\"ResourceList\",\"icon\":\"Menu\",\"isKeepAlive\":true,\"routeName\":\"ResourceList\"}', 1, 'admin', 1, 'admin', '2021-05-26 15:23:07', '2021-06-08 11:27:55');
INSERT INTO `t_sys_resource` VALUES (11, 4, 1, 1, '角色管理', 'roles', 2, '{\"component\":\"RoleList\",\"icon\":\"Menu\",\"isKeepAlive\":true,\"routeName\":\"RoleList\"}', 1, 'admin', 1, 'admin', '2021-05-27 11:15:35', '2021-06-03 09:59:41');
INSERT INTO `t_sys_resource` VALUES (12, 3, 2, 1, '机器终端按钮', 'machine:terminal', 4, '', 1, 'admin', 1, 'admin', '2021-05-28 14:06:02', '2021-05-31 17:47:59');
INSERT INTO `t_sys_resource` VALUES (14, 4, 1, 1, '账号管理', 'accounts', 1, '{\"component\":\"AccountList\",\"icon\":\"Menu\",\"isKeepAlive\":true,\"routeName\":\"AccountList\"}', 1, 'admin', 1, 'admin', '2021-05-28 14:56:25', '2021-06-03 09:39:22');
INSERT INTO `t_sys_resource` VALUES (15, 3, 2, 1, '文件管理按钮', 'machine:file', 5, NULL, 1, 'admin', 1, 'admin', '2021-05-31 17:44:37', '2021-05-31 17:48:07');
INSERT INTO `t_sys_resource` VALUES (16, 3, 2, 1, '机器添加按钮', 'machine:add', 1, NULL, 1, 'admin', 1, 'admin', '2021-05-31 17:46:11', '2021-05-31 19:34:15');
INSERT INTO `t_sys_resource` VALUES (17, 3, 2, 1, '机器编辑按钮', 'machine:update', 2, NULL, 1, 'admin', 1, 'admin', '2021-05-31 17:46:23', '2021-05-31 19:34:18');
INSERT INTO `t_sys_resource` VALUES (18, 3, 2, 1, '机器删除按钮', 'machine:del', 3, NULL, 1, 'admin', 1, 'admin', '2021-05-31 17:46:36', '2021-05-31 19:34:17');
INSERT INTO `t_sys_resource` VALUES (19, 14, 2, 1, '角色分配按钮', 'account:saveRoles', 1, NULL, 1, 'admin', 1, 'admin', '2021-05-31 17:50:51', '2021-05-31 19:19:30');
INSERT INTO `t_sys_resource` VALUES (20, 11, 2, 1, '分配菜单&权限按钮', 'role:saveResources', 1, NULL, 1, 'admin', 1, 'admin', '2021-05-31 17:51:41', '2021-05-31 19:33:37');
INSERT INTO `t_sys_resource` VALUES (21, 14, 2, 1, '账号删除按钮', 'account:del', 2, 'null', 1, 'admin', 1, 'admin', '2021-05-31 18:02:01', '2021-06-10 17:12:17');
INSERT INTO `t_sys_resource` VALUES (22, 11, 2, 1, '角色删除按钮', 'role:del', 2, NULL, 1, 'admin', 1, 'admin', '2021-05-31 18:02:29', '2021-05-31 19:33:38');
INSERT INTO `t_sys_resource` VALUES (23, 11, 2, 1, '角色新增按钮', 'role:add', 3, NULL, 1, 'admin', 1, 'admin', '2021-05-31 18:02:44', '2021-05-31 19:33:39');
INSERT INTO `t_sys_resource` VALUES (24, 11, 2, 1, '角色编辑按钮', 'role:update', 4, NULL, 1, 'admin', 1, 'admin', '2021-05-31 18:02:57', '2021-05-31 19:33:40');
INSERT INTO `t_sys_resource` VALUES (25, 5, 2, 1, '资源新增按钮', 'resource:add', 1, NULL, 1, 'admin', 1, 'admin', '2021-05-31 18:03:33', '2021-05-31 19:31:47');
INSERT INTO `t_sys_resource` VALUES (26, 5, 2, 1, '资源删除按钮', 'resource:delete', 2, NULL, 1, 'admin', 1, 'admin', '2021-05-31 18:03:47', '2021-05-31 19:29:40');
INSERT INTO `t_sys_resource` VALUES (27, 5, 2, 1, '资源编辑按钮', 'resource:update', 3, NULL, 1, 'admin', 1, 'admin', '2021-05-31 18:04:03', '2021-05-31 19:29:40');
INSERT INTO `t_sys_resource` VALUES (28, 5, 2, 1, '资源禁用启用按钮', 'resource:changeStatus', 4, NULL, 1, 'admin', 1, 'admin', '2021-05-31 18:04:33', '2021-05-31 18:04:33');
INSERT INTO `t_sys_resource` VALUES (29, 14, 2, 1, '账号添加按钮', 'account:add', 3, NULL, 1, 'admin', 1, 'admin', '2021-05-31 19:23:42', '2021-05-31 19:23:42');
INSERT INTO `t_sys_resource` VALUES (30, 14, 2, 1, '账号编辑修改按钮', 'account:update', 4, NULL, 1, 'admin', 1, 'admin', '2021-05-31 19:23:58', '2021-05-31 19:23:58');
INSERT INTO `t_sys_resource` VALUES (31, 14, 2, 1, '账号管理基本权限', 'account', 0, 'null', 1, 'admin', 1, 'admin', '2021-05-31 21:25:06', '2021-06-22 11:20:34');
INSERT INTO `t_sys_resource` VALUES (32, 5, 2, 1, '资源管理基本权限', 'resource', 0, NULL, 1, 'admin', 1, 'admin', '2021-05-31 21:25:25', '2021-05-31 21:25:25');
INSERT INTO `t_sys_resource` VALUES (33, 11, 2, 1, '角色管理基本权限', 'role', 0, NULL, 1, 'admin', 1, 'admin', '2021-05-31 21:25:40', '2021-05-31 21:25:40');
INSERT INTO `t_sys_resource` VALUES (34, 14, 2, 1, '账号启用禁用按钮', 'account:changeStatus', 5, NULL, 1, 'admin', 1, 'admin', '2021-05-31 21:29:48', '2021-05-31 21:29:48');
INSERT INTO `t_sys_resource` VALUES (36, 0, 1, 1, 'DBMS', '/dbms', 5, '{\"icon\":\"Grid\",\"isKeepAlive\":true,\"routeName\":\"DBMS\"}', 1, 'admin', 1, 'admin', '2021-06-01 14:01:33', '2022-10-06 15:00:40');
INSERT INTO `t_sys_resource` VALUES (37, 3, 2, 1, '添加文件配置', 'machine:addFile', 6, 'null', 1, 'admin', 1, 'admin', '2021-06-01 19:54:23', '2021-06-01 19:54:23');
INSERT INTO `t_sys_resource` VALUES (38, 36, 1, 1, '数据操作', 'sql-exec', 1, '{\"component\":\"SqlExec\",\"icon\":\"Search\",\"isKeepAlive\":true,\"routeName\":\"SqlExec\"}', 1, 'admin', 1, 'admin', '2021-06-03 09:09:29', '2021-11-08 09:59:26');
INSERT INTO `t_sys_resource` VALUES (39, 0, 1, 1, '个人中心', '/personal', 2, '{\"component\":\"Personal\",\"icon\":\"UserFilled\",\"isHide\":true,\"isKeepAlive\":true,\"routeName\":\"Personal\"}', 1, 'admin', 1, 'admin', '2021-06-03 14:25:35', '2021-09-10 09:18:46');
INSERT INTO `t_sys_resource` VALUES (40, 3, 2, 1, '文件管理-新增按钮', 'machine:file:add', 7, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:06:26', '2021-06-08 11:12:28');
INSERT INTO `t_sys_resource` VALUES (41, 3, 2, 1, '文件管理-删除按钮', 'machine:file:del', 8, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:06:49', '2021-06-08 11:06:49');
INSERT INTO `t_sys_resource` VALUES (42, 3, 2, 1, '文件管理-写入or下载文件权限', 'machine:file:write', 9, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:07:27', '2021-06-08 11:07:27');
INSERT INTO `t_sys_resource` VALUES (43, 3, 2, 1, '文件管理-文件上传按钮', 'machine:file:upload', 10, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:07:42', '2021-06-08 11:07:42');
INSERT INTO `t_sys_resource` VALUES (44, 3, 2, 1, '文件管理-删除文件按钮', 'machine:file:rm', 11, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:08:12', '2021-06-08 11:08:12');
INSERT INTO `t_sys_resource` VALUES (45, 3, 2, 1, '脚本管理-保存脚本按钮', 'machine:script:save', 12, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:09:01', '2021-06-08 11:09:01');
INSERT INTO `t_sys_resource` VALUES (46, 3, 2, 1, '脚本管理-删除按钮', 'machine:script:del', 13, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:09:27', '2021-06-08 11:09:27');
INSERT INTO `t_sys_resource` VALUES (47, 3, 2, 1, '脚本管理-执行按钮', 'machine:script:run', 14, 'null', 1, 'admin', 1, 'admin', '2021-06-08 11:09:50', '2021-06-08 11:09:50');
INSERT INTO `t_sys_resource` VALUES (49, 36, 1, 1, '数据库管理', 'dbs', 2, '{\"component\":\"DbList\",\"icon\":\"Menu\",\"isKeepAlive\":true,\"routeName\":\"DbList\"}', 1, 'admin', 1, 'admin', '2021-07-07 15:13:55', '2021-07-07 15:13:55');
INSERT INTO `t_sys_resource` VALUES (54, 49, 2, 1, '数据库保存', 'db:save', 1, 'null', 1, 'admin', 1, 'admin', '2021-07-08 17:30:36', '2021-07-08 17:31:05');
INSERT INTO `t_sys_resource` VALUES (55, 49, 2, 1, '数据库删除', 'db:del', 2, 'null', 1, 'admin', 1, 'admin', '2021-07-08 17:30:48', '2021-07-08 17:30:48');
INSERT INTO `t_sys_resource` VALUES (57, 3, 2, 1, '基本权限', 'machine', 0, 'null', 1, 'admin', 1, 'admin', '2021-07-09 10:48:02', '2021-07-09 10:48:02');
INSERT INTO `t_sys_resource` VALUES (58, 49, 2, 1, '基本权限', 'db', 0, 'null', 1, 'admin', 1, 'admin', '2021-07-09 10:48:22', '2021-07-09 10:48:22');
INSERT INTO `t_sys_resource` VALUES (59, 38, 2, 1, '基本权限', 'db:exec', 1, 'null', 1, 'admin', 1, 'admin', '2021-07-09 10:50:13', '2021-07-09 10:50:13');
INSERT INTO `t_sys_resource` VALUES (60, 0, 1, 1, 'Redis', '/redis', 6, '{\"icon\":\"Menu\",\"isKeepAlive\":true,\"routeName\":\"RDS\"}', 1, 'admin', 1, 'admin', '2021-07-19 20:15:41', '2022-10-06 15:01:29');
INSERT INTO `t_sys_resource` VALUES (61, 60, 1, 1, '数据操作', 'data-operation', 1, '{\"component\":\"DataOperation\",\"icon\":\"Search\",\"isKeepAlive\":true,\"routeName\":\"DataOperation\"}', 1, 'admin', 1, 'admin', '2021-07-19 20:17:29', '2021-07-20 10:45:28');
INSERT INTO `t_sys_resource` VALUES (62, 61, 2, 1, '基本权限', 'redis:data', 1, 'null', 1, 'admin', 1, 'admin', '2021-07-19 20:18:54', '2021-07-19 20:18:54');
INSERT INTO `t_sys_resource` VALUES (63, 60, 1, 1, 'redis管理', 'manage', 2, '{\"component\":\"RedisList\",\"icon\":\"Menu\",\"isKeepAlive\":true,\"routeName\":\"RedisList\"}', 1, 'admin', 1, 'admin', '2021-07-20 10:48:04', '2021-07-20 10:48:04');
INSERT INTO `t_sys_resource` VALUES (64, 63, 2, 1, '基本权限', 'redis:manage', 1, 'null', 1, 'admin', 1, 'admin', '2021-07-20 10:48:26', '2021-07-20 10:48:26');
INSERT INTO `t_sys_resource` VALUES (71, 61, 2, 1, '数据保存', 'redis:data:save', 6, 'null', 1, 'admin', 1, 'admin', '2021-08-17 11:20:37', '2021-08-17 11:20:37');
INSERT INTO `t_sys_resource` VALUES (72, 3, 2, 1, '终止进程', 'machine:killprocess', 6, 'null', 1, 'admin', 1, 'admin', '2021-08-17 11:20:37', '2021-08-17 11:20:37');
INSERT INTO `t_sys_resource` VALUES (79, 0, 1, 1, 'Mongo', '/mongo', 7, '{\"icon\":\"Document\",\"isKeepAlive\":true,\"routeName\":\"Mongo\"}', 1, 'admin', 1, 'admin', '2022-05-13 14:00:41', '2022-10-06 15:01:34');
INSERT INTO `t_sys_resource` VALUES (80, 79, 1, 1, '数据操作', 'mongo-data-operation', 1, '{\"component\":\"MongoDataOp\",\"icon\":\"Document\",\"isKeepAlive\":true,\"routeName\":\"MongoDataOp\"}', 1, 'admin', 1, 'admin', '2022-05-13 14:03:58', '2022-05-14 20:16:07');
INSERT INTO `t_sys_resource` VALUES (81, 80, 2, 1, '基本权限', 'mongo:base', 1, 'null', 1, 'admin', 1, 'admin', '2022-05-13 14:04:16', '2022-05-13 14:04:16');
INSERT INTO `t_sys_resource` VALUES (82, 79, 1, 1, 'Mongo管理', 'mongo-manage', 2, '{\"component\":\"MongoList\",\"icon\":\"Menu\",\"isKeepAlive\":true,\"routeName\":\"MongoList\"}', 1, 'admin', 1, 'admin', '2022-05-16 18:13:06', '2022-05-16 18:13:06');
INSERT INTO `t_sys_resource` VALUES (83, 82, 2, 1, '基本权限', 'mongo:manage:base', 1, 'null', 1, 'admin', 1, 'admin', '2022-05-16 18:13:25', '2022-05-16 18:13:25');
INSERT INTO `t_sys_resource` VALUES (84, 4, 1, 1, '操作日志', 'syslogs', 4, '{\"component\":\"SyslogList\",\"icon\":\"Tickets\",\"routeName\":\"SyslogList\"}', 1, 'admin', 1, 'admin', '2022-07-13 19:57:07', '2022-07-13 22:58:19');
INSERT INTO `t_sys_resource` VALUES (85, 84, 2, 1, '操作日志基本权限', 'syslog', 1, 'null', 1, 'admin', 1, 'admin', '2022-07-13 19:57:55', '2022-07-13 19:57:55');
INSERT INTO `t_sys_resource` VALUES (87, 4, 1, 1, '系统配置', 'configs', 5, '{\"component\":\"ConfigList\",\"icon\":\"Setting\",\"isKeepAlive\":true,\"routeName\":\"ConfigList\"}', 1, 'admin', 1, 'admin', '2022-08-25 22:18:55', '2022-08-25 22:19:18');
INSERT INTO `t_sys_resource` VALUES (88, 87, 2, 1, '基本权限', 'config:base', 1, 'null', 1, 'admin', 1, 'admin', '2022-08-25 22:19:35', '2022-08-25 22:19:35');
INSERT INTO `t_sys_resource` VALUES (93, 0, 1, 1, '标签管理', '/tag', 3, '{\"icon\":\"CollectionTag\",\"isKeepAlive\":true,\"routeName\":\"Tag\"}', 1, 'admin', 1, 'admin', '2022-10-24 15:18:40', '2022-10-24 15:24:29');
INSERT INTO `t_sys_resource` VALUES (94, 93, 1, 1, '标签', 'tag-trees', 1, '{\"component\":\"TagTreeList\",\"icon\":\"CollectionTag\",\"isKeepAlive\":true,\"routeName\":\"TagTreeList\"}', 1, 'admin', 1, 'admin', '2022-10-24 15:19:40', '2022-10-24 15:28:07');
INSERT INTO `t_sys_resource` VALUES (95, 93, 1, 1, '团队管理', 'teams', 2, '{\"component\":\"TeamList\",\"icon\":\"UserFilled\",\"isKeepAlive\":true,\"routeName\":\"TeamList\"}', 1, 'admin', 1, 'admin', '2022-10-24 15:20:09', '2022-10-24 15:24:01');
INSERT INTO `t_sys_resource` VALUES (96, 94, 2, 1, '保存标签', 'tag:save', 1, 'null', 1, 'admin', 1, 'admin', '2022-10-24 15:20:40', '2022-10-26 13:58:36');
INSERT INTO `t_sys_resource` VALUES (97, 95, 2, 1, '保存团队', 'team:save', 1, 'null', 1, 'admin', 1, 'admin', '2022-10-24 15:20:57', '2022-10-26 13:58:56');
INSERT INTO `t_sys_resource` VALUES (98, 94, 2, 1, '删除标签', 'tag:del', 2, 'null', 1, 'admin', 1, 'admin', '2022-10-26 13:58:47', '2022-10-26 13:58:47');
INSERT INTO `t_sys_resource` VALUES (99, 95, 2, 1, '删除团队', 'team:del', 2, 'null', 1, 'admin', 1, 'admin', '2022-10-26 13:59:06', '2022-10-26 13:59:06');
INSERT INTO `t_sys_resource` VALUES (100, 95, 2, 1, '新增团队成员', 'team:member:save', 3, 'null', 1, 'admin', 1, 'admin', '2022-10-26 13:59:27', '2022-10-26 13:59:27');
INSERT INTO `t_sys_resource` VALUES (101, 95, 2, 1, '移除团队成员', 'team:member:del', 4, 'null', 1, 'admin', 1, 'admin', '2022-10-26 13:59:43', '2022-10-26 13:59:43');
INSERT INTO `t_sys_resource` VALUES (102, 95, 2, 1, '保存团队标签', 'team:tag:save', 5, 'null', 1, 'admin', 1, 'admin', '2022-10-26 13:59:57', '2022-10-26 13:59:57');
INSERT INTO `t_sys_resource` (id,pid,`type`,status,name,code,weight,meta,creator_id,creator,modifier_id,modifier,create_time,update_time) VALUES
(1,0,1,1,'首页','/home',1,'{"component":"home/Home","icon":"HomeFilled","isAffix":true,"isKeepAlive":true,"routeName":"Home"}',1,'admin',1,'admin','2021-05-25 16:44:41','2023-03-14 14:27:07'),
(2,0,1,1,'机器管理','/machine',4,'{"icon":"Monitor","isKeepAlive":true,"redirect":"machine/list","routeName":"Machine"}',1,'admin',1,'admin','2021-05-25 16:48:16','2022-10-06 14:58:49'),
(3,2,1,1,'机器列表','machines',2,'{"component":"ops/machine/MachineList","icon":"Monitor","isKeepAlive":true,"routeName":"MachineList"}',2,'admin',1,'admin','2021-05-25 16:50:04','2023-03-15 17:14:44'),
(4,0,1,1,'系统管理','/sys',8,'{"icon":"Setting","isKeepAlive":true,"redirect":"/sys/resources","routeName":"sys"}',1,'admin',1,'admin','2021-05-26 15:20:20','2022-10-06 14:59:53'),
(5,4,1,1,'资源管理','resources',3,'{"component":"system/resource/ResourceList","icon":"Menu","isKeepAlive":true,"routeName":"ResourceList"}',1,'admin',1,'admin','2021-05-26 15:23:07','2023-03-14 15:44:34'),
(11,4,1,1,'角色管理','roles',2,'{"component":"system/role/RoleList","icon":"Menu","isKeepAlive":true,"routeName":"RoleList"}',1,'admin',1,'admin','2021-05-27 11:15:35','2023-03-14 15:44:22'),
(12,3,2,1,'机器终端按钮','machine:terminal',4,'',1,'admin',1,'admin','2021-05-28 14:06:02','2021-05-31 17:47:59'),
(14,4,1,1,'账号管理','accounts',1,'{"component":"system/account/AccountList","icon":"Menu","isKeepAlive":true,"routeName":"AccountList"}',1,'admin',1,'admin','2021-05-28 14:56:25','2023-03-14 15:44:10'),
(15,3,2,1,'文件管理按钮','machine:file',5,NULL,1,'admin',1,'admin','2021-05-31 17:44:37','2021-05-31 17:48:07'),
(16,3,2,1,'机器添加按钮','machine:add',1,NULL,1,'admin',1,'admin','2021-05-31 17:46:11','2021-05-31 19:34:15'),
(17,3,2,1,'机器编辑按钮','machine:update',2,NULL,1,'admin',1,'admin','2021-05-31 17:46:23','2021-05-31 19:34:18'),
(18,3,2,1,'机器删除按钮','machine:del',3,NULL,1,'admin',1,'admin','2021-05-31 17:46:36','2021-05-31 19:34:17'),
(19,14,2,1,'角色分配按钮','account:saveRoles',1,NULL,1,'admin',1,'admin','2021-05-31 17:50:51','2021-05-31 19:19:30'),
(20,11,2,1,'分配菜单&权限按钮','role:saveResources',1,NULL,1,'admin',1,'admin','2021-05-31 17:51:41','2021-05-31 19:33:37'),
(21,14,2,1,'账号删除按钮','account:del',2,'null',1,'admin',1,'admin','2021-05-31 18:02:01','2021-06-10 17:12:17'),
(22,11,2,1,'角色删除按钮','role:del',2,NULL,1,'admin',1,'admin','2021-05-31 18:02:29','2021-05-31 19:33:38'),
(23,11,2,1,'角色新增按钮','role:add',3,NULL,1,'admin',1,'admin','2021-05-31 18:02:44','2021-05-31 19:33:39'),
(24,11,2,1,'角色编辑按钮','role:update',4,NULL,1,'admin',1,'admin','2021-05-31 18:02:57','2021-05-31 19:33:40'),
(25,5,2,1,'资源新增按钮','resource:add',1,NULL,1,'admin',1,'admin','2021-05-31 18:03:33','2021-05-31 19:31:47'),
(26,5,2,1,'资源删除按钮','resource:delete',2,NULL,1,'admin',1,'admin','2021-05-31 18:03:47','2021-05-31 19:29:40'),
(27,5,2,1,'资源编辑按钮','resource:update',3,NULL,1,'admin',1,'admin','2021-05-31 18:04:03','2021-05-31 19:29:40'),
(28,5,2,1,'资源禁用启用按钮','resource:changeStatus',4,NULL,1,'admin',1,'admin','2021-05-31 18:04:33','2021-05-31 18:04:33'),
(29,14,2,1,'账号添加按钮','account:add',3,NULL,1,'admin',1,'admin','2021-05-31 19:23:42','2021-05-31 19:23:42'),
(30,14,2,1,'账号编辑修改按钮','account:update',4,NULL,1,'admin',1,'admin','2021-05-31 19:23:58','2021-05-31 19:23:58'),
(31,14,2,1,'账号管理基本权限','account',0,'null',1,'admin',1,'admin','2021-05-31 21:25:06','2021-06-22 11:20:34'),
(32,5,2,1,'资源管理基本权限','resource',0,NULL,1,'admin',1,'admin','2021-05-31 21:25:25','2021-05-31 21:25:25'),
(33,11,2,1,'角色管理基本权限','role',0,NULL,1,'admin',1,'admin','2021-05-31 21:25:40','2021-05-31 21:25:40'),
(34,14,2,1,'账号启用禁用按钮','account:changeStatus',5,NULL,1,'admin',1,'admin','2021-05-31 21:29:48','2021-05-31 21:29:48'),
(36,0,1,1,'DBMS','/dbms',5,'{"icon":"Coin","isKeepAlive":true,"routeName":"DBMS"}',1,'admin',1,'admin','2021-06-01 14:01:33','2023-03-15 17:31:08'),
(37,3,2,1,'添加文件配置','machine:addFile',6,'null',1,'admin',1,'admin','2021-06-01 19:54:23','2021-06-01 19:54:23'),
(38,36,1,1,'数据操作','sql-exec',1,'{"component":"ops/db/SqlExec","icon":"Coin","isKeepAlive":true,"routeName":"SqlExec"}',1,'admin',1,'admin','2021-06-03 09:09:29','2023-03-15 17:31:21'),
(39,0,1,1,'个人中心','/personal',2,'{"component":"personal/index","icon":"UserFilled","isHide":true,"isKeepAlive":true,"routeName":"Personal"}',1,'admin',1,'admin','2021-06-03 14:25:35','2023-03-14 14:28:36'),
(40,3,2,1,'文件管理-新增按钮','machine:file:add',7,'null',1,'admin',1,'admin','2021-06-08 11:06:26','2021-06-08 11:12:28'),
(41,3,2,1,'文件管理-删除按钮','machine:file:del',8,'null',1,'admin',1,'admin','2021-06-08 11:06:49','2021-06-08 11:06:49'),
(42,3,2,1,'文件管理-写入or下载文件权限','machine:file:write',9,'null',1,'admin',1,'admin','2021-06-08 11:07:27','2021-06-08 11:07:27'),
(43,3,2,1,'文件管理-文件上传按钮','machine:file:upload',10,'null',1,'admin',1,'admin','2021-06-08 11:07:42','2021-06-08 11:07:42'),
(44,3,2,1,'文件管理-删除文件按钮','machine:file:rm',11,'null',1,'admin',1,'admin','2021-06-08 11:08:12','2021-06-08 11:08:12'),
(45,3,2,1,'脚本管理-保存脚本按钮','machine:script:save',12,'null',1,'admin',1,'admin','2021-06-08 11:09:01','2021-06-08 11:09:01'),
(46,3,2,1,'脚本管理-删除按钮','machine:script:del',13,'null',1,'admin',1,'admin','2021-06-08 11:09:27','2021-06-08 11:09:27'),
(47,3,2,1,'脚本管理-执行按钮','machine:script:run',14,'null',1,'admin',1,'admin','2021-06-08 11:09:50','2021-06-08 11:09:50'),
(49,36,1,1,'数据库管理','dbs',2,'{"component":"ops/db/DbList","icon":"Coin","isKeepAlive":true,"routeName":"DbList"}',1,'admin',1,'admin','2021-07-07 15:13:55','2023-03-15 17:31:28'),
(54,49,2,1,'数据库保存','db:save',1,'null',1,'admin',1,'admin','2021-07-08 17:30:36','2021-07-08 17:31:05'),
(55,49,2,1,'数据库删除','db:del',2,'null',1,'admin',1,'admin','2021-07-08 17:30:48','2021-07-08 17:30:48'),
(57,3,2,1,'基本权限','machine',0,'null',1,'admin',1,'admin','2021-07-09 10:48:02','2021-07-09 10:48:02'),
(58,49,2,1,'基本权限','db',0,'null',1,'admin',1,'admin','2021-07-09 10:48:22','2021-07-09 10:48:22'),
(59,38,2,1,'基本权限','db:exec',1,'null',1,'admin',1,'admin','2021-07-09 10:50:13','2021-07-09 10:50:13'),
(60,0,1,1,'Redis','/redis',6,'{"icon":"iconfont icon-redis","isKeepAlive":true,"routeName":"RDS"}',1,'admin',1,'admin','2021-07-19 20:15:41','2023-03-15 16:44:59'),
(61,60,1,1,'数据操作','data-operation',1,'{"component":"ops/redis/DataOperation","icon":"iconfont icon-redis","isKeepAlive":true,"routeName":"DataOperation"}',1,'admin',1,'admin','2021-07-19 20:17:29','2023-03-15 16:37:50'),
(62,61,2,1,'基本权限','redis:data',1,'null',1,'admin',1,'admin','2021-07-19 20:18:54','2021-07-19 20:18:54'),
(63,60,1,1,'redis管理','manage',2,'{"component":"ops/redis/RedisList","icon":"iconfont icon-redis","isKeepAlive":true,"routeName":"RedisList"}',1,'admin',1,'admin','2021-07-20 10:48:04','2023-03-15 16:38:00'),
(64,63,2,1,'基本权限','redis:manage',1,'null',1,'admin',1,'admin','2021-07-20 10:48:26','2021-07-20 10:48:26'),
(71,61,2,1,'数据保存','redis:data:save',6,'null',1,'admin',1,'admin','2021-08-17 11:20:37','2021-08-17 11:20:37'),
(72,3,2,1,'终止进程','machine:killprocess',6,'null',1,'admin',1,'admin','2021-08-17 11:20:37','2021-08-17 11:20:37'),
(79,0,1,1,'Mongo','/mongo',7,'{"icon":"iconfont icon-mongo","isKeepAlive":true,"routeName":"Mongo"}',1,'admin',1,'admin','2022-05-13 14:00:41','2023-03-16 14:23:22'),
(80,79,1,1,'数据操作','mongo-data-operation',1,'{"component":"ops/mongo/MongoDataOp","icon":"iconfont icon-mongo","isKeepAlive":true,"routeName":"MongoDataOp"}',1,'admin',1,'admin','2022-05-13 14:03:58','2023-03-15 17:15:02'),
(81,80,2,1,'基本权限','mongo:base',1,'null',1,'admin',1,'admin','2022-05-13 14:04:16','2022-05-13 14:04:16'),
(82,79,1,1,'Mongo管理','mongo-manage',2,'{"component":"ops/mongo/MongoList","icon":"iconfont icon-mongo","isKeepAlive":true,"routeName":"MongoList"}',1,'admin',1,'admin','2022-05-16 18:13:06','2023-03-15 17:26:55'),
(83,82,2,1,'基本权限','mongo:manage:base',1,'null',1,'admin',1,'admin','2022-05-16 18:13:25','2022-05-16 18:13:25'),
(84,4,1,1,'操作日志','syslogs',4,'{"component":"system/syslog/SyslogList","icon":"Tickets","routeName":"SyslogList"}',1,'admin',1,'admin','2022-07-13 19:57:07','2023-03-14 15:44:45'),
(85,84,2,1,'操作日志基本权限','syslog',1,'null',1,'admin',1,'admin','2022-07-13 19:57:55','2022-07-13 19:57:55'),
(87,4,1,1,'系统配置','configs',5,'{"component":"system/config/ConfigList","icon":"Setting","isKeepAlive":true,"routeName":"ConfigList"}',1,'admin',1,'admin','2022-08-25 22:18:55','2023-03-15 11:06:07'),
(88,87,2,1,'基本权限','config:base',1,'null',1,'admin',1,'admin','2022-08-25 22:19:35','2022-08-25 22:19:35'),
(93,0,1,1,'标签管理','/tag',3,'{"icon":"CollectionTag","isKeepAlive":true,"routeName":"Tag"}',1,'admin',1,'admin','2022-10-24 15:18:40','2022-10-24 15:24:29'),
(94,93,1,1,'标签树','tag-trees',1,'{"component":"ops/tag/TagTreeList","icon":"CollectionTag","isKeepAlive":true,"routeName":"TagTreeList"}',1,'admin',1,'admin','2022-10-24 15:19:40','2023-03-14 14:30:51'),
(95,93,1,1,'团队管理','teams',2,'{"component":"ops/tag/TeamList","icon":"UserFilled","isKeepAlive":true,"routeName":"TeamList"}',1,'admin',1,'admin','2022-10-24 15:20:09','2023-03-14 14:31:03'),
(96,94,2,1,'保存标签','tag:save',1,'null',1,'admin',1,'admin','2022-10-24 15:20:40','2022-10-26 13:58:36'),
(97,95,2,1,'保存团队','team:save',1,'null',1,'admin',1,'admin','2022-10-24 15:20:57','2022-10-26 13:58:56'),
(98,94,2,1,'删除标签','tag:del',2,'null',1,'admin',1,'admin','2022-10-26 13:58:47','2022-10-26 13:58:47'),
(99,95,2,1,'删除团队','team:del',2,'null',1,'admin',1,'admin','2022-10-26 13:59:06','2022-10-26 13:59:06'),
(100,95,2,1,'新增团队成员','team:member:save',3,'null',1,'admin',1,'admin','2022-10-26 13:59:27','2022-10-26 13:59:27'),
(101,95,2,1,'移除团队成员','team:member:del',4,'null',1,'admin',1,'admin','2022-10-26 13:59:43','2022-10-26 13:59:43'),
(102,95,2,1,'保存团队标签','team:tag:save',5,'null',1,'admin',1,'admin','2022-10-26 13:59:57','2022-10-26 13:59:57'),
(103,2,1,1,'授权凭证','authcerts',6,'{"component":"ops/machine/authcert/AuthCertList","icon":"Unlock","isKeepAlive":true,"routeName":"AuthCertList"}',1,'admin',1,'admin','2023-02-23 11:36:26','2023-03-14 14:33:28'),
(104,103,2,1,'基本权限','authcert',1,'null',1,'admin',1,'admin','2023-02-23 11:37:24','2023-02-23 11:37:24'),
(105,103,2,1,'保存权限','authcert:save',2,'null',1,'admin',1,'admin','2023-02-23 11:37:54','2023-02-23 11:37:54'),
(106,103,2,1,'删除权限','authcert:del',3,'null',1,'admin',1,'admin','2023-02-23 11:38:09','2023-02-23 11:38:09'),
(108,61,2,1,'数据删除','redis:data:del',3,'null',1,'admin',1,'admin','2023-03-14 17:20:00','2023-03-14 17:20:00'),
(109,3,2,1,'关闭连接','machine:close-cli',6,'null',1,'admin',1,'admin','2023-03-16 16:11:04','2023-03-16 16:11:04');
COMMIT;
-- ----------------------------
@@ -546,160 +569,170 @@ CREATE TABLE `t_sys_role_resource` (
-- Records of t_sys_role_resource
-- ----------------------------
BEGIN;
INSERT INTO `t_sys_role_resource` VALUES (1, 1, 1, 1, 'admin', '2021-05-27 15:07:39');
INSERT INTO `t_sys_role_resource` VALUES (323, 1, 2, 1, 'admin', '2021-05-28 09:04:50');
INSERT INTO `t_sys_role_resource` VALUES (326, 1, 4, 1, 'admin', '2021-05-28 09:04:50');
INSERT INTO `t_sys_role_resource` VALUES (327, 1, 5, 1, 'admin', '2021-05-28 09:04:50');
INSERT INTO `t_sys_role_resource` VALUES (328, 1, 11, 1, 'admin', '2021-05-28 09:04:50');
INSERT INTO `t_sys_role_resource` VALUES (335, 1, 14, 1, 'admin', '2021-05-28 17:42:21');
INSERT INTO `t_sys_role_resource` VALUES (336, 1, 3, 1, 'admin', '2021-05-28 17:42:43');
INSERT INTO `t_sys_role_resource` VALUES (337, 1, 12, 1, 'admin', '2021-05-28 17:42:43');
INSERT INTO `t_sys_role_resource` VALUES (338, 6, 2, 1, 'admin', '2021-05-28 19:19:38');
INSERT INTO `t_sys_role_resource` VALUES (339, 6, 3, 1, 'admin', '2021-05-28 19:19:38');
INSERT INTO `t_sys_role_resource` VALUES (342, 6, 1, 1, 'admin', '2021-05-29 01:31:22');
INSERT INTO `t_sys_role_resource` VALUES (343, 5, 1, 1, 'admin', '2021-05-31 14:05:23');
INSERT INTO `t_sys_role_resource` VALUES (344, 5, 4, 1, 'admin', '2021-05-31 14:05:23');
INSERT INTO `t_sys_role_resource` VALUES (345, 5, 14, 1, 'admin', '2021-05-31 14:05:23');
INSERT INTO `t_sys_role_resource` VALUES (346, 5, 5, 1, 'admin', '2021-05-31 14:05:23');
INSERT INTO `t_sys_role_resource` VALUES (347, 5, 11, 1, 'admin', '2021-05-31 14:05:23');
INSERT INTO `t_sys_role_resource` VALUES (348, 5, 3, 1, 'admin', '2021-05-31 16:33:14');
INSERT INTO `t_sys_role_resource` VALUES (349, 5, 12, 1, 'admin', '2021-05-31 16:33:14');
INSERT INTO `t_sys_role_resource` VALUES (350, 5, 2, 1, 'admin', '2021-05-31 16:33:14');
INSERT INTO `t_sys_role_resource` VALUES (353, 1, 15, 1, 'admin', '2021-05-31 17:48:33');
INSERT INTO `t_sys_role_resource` VALUES (354, 1, 16, 1, 'admin', '2021-05-31 17:48:33');
INSERT INTO `t_sys_role_resource` VALUES (355, 1, 17, 1, 'admin', '2021-05-31 17:48:33');
INSERT INTO `t_sys_role_resource` VALUES (356, 1, 18, 1, 'admin', '2021-05-31 17:48:33');
INSERT INTO `t_sys_role_resource` VALUES (358, 1, 20, 1, 'admin', '2021-05-31 17:52:08');
INSERT INTO `t_sys_role_resource` VALUES (360, 1, 22, 1, 'admin', '2021-05-31 18:05:04');
INSERT INTO `t_sys_role_resource` VALUES (361, 1, 23, 1, 'admin', '2021-05-31 18:05:04');
INSERT INTO `t_sys_role_resource` VALUES (362, 1, 24, 1, 'admin', '2021-05-31 18:05:04');
INSERT INTO `t_sys_role_resource` VALUES (363, 1, 25, 1, 'admin', '2021-05-31 18:05:04');
INSERT INTO `t_sys_role_resource` VALUES (364, 1, 26, 1, 'admin', '2021-05-31 18:05:04');
INSERT INTO `t_sys_role_resource` VALUES (365, 1, 27, 1, 'admin', '2021-05-31 18:05:04');
INSERT INTO `t_sys_role_resource` VALUES (366, 1, 28, 1, 'admin', '2021-05-31 18:05:04');
INSERT INTO `t_sys_role_resource` VALUES (369, 1, 31, 1, 'admin', '2021-05-31 21:25:56');
INSERT INTO `t_sys_role_resource` VALUES (370, 1, 32, 1, 'admin', '2021-05-31 21:25:56');
INSERT INTO `t_sys_role_resource` VALUES (371, 1, 33, 1, 'admin', '2021-05-31 21:25:56');
INSERT INTO `t_sys_role_resource` VALUES (374, 1, 36, 1, 'admin', '2021-06-01 14:01:57');
INSERT INTO `t_sys_role_resource` VALUES (375, 1, 19, 1, 'admin', '2021-06-01 17:34:03');
INSERT INTO `t_sys_role_resource` VALUES (376, 1, 21, 1, 'admin', '2021-06-01 17:34:03');
INSERT INTO `t_sys_role_resource` VALUES (377, 1, 29, 1, 'admin', '2021-06-01 17:34:03');
INSERT INTO `t_sys_role_resource` VALUES (378, 1, 30, 1, 'admin', '2021-06-01 17:34:03');
INSERT INTO `t_sys_role_resource` VALUES (379, 1, 34, 1, 'admin', '2021-06-01 17:34:03');
INSERT INTO `t_sys_role_resource` VALUES (380, 1, 37, 1, 'admin', '2021-06-03 09:09:42');
INSERT INTO `t_sys_role_resource` VALUES (381, 1, 38, 1, 'admin', '2021-06-03 09:09:42');
INSERT INTO `t_sys_role_resource` VALUES (383, 1, 40, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_sys_role_resource` VALUES (384, 1, 41, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_sys_role_resource` VALUES (385, 1, 42, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_sys_role_resource` VALUES (386, 1, 43, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_sys_role_resource` VALUES (387, 1, 44, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_sys_role_resource` VALUES (388, 1, 45, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_sys_role_resource` VALUES (389, 1, 46, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_sys_role_resource` VALUES (390, 1, 47, 1, 'admin', '2021-06-08 11:21:52');
INSERT INTO `t_sys_role_resource` VALUES (391, 6, 39, 1, 'admin', '2021-06-08 15:10:58');
INSERT INTO `t_sys_role_resource` VALUES (392, 6, 15, 1, 'admin', '2021-06-08 15:10:58');
INSERT INTO `t_sys_role_resource` VALUES (395, 6, 31, 1, 'admin', '2021-06-08 15:10:58');
INSERT INTO `t_sys_role_resource` VALUES (396, 6, 33, 1, 'admin', '2021-06-08 15:10:58');
INSERT INTO `t_sys_role_resource` VALUES (397, 6, 32, 1, 'admin', '2021-06-08 15:10:58');
INSERT INTO `t_sys_role_resource` VALUES (398, 6, 4, 1, 'admin', '2021-06-08 15:10:58');
INSERT INTO `t_sys_role_resource` VALUES (399, 6, 14, 1, 'admin', '2021-06-08 15:10:58');
INSERT INTO `t_sys_role_resource` VALUES (400, 6, 11, 1, 'admin', '2021-06-08 15:10:58');
INSERT INTO `t_sys_role_resource` VALUES (401, 6, 5, 1, 'admin', '2021-06-08 15:10:58');
INSERT INTO `t_sys_role_resource` VALUES (403, 7, 1, 1, 'admin', '2021-07-06 15:07:09');
INSERT INTO `t_sys_role_resource` VALUES (405, 1, 49, 1, 'admin', '2021-07-07 15:14:17');
INSERT INTO `t_sys_role_resource` VALUES (410, 1, 54, 1, 'admin', '2021-07-08 17:32:19');
INSERT INTO `t_sys_role_resource` VALUES (411, 1, 55, 1, 'admin', '2021-07-08 17:32:19');
INSERT INTO `t_sys_role_resource` VALUES (413, 1, 57, 1, 'admin', '2021-07-09 10:48:50');
INSERT INTO `t_sys_role_resource` VALUES (414, 1, 58, 1, 'admin', '2021-07-09 10:48:50');
INSERT INTO `t_sys_role_resource` VALUES (415, 8, 1, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (416, 8, 39, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (418, 8, 57, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (419, 8, 12, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (420, 8, 15, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (421, 8, 38, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (422, 8, 58, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (423, 8, 2, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (425, 8, 3, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (426, 8, 36, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (427, 8, 49, 1, 'admin', '2021-07-09 10:49:46');
INSERT INTO `t_sys_role_resource` VALUES (428, 1, 59, 1, 'admin', '2021-07-09 10:50:20');
INSERT INTO `t_sys_role_resource` VALUES (429, 8, 59, 1, 'admin', '2021-07-09 10:50:32');
INSERT INTO `t_sys_role_resource` VALUES (431, 6, 57, 1, 'admin', '2021-07-12 16:44:12');
INSERT INTO `t_sys_role_resource` VALUES (433, 1, 60, 1, 'admin', '2021-07-19 20:19:29');
INSERT INTO `t_sys_role_resource` VALUES (434, 1, 61, 1, 'admin', '2021-07-19 20:19:29');
INSERT INTO `t_sys_role_resource` VALUES (435, 1, 62, 1, 'admin', '2021-07-19 20:19:29');
INSERT INTO `t_sys_role_resource` VALUES (436, 1, 63, 1, 'admin', '2021-07-20 10:48:39');
INSERT INTO `t_sys_role_resource` VALUES (437, 1, 64, 1, 'admin', '2021-07-20 10:48:39');
INSERT INTO `t_sys_role_resource` VALUES (444, 7, 39, 1, 'admin', '2021-09-09 10:10:30');
INSERT INTO `t_sys_role_resource` VALUES (450, 6, 16, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (451, 6, 17, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (452, 6, 18, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (453, 6, 37, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (454, 6, 40, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (455, 6, 41, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (456, 6, 42, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (457, 6, 43, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (458, 6, 44, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (459, 6, 45, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (460, 6, 46, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (461, 6, 47, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (462, 6, 36, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (463, 6, 38, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (464, 6, 59, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (465, 6, 49, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (466, 6, 58, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (467, 6, 54, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (468, 6, 55, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (469, 6, 60, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (470, 6, 61, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (471, 6, 62, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (472, 6, 63, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (473, 6, 64, 1, 'admin', '2021-09-09 15:52:38');
INSERT INTO `t_sys_role_resource` VALUES (479, 6, 19, 1, 'admin', '2021-09-09 15:53:56');
INSERT INTO `t_sys_role_resource` VALUES (480, 6, 21, 1, 'admin', '2021-09-09 15:53:56');
INSERT INTO `t_sys_role_resource` VALUES (481, 6, 29, 1, 'admin', '2021-09-09 15:53:56');
INSERT INTO `t_sys_role_resource` VALUES (482, 6, 30, 1, 'admin', '2021-09-09 15:53:56');
INSERT INTO `t_sys_role_resource` VALUES (483, 6, 34, 1, 'admin', '2021-09-09 15:53:56');
INSERT INTO `t_sys_role_resource` VALUES (484, 6, 20, 1, 'admin', '2021-09-09 15:53:56');
INSERT INTO `t_sys_role_resource` VALUES (485, 6, 22, 1, 'admin', '2021-09-09 15:53:56');
INSERT INTO `t_sys_role_resource` VALUES (486, 6, 23, 1, 'admin', '2021-09-09 15:53:56');
INSERT INTO `t_sys_role_resource` VALUES (487, 6, 24, 1, 'admin', '2021-09-09 15:53:56');
INSERT INTO `t_sys_role_resource` VALUES (488, 6, 25, 1, 'admin', '2021-09-09 15:53:56');
INSERT INTO `t_sys_role_resource` VALUES (489, 6, 26, 1, 'admin', '2021-09-09 15:53:56');
INSERT INTO `t_sys_role_resource` VALUES (490, 6, 27, 1, 'admin', '2021-09-09 15:53:56');
INSERT INTO `t_sys_role_resource` VALUES (491, 6, 28, 1, 'admin', '2021-09-09 15:53:56');
INSERT INTO `t_sys_role_resource` VALUES (492, 8, 42, 1, 'admin', '2021-11-05 15:59:16');
INSERT INTO `t_sys_role_resource` VALUES (493, 8, 43, 1, 'admin', '2021-11-05 15:59:16');
INSERT INTO `t_sys_role_resource` VALUES (494, 8, 47, 1, 'admin', '2021-11-05 15:59:16');
INSERT INTO `t_sys_role_resource` VALUES (495, 8, 60, 1, 'admin', '2021-11-05 15:59:16');
INSERT INTO `t_sys_role_resource` VALUES (496, 8, 61, 1, 'admin', '2021-11-05 15:59:16');
INSERT INTO `t_sys_role_resource` VALUES (497, 8, 62, 1, 'admin', '2021-11-05 15:59:16');
INSERT INTO `t_sys_role_resource` VALUES (498, 8, 63, 1, 'admin', '2021-11-05 15:59:16');
INSERT INTO `t_sys_role_resource` VALUES (499, 8, 64, 1, 'admin', '2021-11-05 15:59:16');
INSERT INTO `t_sys_role_resource` VALUES (500, 1, 72, 1, 'admin', '2022-07-14 11:03:09');
INSERT INTO `t_sys_role_resource` VALUES (501, 1, 71, 1, 'admin', '2022-07-14 11:03:09');
INSERT INTO `t_sys_role_resource` VALUES (502, 1, 79, 1, 'admin', '2022-07-14 11:03:09');
INSERT INTO `t_sys_role_resource` VALUES (503, 1, 80, 1, 'admin', '2022-07-14 11:03:09');
INSERT INTO `t_sys_role_resource` VALUES (504, 1, 81, 1, 'admin', '2022-07-14 11:03:09');
INSERT INTO `t_sys_role_resource` VALUES (505, 1, 82, 1, 'admin', '2022-07-14 11:03:09');
INSERT INTO `t_sys_role_resource` VALUES (506, 1, 83, 1, 'admin', '2022-07-14 11:03:09');
INSERT INTO `t_sys_role_resource` VALUES (507, 1, 84, 1, 'admin', '2022-07-14 11:10:11');
INSERT INTO `t_sys_role_resource` VALUES (508, 1, 85, 1, 'admin', '2022-07-14 11:10:11');
INSERT INTO `t_sys_role_resource` VALUES (510, 1, 87, 1, 'admin', '2022-07-14 11:10:11');
INSERT INTO `t_sys_role_resource` VALUES (511, 1, 88, 1, 'admin', '2022-10-08 10:54:06');
INSERT INTO `t_sys_role_resource` VALUES (512, 8, 80, 1, 'admin', '2022-10-08 10:54:34');
INSERT INTO `t_sys_role_resource` VALUES (513, 8, 81, 1, 'admin', '2022-10-08 10:54:34');
INSERT INTO `t_sys_role_resource` VALUES (515, 8, 79, 1, 'admin', '2022-10-08 10:54:34');
INSERT INTO `t_sys_role_resource` VALUES (516, 1, 93, 1, 'admin', '2022-10-26 20:03:14');
INSERT INTO `t_sys_role_resource` VALUES (517, 1, 94, 1, 'admin', '2022-10-26 20:03:14');
INSERT INTO `t_sys_role_resource` VALUES (518, 1, 96, 1, 'admin', '2022-10-26 20:03:14');
INSERT INTO `t_sys_role_resource` VALUES (519, 1, 98, 1, 'admin', '2022-10-26 20:03:14');
INSERT INTO `t_sys_role_resource` VALUES (520, 1, 95, 1, 'admin', '2022-10-26 20:03:14');
INSERT INTO `t_sys_role_resource` VALUES (521, 1, 97, 1, 'admin', '2022-10-26 20:03:14');
INSERT INTO `t_sys_role_resource` VALUES (522, 1, 99, 1, 'admin', '2022-10-26 20:03:14');
INSERT INTO `t_sys_role_resource` VALUES (523, 1, 100, 1, 'admin', '2022-10-26 20:03:14');
INSERT INTO `t_sys_role_resource` VALUES (524, 1, 101, 1, 'admin', '2022-10-26 20:03:14');
INSERT INTO `t_sys_role_resource` VALUES (525, 1, 102, 1, 'admin', '2022-10-26 20:03:14');
INSERT INTO `t_sys_role_resource` (id,role_id,resource_id,creator_id,creator,create_time) VALUES
(1,1,1,1,'admin','2021-05-27 15:07:39'),
(323,1,2,1,'admin','2021-05-28 09:04:50'),
(326,1,4,1,'admin','2021-05-28 09:04:50'),
(327,1,5,1,'admin','2021-05-28 09:04:50'),
(328,1,11,1,'admin','2021-05-28 09:04:50'),
(335,1,14,1,'admin','2021-05-28 17:42:21'),
(336,1,3,1,'admin','2021-05-28 17:42:43'),
(337,1,12,1,'admin','2021-05-28 17:42:43'),
(338,6,2,1,'admin','2021-05-28 19:19:38'),
(339,6,3,1,'admin','2021-05-28 19:19:38'),
(342,6,1,1,'admin','2021-05-29 01:31:22'),
(343,5,1,1,'admin','2021-05-31 14:05:23'),
(344,5,4,1,'admin','2021-05-31 14:05:23'),
(345,5,14,1,'admin','2021-05-31 14:05:23'),
(346,5,5,1,'admin','2021-05-31 14:05:23'),
(347,5,11,1,'admin','2021-05-31 14:05:23'),
(348,5,3,1,'admin','2021-05-31 16:33:14'),
(349,5,12,1,'admin','2021-05-31 16:33:14'),
(350,5,2,1,'admin','2021-05-31 16:33:14'),
(353,1,15,1,'admin','2021-05-31 17:48:33'),
(354,1,16,1,'admin','2021-05-31 17:48:33'),
(355,1,17,1,'admin','2021-05-31 17:48:33'),
(356,1,18,1,'admin','2021-05-31 17:48:33'),
(358,1,20,1,'admin','2021-05-31 17:52:08'),
(360,1,22,1,'admin','2021-05-31 18:05:04'),
(361,1,23,1,'admin','2021-05-31 18:05:04'),
(362,1,24,1,'admin','2021-05-31 18:05:04'),
(363,1,25,1,'admin','2021-05-31 18:05:04'),
(364,1,26,1,'admin','2021-05-31 18:05:04'),
(365,1,27,1,'admin','2021-05-31 18:05:04'),
(366,1,28,1,'admin','2021-05-31 18:05:04'),
(369,1,31,1,'admin','2021-05-31 21:25:56'),
(370,1,32,1,'admin','2021-05-31 21:25:56'),
(371,1,33,1,'admin','2021-05-31 21:25:56'),
(374,1,36,1,'admin','2021-06-01 14:01:57'),
(375,1,19,1,'admin','2021-06-01 17:34:03'),
(376,1,21,1,'admin','2021-06-01 17:34:03'),
(377,1,29,1,'admin','2021-06-01 17:34:03'),
(378,1,30,1,'admin','2021-06-01 17:34:03'),
(379,1,34,1,'admin','2021-06-01 17:34:03'),
(380,1,37,1,'admin','2021-06-03 09:09:42'),
(381,1,38,1,'admin','2021-06-03 09:09:42'),
(383,1,40,1,'admin','2021-06-08 11:21:52'),
(384,1,41,1,'admin','2021-06-08 11:21:52'),
(385,1,42,1,'admin','2021-06-08 11:21:52'),
(386,1,43,1,'admin','2021-06-08 11:21:52'),
(387,1,44,1,'admin','2021-06-08 11:21:52'),
(388,1,45,1,'admin','2021-06-08 11:21:52'),
(389,1,46,1,'admin','2021-06-08 11:21:52'),
(390,1,47,1,'admin','2021-06-08 11:21:52'),
(391,6,39,1,'admin','2021-06-08 15:10:58'),
(392,6,15,1,'admin','2021-06-08 15:10:58'),
(395,6,31,1,'admin','2021-06-08 15:10:58'),
(396,6,33,1,'admin','2021-06-08 15:10:58'),
(397,6,32,1,'admin','2021-06-08 15:10:58'),
(398,6,4,1,'admin','2021-06-08 15:10:58'),
(399,6,14,1,'admin','2021-06-08 15:10:58'),
(400,6,11,1,'admin','2021-06-08 15:10:58'),
(401,6,5,1,'admin','2021-06-08 15:10:58'),
(403,7,1,1,'admin','2021-07-06 15:07:09'),
(405,1,49,1,'admin','2021-07-07 15:14:17'),
(410,1,54,1,'admin','2021-07-08 17:32:19'),
(411,1,55,1,'admin','2021-07-08 17:32:19'),
(413,1,57,1,'admin','2021-07-09 10:48:50'),
(414,1,58,1,'admin','2021-07-09 10:48:50'),
(418,8,57,1,'admin','2021-07-09 10:49:46'),
(419,8,12,1,'admin','2021-07-09 10:49:46'),
(420,8,15,1,'admin','2021-07-09 10:49:46'),
(421,8,38,1,'admin','2021-07-09 10:49:46'),
(423,8,2,1,'admin','2021-07-09 10:49:46'),
(425,8,3,1,'admin','2021-07-09 10:49:46'),
(426,8,36,1,'admin','2021-07-09 10:49:46'),
(428,1,59,1,'admin','2021-07-09 10:50:20'),
(429,8,59,1,'admin','2021-07-09 10:50:32'),
(431,6,57,1,'admin','2021-07-12 16:44:12'),
(433,1,60,1,'admin','2021-07-19 20:19:29'),
(434,1,61,1,'admin','2021-07-19 20:19:29'),
(435,1,62,1,'admin','2021-07-19 20:19:29'),
(436,1,63,1,'admin','2021-07-20 10:48:39'),
(437,1,64,1,'admin','2021-07-20 10:48:39'),
(444,7,39,1,'admin','2021-09-09 10:10:30'),
(450,6,16,1,'admin','2021-09-09 15:52:38'),
(451,6,17,1,'admin','2021-09-09 15:52:38'),
(452,6,18,1,'admin','2021-09-09 15:52:38'),
(453,6,37,1,'admin','2021-09-09 15:52:38'),
(454,6,40,1,'admin','2021-09-09 15:52:38'),
(455,6,41,1,'admin','2021-09-09 15:52:38'),
(456,6,42,1,'admin','2021-09-09 15:52:38'),
(457,6,43,1,'admin','2021-09-09 15:52:38'),
(458,6,44,1,'admin','2021-09-09 15:52:38'),
(459,6,45,1,'admin','2021-09-09 15:52:38'),
(460,6,46,1,'admin','2021-09-09 15:52:38'),
(461,6,47,1,'admin','2021-09-09 15:52:38'),
(462,6,36,1,'admin','2021-09-09 15:52:38'),
(463,6,38,1,'admin','2021-09-09 15:52:38'),
(464,6,59,1,'admin','2021-09-09 15:52:38'),
(465,6,49,1,'admin','2021-09-09 15:52:38'),
(466,6,58,1,'admin','2021-09-09 15:52:38'),
(467,6,54,1,'admin','2021-09-09 15:52:38'),
(468,6,55,1,'admin','2021-09-09 15:52:38'),
(469,6,60,1,'admin','2021-09-09 15:52:38'),
(470,6,61,1,'admin','2021-09-09 15:52:38'),
(471,6,62,1,'admin','2021-09-09 15:52:38'),
(472,6,63,1,'admin','2021-09-09 15:52:38'),
(473,6,64,1,'admin','2021-09-09 15:52:38'),
(479,6,19,1,'admin','2021-09-09 15:53:56'),
(480,6,21,1,'admin','2021-09-09 15:53:56'),
(481,6,29,1,'admin','2021-09-09 15:53:56'),
(482,6,30,1,'admin','2021-09-09 15:53:56'),
(483,6,34,1,'admin','2021-09-09 15:53:56'),
(484,6,20,1,'admin','2021-09-09 15:53:56'),
(485,6,22,1,'admin','2021-09-09 15:53:56'),
(486,6,23,1,'admin','2021-09-09 15:53:56'),
(487,6,24,1,'admin','2021-09-09 15:53:56'),
(488,6,25,1,'admin','2021-09-09 15:53:56'),
(489,6,26,1,'admin','2021-09-09 15:53:56'),
(490,6,27,1,'admin','2021-09-09 15:53:56'),
(491,6,28,1,'admin','2021-09-09 15:53:56'),
(492,8,42,1,'admin','2021-11-05 15:59:16'),
(493,8,43,1,'admin','2021-11-05 15:59:16'),
(494,8,47,1,'admin','2021-11-05 15:59:16'),
(495,8,60,1,'admin','2021-11-05 15:59:16'),
(496,8,61,1,'admin','2021-11-05 15:59:16'),
(497,8,62,1,'admin','2021-11-05 15:59:16'),
(500,1,72,1,'admin','2022-07-14 11:03:09'),
(501,1,71,1,'admin','2022-07-14 11:03:09'),
(502,1,79,1,'admin','2022-07-14 11:03:09'),
(503,1,80,1,'admin','2022-07-14 11:03:09'),
(504,1,81,1,'admin','2022-07-14 11:03:09'),
(505,1,82,1,'admin','2022-07-14 11:03:09'),
(506,1,83,1,'admin','2022-07-14 11:03:09'),
(507,1,84,1,'admin','2022-07-14 11:10:11'),
(508,1,85,1,'admin','2022-07-14 11:10:11'),
(510,1,87,1,'admin','2022-07-14 11:10:11'),
(511,1,88,1,'admin','2022-10-08 10:54:06'),
(512,8,80,1,'admin','2022-10-08 10:54:34'),
(513,8,81,1,'admin','2022-10-08 10:54:34'),
(515,8,79,1,'admin','2022-10-08 10:54:34'),
(516,1,93,1,'admin','2022-10-26 20:03:14'),
(517,1,94,1,'admin','2022-10-26 20:03:14'),
(518,1,96,1,'admin','2022-10-26 20:03:14'),
(519,1,98,1,'admin','2022-10-26 20:03:14'),
(520,1,95,1,'admin','2022-10-26 20:03:14'),
(521,1,97,1,'admin','2022-10-26 20:03:14'),
(522,1,99,1,'admin','2022-10-26 20:03:14'),
(523,1,100,1,'admin','2022-10-26 20:03:14'),
(524,1,101,1,'admin','2022-10-26 20:03:14'),
(525,1,102,1,'admin','2022-10-26 20:03:14'),
(527,1,106,1,'admin','2023-02-23 14:30:54'),
(528,1,103,1,'admin','2023-02-23 14:30:54'),
(529,1,105,1,'admin','2023-02-23 14:31:00'),
(530,1,104,1,'admin','2023-02-24 13:40:26'),
(532,1,108,1,'admin','2023-03-14 17:28:06'),
(533,6,79,1,'admin','2023-03-14 17:28:50'),
(534,6,80,1,'admin','2023-03-14 17:28:50'),
(535,6,81,1,'admin','2023-03-14 17:28:50'),
(536,6,82,1,'admin','2023-03-14 17:28:50'),
(537,6,83,1,'admin','2023-03-14 17:28:50'),
(538,6,84,1,'admin','2023-03-14 17:29:00'),
(539,6,85,1,'admin','2023-03-14 17:29:00'),
(540,6,87,1,'admin','2023-03-14 17:29:00'),
(541,6,88,1,'admin','2023-03-14 17:29:00'),
(544,1,109,1,'admin','2023-03-16 16:11:25');
COMMIT;
-- ----------------------------

View File

@@ -3,61 +3,62 @@ module mayfly-go
go 1.20
require (
github.com/gin-gonic/gin v1.9.0
github.com/go-sql-driver/mysql v1.7.0
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/gin-gonic/gin v1.9.1
github.com/go-sql-driver/mysql v1.7.1
github.com/golang-jwt/jwt/v5 v5.0.0
github.com/gorilla/websocket v1.5.0
github.com/lib/pq v1.10.7
github.com/mojocn/base64Captcha v1.3.5 //
github.com/pkg/sftp v1.13.5
github.com/redis/go-redis/v9 v9.0.2
github.com/redis/go-redis/v9 v9.0.5
github.com/robfig/cron/v3 v3.0.1 //
github.com/sirupsen/logrus v1.9.0
github.com/sirupsen/logrus v1.9.3
github.com/xwb1989/sqlparser v0.0.0-20180606152119-120387863bf2
go.mongodb.org/mongo-driver v1.11.4 // mongo
golang.org/x/crypto v0.8.0 // ssh
golang.org/x/crypto v0.10.0 // ssh
gopkg.in/yaml.v3 v3.0.1
// gorm
gorm.io/driver/mysql v1.5.0
gorm.io/gorm v1.25.0
gorm.io/gorm v1.25.1
)
require (
github.com/bytedance/sonic v1.8.0 // indirect
github.com/bytedance/sonic v1.9.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/gin-contrib/sse v0.1.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.11.2 // indirect
github.com/goccy/go-json v0.10.0 // indirect
github.com/go-playground/validator/v10 v10.14.0 // indirect
github.com/goccy/go-json v0.10.2 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/golang/snappy v0.0.1 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/klauspost/compress v1.13.6 // indirect
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
github.com/klauspost/cpuid/v2 v2.2.4 // indirect
github.com/kr/fs v0.1.0 // indirect
github.com/leodido/go-urn v1.2.1 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/leodido/go-urn v1.2.4 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
github.com/ugorji/go/codec v1.2.9 // indirect
github.com/ugorji/go/codec v1.2.11 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.1 // indirect
github.com/xdg-go/stringprep v1.0.3 // indirect
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
golang.org/x/arch v0.0.0-20210923205945-b76863e36670 // indirect
golang.org/x/arch v0.3.0 // indirect
golang.org/x/image v0.0.0-20220302094943-723b81ca9867 // indirect
golang.org/x/net v0.9.0 // indirect
golang.org/x/net v0.10.0 // indirect
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect
golang.org/x/sys v0.7.0 // indirect
golang.org/x/text v0.9.0 // indirect
google.golang.org/protobuf v1.28.1 // indirect
golang.org/x/sys v0.9.0 // indirect
golang.org/x/text v0.10.0 // indirect
google.golang.org/protobuf v1.30.0 // indirect
)

View File

@@ -36,7 +36,7 @@ func (i *Index) Count(rc *req.Ctx) {
dbNum = i.DbApp.Count(&dbentity.DbQuery{TagIds: tagIds})
redisNum = i.RedisApp.Count(&redisentity.RedisQuery{TagIds: tagIds})
}
rc.ResData = map[string]interface{}{
rc.ResData = map[string]any{
"mongoNum": mongoNum,
"machineNum": machienNum,
"dbNum": dbNum,

View File

@@ -164,7 +164,7 @@ func (d *Db) ExecSql(rc *req.Ctx) {
}
}
colAndRes := make(map[string]interface{})
colAndRes := make(map[string]any)
colAndRes["colNames"] = execResAll.ColNames
colAndRes["res"] = execResAll.Res
rc.ResData = colAndRes
@@ -266,7 +266,7 @@ func (d *Db) DumpSql(rc *req.Ctx) {
if needStruct {
writer.WriteString(fmt.Sprintf("\n-- ----------------------------\n-- 表结构: %s \n-- ----------------------------\n", table))
writer.WriteString(fmt.Sprintf("DROP TABLE IF EXISTS `%s`;\n", table))
writer.WriteString(dbmeta.GetCreateTableDdl(table)[0]["Create Table"].(string) + ";\n")
writer.WriteString(dbmeta.GetCreateTableDdl(table) + ";\n")
}
if !needData {
@@ -339,7 +339,7 @@ func (d *Db) HintTables(rc *req.Ctx) {
tables := dm.GetTables()
tableNames := make([]string, 0)
for _, v := range tables {
tableNames = append(tableNames, v["tableName"].(string))
tableNames = append(tableNames, v.TableName)
}
// key = 表名value = 列名数组
res := make(map[string][]string)
@@ -353,15 +353,15 @@ func (d *Db) HintTables(rc *req.Ctx) {
// 获取所有表下的所有列信息
columnMds := dm.GetColumns(tableNames...)
for _, v := range columnMds {
tName := v["tableName"].(string)
tName := v.TableName
if res[tName] == nil {
res[tName] = make([]string, 0)
}
columnName := fmt.Sprintf("%s [%s]", v["columnName"], v["columnType"])
comment := v["columnComment"]
columnName := fmt.Sprintf("%s [%s]", v.ColumnName, v.ColumnType)
comment := v.ColumnComment
// 如果字段备注不为空,则加上备注信息
if comment != nil && comment != "" {
if comment != "" {
columnName = fmt.Sprintf("%s[%s]", columnName, comment)
}

View File

@@ -1,7 +1,7 @@
package form
type DbForm struct {
Id uint64
Id uint64 `json:"id"`
Name string `binding:"required" json:"name"`
Type string `binding:"required" json:"type"` // 类型mysql oracle等
Host string `binding:"required" json:"host"`
@@ -17,10 +17,10 @@ type DbForm struct {
}
type DbSqlSaveForm struct {
Name string `binding:"required"`
Sql string `binding:"required"`
Type int `binding:"required"`
Db string `binding:"required"`
Name string `json:"name" binding:"required"`
Sql string `json:"sql" binding:"required"`
Type int `json:"type" binding:"required"`
Db string `json:"db" binding:"required"`
}
// 数据库SQL执行表单

View File

@@ -21,7 +21,7 @@ import (
type Db interface {
// 分页获取
GetPageList(condition *entity.DbQuery, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetPageList(condition *entity.DbQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
Count(condition *entity.DbQuery) int64
@@ -58,7 +58,7 @@ type dbAppImpl struct {
}
// 分页获取数据库信息列表
func (d *dbAppImpl) GetPageList(condition *entity.DbQuery, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
func (d *dbAppImpl) GetPageList(condition *entity.DbQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult {
return d.dbRepo.GetDbList(condition, pageParam, toEntity, orderBy...)
}
@@ -108,19 +108,19 @@ func (d *dbAppImpl) Save(dbEntity *entity.Db) {
dbId := dbEntity.Id
old := d.GetById(dbId)
var oldDbs []interface{}
var oldDbs []any
for _, v := range strings.Split(old.Database, " ") {
// 关闭数据库连接
CloseDb(dbEntity.Id, v)
oldDbs = append(oldDbs, v)
}
var newDbs []interface{}
var newDbs []any
for _, v := range strings.Split(dbEntity.Database, " ") {
newDbs = append(newDbs, v)
}
// 比较新旧数据库列表,需要将移除的数据库相关联的信息删除
_, delDb, _ := utils.ArrayCompare(newDbs, oldDbs, func(i1, i2 interface{}) bool {
_, delDb, _ := utils.ArrayCompare(newDbs, oldDbs, func(i1, i2 any) bool {
return i1.(string) == i2.(string)
})
for _, v := range delDb {
@@ -249,22 +249,15 @@ type DbInstance struct {
// 执行查询语句
// 依次返回 列名数组结果map错误
func (d *DbInstance) SelectData(execSql string) ([]string, []map[string]interface{}, error) {
func (d *DbInstance) SelectData(execSql string) ([]string, []map[string]any, error) {
return SelectDataByDb(d.db, execSql)
}
// 将查询结果映射至struct可具体参考sqlx库
func (d *DbInstance) SelectData2Struct(execSql string, dest interface{}) error {
func (d *DbInstance) SelectData2Struct(execSql string, dest any) error {
return Select2StructByDb(d.db, execSql, dest)
}
// 执行内部查询语句,不返回列名以及不限制行数
// 依次返回 结果map错误
func (d *DbInstance) innerSelect(execSql string) ([]map[string]interface{}, error) {
_, res, err := SelectDataByDb(d.db, execSql)
return res, err
}
// 执行 update, insert, delete建表等sql
// 返回影响条数和错误
func (d *DbInstance) Exec(sql string) (int64, error) {
@@ -302,7 +295,7 @@ func (d *DbInstance) Close() {
// 客户端连接缓存,指定时间内没有访问则会被关闭, key为数据库实例id:数据库
var dbCache = cache.NewTimedCache(constant.DbConnExpireTime, 5*time.Second).
WithUpdateAccessTime(true).
OnEvicted(func(key interface{}, value interface{}) {
OnEvicted(func(key any, value any) {
global.Log.Info(fmt.Sprintf("删除db连接缓存 id = %s", key))
value.(*DbInstance).Close()
})
@@ -360,7 +353,7 @@ func GetDbConn(d *entity.Db, db string) (*sql.DB, error) {
return DB, nil
}
func SelectDataByDb(db *sql.DB, selectSql string) ([]string, []map[string]interface{}, error) {
func SelectDataByDb(db *sql.DB, selectSql string) ([]string, []map[string]any, error) {
rows, err := db.Query(selectSql)
if err != nil {
return nil, nil, err
@@ -374,7 +367,7 @@ func SelectDataByDb(db *sql.DB, selectSql string) ([]string, []map[string]interf
}()
colTypes, _ := rows.ColumnTypes()
// 这里表示一行填充数据
scans := make([]interface{}, len(colTypes))
scans := make([]any, len(colTypes))
// 这里表示一行所有列的值,用[]byte表示
vals := make([][]byte, len(colTypes))
// 这里scans引用vals把数据填充到[]byte里
@@ -382,7 +375,7 @@ func SelectDataByDb(db *sql.DB, selectSql string) ([]string, []map[string]interf
scans[k] = &vals[k]
}
result := make([]map[string]interface{}, 0)
result := make([]map[string]any, 0)
// 列名用于前端表头名称按照数据库与查询字段顺序显示
colNames := make([]string, 0)
// 是否第一次遍历,列名数组只需第一次遍历时加入
@@ -394,7 +387,7 @@ func SelectDataByDb(db *sql.DB, selectSql string) ([]string, []map[string]interf
return nil, nil, err
}
// 每行数据
rowData := make(map[string]interface{})
rowData := make(map[string]any)
// 把vals中的数据复制到row中
for i, v := range vals {
colType := colTypes[i]
@@ -413,7 +406,7 @@ func SelectDataByDb(db *sql.DB, selectSql string) ([]string, []map[string]interf
}
// 将查询的值转为对应列类型的实际值,不全部转为字符串
func valueConvert(data []byte, colType *sql.ColumnType) interface{} {
func valueConvert(data []byte, colType *sql.ColumnType) any {
if data == nil {
return nil
}
@@ -462,7 +455,7 @@ func valueConvert(data []byte, colType *sql.ColumnType) interface{} {
}
// 查询数据结果映射至struct。可参考sqlx库
func Select2StructByDb(db *sql.DB, selectSql string, dest interface{}) error {
func Select2StructByDb(db *sql.DB, selectSql string, dest any) error {
rows, err := db.Query(selectSql)
if err != nil {
return err

View File

@@ -26,7 +26,7 @@ type DbSqlExecReq struct {
type DbSqlExecRes struct {
ColNames []string
Res []map[string]interface{}
Res []map[string]any
}
// 合并执行结果主要用于执行多条sql使用
@@ -52,7 +52,7 @@ type DbSqlExec interface {
DeleteBy(condition *entity.DbSqlExec)
// 分页获取
GetPageList(condition *entity.DbSqlExec, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetPageList(condition *entity.DbSqlExec, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
}
func newDbSqlExecApp(dbExecSqlRepo repository.DbSqlExec) DbSqlExec {
@@ -151,7 +151,7 @@ func (d *dbSqlExecAppImpl) DeleteBy(condition *entity.DbSqlExec) {
d.dbSqlExecRepo.DeleteBy(condition)
}
func (d *dbSqlExecAppImpl) GetPageList(condition *entity.DbSqlExec, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
func (d *dbSqlExecAppImpl) GetPageList(condition *entity.DbSqlExec, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult {
return d.dbSqlExecRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
}
@@ -256,8 +256,8 @@ func doExec(sql string, dbInstance *DbInstance) (*DbSqlExecRes, error) {
if err != nil {
execRes = err.Error()
}
res := make([]map[string]interface{}, 0)
resData := make(map[string]interface{})
res := make([]map[string]any, 0)
resData := make(map[string]any)
resData["rowsAffected"] = rowsAffected
resData["sql"] = sql
resData["result"] = execRes

View File

@@ -1,32 +1,102 @@
package application
import (
"embed"
"mayfly-go/pkg/biz"
"strings"
)
// 表信息
type Table struct {
TableName string `json:"tableName"` // 表名
TableComment string `json:"tableComment"` // 表备注
CreateTime string `json:"createTime"` // 创建时间
TableRows int `json:"tableRows"`
DataLength int64 `json:"dataLength"`
IndexLength int64 `json:"indexLength"`
}
// 表的列信息
type Column struct {
TableName string `json:"tableName"` // 表名
ColumnName string `json:"columnName"` // 列名
ColumnType string `json:"columnType"` // 列类型
ColumnComment string `json:"columnComment"` // 列备注
ColumnKey string `json:"columnKey"`
ColumnDefault string `json:"columnDefault"`
Nullable string `json:"nullable"` // 是否可为null
Extra string `json:"extra"` // 其他信息
}
// 表索引信息
type Index struct {
IndexName string `json:"indexName"` // 索引名
ColumnName string `json:"columnName"` // 列名
IndexType string `json:"indexType"` // 索引类型
IndexComment string `json:"indexComment"` // 备注
SeqInIndex int `json:"seqInIndex"`
NonUnique int `json:"nonUnique"`
}
// -----------------------------------元数据接口定义------------------------------------------
// 数据库元信息接口(表、列、获取表数据等元信息)
// 所有数据查出来直接用map接收注意不同数据库实现该接口返回的map中的key需要统一.
// 即: 使用别名统一即可。如table_name AS tableName
type DbMetadata interface {
// 获取表基础元信息
// 表名: tableName, 备注: tableComment
GetTables() []map[string]interface{}
GetTables() []Table
// 获取指定表名的所有列元信息
// 表名: tableName, 列名: columnName, 列类型: columnType, 备注: columnComment, 是否可为null: nullable, 其他信息: extra
GetColumns(tableNames ...string) []map[string]interface{}
GetColumns(tableNames ...string) []Column
// 获取表主键字段名,没有主键标识则默认第一个字段
GetPrimaryKey(tablename string) string
// 获取表信息比GetTables获取更详细的表信息
GetTableInfos() []map[string]interface{}
GetTableInfos() []Table
// 获取表索引信息
GetTableIndex(tableName string) []map[string]interface{}
GetTableIndex(tableName string) []Index
// 获取建表ddl
GetCreateTableDdl(tableName string) []map[string]interface{}
GetCreateTableDdl(tableName string) string
// 获取指定表的数据-分页查询
// @return columns: 列字段名result: 结果集error: 错误
GetTableRecord(tableName string, pageNum, pageSize int) ([]string, []map[string]interface{}, error)
GetTableRecord(tableName string, pageNum, pageSize int) ([]string, []map[string]any, error)
}
// ------------------------- 元数据sql操作 -------------------------
//
//go:embed metasql/*
var metasql embed.FS
// sql缓存 key: sql备注的key 如MYSQL_TABLE_MA value: sql内容
var sqlCache = make(map[string]string, 20)
// 获取本地文件的sql内容并进行解析获取对应key的sql内容
func GetLocalSql(file, key string) string {
sql := sqlCache[key]
if sql != "" {
return sql
}
bytes, err := metasql.ReadFile(file)
biz.ErrIsNilAppendErr(err, "获取sql meta文件内容失败: %s")
allSql := string(bytes)
sqls := strings.Split(allSql, "\n\n")
var resSql string
for _, sql := range sqls {
// 获取sql第一行的sql备注信息如--MYSQL_TABLE_MA 表信息元数据
info := strings.SplitN(sql, "\n", 2)
// 原始sql即去除第一行的key与备注信息
rowSql := info[1]
// 获取sql keyMYSQL_TABLE_MA
sqlKey := strings.Split(strings.Split(info[0], " ")[0], "--")[1]
if key == sqlKey {
resSql = rowSql
}
sqlCache[sqlKey] = rowSql
}
return resSql
}

View File

@@ -0,0 +1,69 @@
--MYSQL_TABLE_MA
SELECT
table_name tableName,
table_comment tableComment
from
information_schema.tables
WHERE
table_schema = (
SELECT
database ()
)
--MYSQL_TABLE_INFO
SELECT
table_name tableName,
table_comment tableComment,
table_rows tableRows,
data_length dataLength,
index_length indexLength,
create_time createTime
FROM
information_schema.tables
WHERE
table_schema = (
SELECT
database ()
)
--MYSQL_INDEX_INFO
SELECT
index_name indexName,
column_name columnName,
index_type indexType,
non_unique nonUnique,
SEQ_IN_INDEX seqInIndex,
INDEX_COMMENT indexComment
FROM
information_schema.STATISTICS
WHERE
table_schema = (
SELECT
database ()
)
AND table_name = '%s'
ORDER BY
index_name asc,
SEQ_IN_INDEX asc
--MYSQL_COLUMN_MA
SELECT
table_name tableName,
column_name columnName,
column_type columnType,
column_default columnDefault,
column_comment columnComment,
column_key columnKey,
extra extra,
is_nullable nullable
from
information_schema.columns
WHERE
table_schema = (
SELECT
database ()
)
AND table_name in (%s)
ORDER BY
tableName,
ordinal_position

View File

@@ -0,0 +1,169 @@
--PGSQL_TABLE_MA
SELECT
obj_description (c.oid) AS "tableComment",
c.relname AS "tableName"
FROM
pg_class c
JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE
n.nspname = (
select
current_schema ()
)
AND c.reltype > 0
--PGSQL_TABLE_INFO
SELECT
obj_description (c.oid) AS "tableComment",
c.relname AS "tableName",
pg_table_size ('"' || n.nspname || '"."' || c.relname || '"') as "dataLength",
pg_indexes_size ('"' || n.nspname || '"."' || c.relname || '"') as "indexLength",
c.reltuples as "tableRows"
FROM
pg_class c
JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE
n.nspname = (
select
current_schema ()
)
AND c.reltype > 0
--PGSQL_INDEX_INFO
SELECT
indexname AS "indexName",
indexdef AS "indexComment"
FROM
pg_indexes
WHERE
schemaname = (
select
current_schema ()
)
AND tablename = '%s'
--PGSQL_COLUMN_MA
SELECT
C.relname AS "tableName",
A.attname AS "columnName",
tc.is_nullable AS "nullable",
concat_ws ( '', t.typname, SUBSTRING ( format_type ( a.atttypid, a.atttypmod ) FROM '\(.*\)' ) ) AS "columnType",
(CASE WHEN ( SELECT COUNT(*) FROM pg_constraint WHERE conrelid = a.attrelid AND conkey[1]= attnum AND contype = 'p' ) > 0 THEN 'PRI' ELSE '' END ) AS "columnKey",
d.description AS "columnComment"
FROM
pg_attribute a LEFT JOIN pg_description d ON d.objoid = a.attrelid
AND d.objsubid = A.attnum
LEFT JOIN pg_class c ON A.attrelid = c.oid
LEFT JOIN pg_namespace pn ON c.relnamespace = pn.oid
LEFT JOIN pg_type t ON a.atttypid = t.oid
JOIN information_schema.columns tc ON tc.column_name = a.attname AND tc.table_name = C.relname AND tc.table_schema = pn.nspname
WHERE
A.attnum >= 0
AND pn.nspname = (select current_schema())
AND C.relname in (%s)
ORDER BY
C.relname DESC,
A.attnum ASC
--PGSQL_TABLE_DDL_FUNC ddl函数
CREATE OR REPLACE FUNCTION showcreatetable(namespace character varying, tablename character varying)
RETURNS character varying AS
$BODY$
declare
tableScript character varying default '';
begin
-- columns
tableScript:=tableScript || ' CREATE TABLE '|| tablename|| ' ( '|| chr(13)||chr(10) || array_to_string(
array(
select ' ' || concat_ws(' ',fieldName, fieldType, fieldLen, indexType, isNullStr, fieldComment ) as column_line
from (
select a.attname as fieldName,format_type(a.atttypid,a.atttypmod) as fieldType,(case when atttypmod-4>0 then
atttypmod-4 else 0 end) as fieldLen,
(case when (select count(*) from pg_constraint where conrelid = a.attrelid and conkey[1]=attnum and
contype='p')>0 then 'PRI'
when (select count(*) from pg_constraint where conrelid = a.attrelid and conkey[1]=attnum and contype='u')>0
then 'UNI'
when (select count(*) from pg_constraint where conrelid = a.attrelid and conkey[1]=attnum and contype='f')>0
then 'FRI'
else '' end) as indexType,
(case when a.attnotnull=true then 'not null' else 'null' end) as isNullStr,
' comment ' || col_description(a.attrelid,a.attnum) as fieldComment
from pg_attribute a where attstattarget=-1 and attrelid = (select c.oid from pg_class c,pg_namespace n where
c.relnamespace=n.oid and n.nspname =namespace and relname =tablename)
) as string_columns
),','||chr(13)||chr(10)) || ',';
-- 约束
tableScript:= tableScript || chr(13)||chr(10) || array_to_string(
array(
select concat(' CONSTRAINT ',conname ,c ,u,p,f) from (
select conname,
case when contype='c' then ' CHECK('|| ( select findattname(namespace,tablename,'c') ) ||')' end as c ,
case when contype='u' then ' UNIQUE('|| ( select findattname(namespace,tablename,'u') ) ||')' end as u ,
case when contype='p' then ' PRIMARY KEY ('|| ( select findattname(namespace,tablename,'p') ) ||')' end as p ,
case when contype='f' then ' FOREIGN KEY('|| ( select findattname(namespace,tablename,'u') ) ||') REFERENCES '||
(select p.relname from pg_class p where p.oid=c.confrelid ) || '('|| ( select
findattname(namespace,tablename,'u') ) ||')' end as f
from pg_constraint c
where contype in('u','c','f','p') and conrelid=(
select oid from pg_class where relname=tablename and relnamespace =(
select oid from pg_namespace where nspname = namespace
)
)
) as t
) ,',' || chr(13)||chr(10) ) || chr(13)||chr(10) ||' ); ';
-- indexs
-- CREATE UNIQUE INDEX pg_language_oid_index ON pg_language USING btree (oid); -- table pg_language
--
/** **/
--- 获取非约束索引 column
-- CREATE UNIQUE INDEX pg_language_oid_index ON pg_language USING btree (oid); -- table pg_language
tableScript:= tableScript || chr(13)||chr(10) || chr(13)||chr(10) || array_to_string(
array(
select 'CREATE INDEX ' || indexrelname || ' ON ' || tablename || ' USING btree '|| '(' || attname || ');' from (
SELECT
i.relname AS indexrelname , x.indkey,
( select array_to_string (
array(
select a.attname from pg_attribute a where attrelid=c.oid and a.attnum in ( select unnest(x.indkey) )
)
,',' ) )as attname
FROM pg_class c
JOIN pg_index x ON c.oid = x.indrelid
JOIN pg_class i ON i.oid = x.indexrelid
LEFT JOIN pg_namespace n ON n.oid = c.relnamespace
WHERE c.relname=tablename and i.relname not in
( select constraint_name from information_schema.key_column_usage where table_name=tablename )
)as t
) ,','|| chr(13)||chr(10));
-- COMMENT COMMENT ON COLUMN sys_activity.id IS '主键';
tableScript:= tableScript || chr(13)||chr(10) || chr(13)||chr(10) || array_to_string(
array(
SELECT 'COMMENT ON COLUMN' || tablename || '.' || a.attname ||' IS '|| ''''|| d.description ||''''
FROM pg_class c
JOIN pg_description d ON c.oid=d.objoid
JOIN pg_attribute a ON c.oid = a.attrelid
WHERE c.relname=tablename
AND a.attnum = d.objsubid),','|| chr(13)||chr(10)) ;
return tableScript;
end
$BODY$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION findattname(namespace character varying, tablename character varying, ctype character
varying)
RETURNS character varying as $BODY$
declare
tt oid ;
aname character varying default '';
begin
tt := oid from pg_class where relname= tablename and relnamespace =(select oid from pg_namespace where
nspname=namespace) ;
aname:= array_to_string(
array(
select a.attname from pg_attribute a
where a.attrelid=tt and a.attnum in (
select unnest(conkey) from pg_constraint c where contype=ctype
and conrelid=tt and array_to_string(conkey,',') is not null
)
),',');
return aname;
end
$BODY$ LANGUAGE plpgsql

View File

@@ -7,6 +7,7 @@ import (
"mayfly-go/internal/db/domain/entity"
machineapp "mayfly-go/internal/machine/application"
"mayfly-go/pkg/biz"
"mayfly-go/pkg/utils"
"net"
"github.com/go-sql-driver/mysql"
@@ -30,25 +31,11 @@ func getMysqlDB(d *entity.Db, db string) (*sql.DB, error) {
// ---------------------------------- mysql元数据 -----------------------------------
const (
// mysql 表信息元数据
MYSQL_TABLE_MA = `SELECT table_name tableName, table_comment tableComment from information_schema.tables WHERE table_schema = (SELECT database())`
// mysql 表信息
MYSQL_TABLE_INFO = `SELECT table_name tableName, table_comment tableComment, table_rows tableRows,
data_length dataLength, index_length indexLength, create_time createTime
FROM information_schema.tables
WHERE table_schema = (SELECT database())`
// mysql 索引信息
MYSQL_INDEX_INFO = `SELECT index_name indexName, column_name columnName, index_type indexType, non_unique nonUnique,
SEQ_IN_INDEX seqInIndex, INDEX_COMMENT indexComment
FROM information_schema.STATISTICS
WHERE table_schema = (SELECT database()) AND table_name = '%s' ORDER BY index_name asc , SEQ_IN_INDEX asc`
// mysql 列信息元数据
MYSQL_COLUMN_MA = `SELECT table_name tableName, column_name columnName, column_type columnType, column_default columnDefault,
column_comment columnComment, column_key columnKey, extra, is_nullable nullable from information_schema.columns
WHERE table_schema = (SELECT database()) AND table_name in (%s) ORDER BY tableName, ordinal_position`
MYSQL_META_FILE = "metasql/mysql_meta.sql"
MYSQL_TABLE_MA_KEY = "MYSQL_TABLE_MA"
MYSQL_TABLE_INFO_KEY = "MYSQL_TABLE_INFO"
MYSQL_INDEX_INFO_KEY = "MYSQL_INDEX_INFO"
MYSQL_COLUMN_MA_KEY = "MYSQL_COLUMN_MA"
)
type MysqlMetadata struct {
@@ -56,14 +43,22 @@ type MysqlMetadata struct {
}
// 获取表基础元信息, 如表名等
func (mm *MysqlMetadata) GetTables() []map[string]interface{} {
res, err := mm.di.innerSelect(MYSQL_TABLE_MA)
func (mm *MysqlMetadata) GetTables() []Table {
_, res, err := mm.di.SelectData(GetLocalSql(MYSQL_META_FILE, MYSQL_TABLE_MA_KEY))
biz.ErrIsNilAppendErr(err, "获取表基本信息失败: %s")
return res
tables := make([]Table, 0)
for _, re := range res {
tables = append(tables, Table{
TableName: re["tableName"].(string),
TableComment: utils.Any2String(re["tableComment"]),
})
}
return tables
}
// 获取列元信息, 如列名等
func (mm *MysqlMetadata) GetColumns(tableNames ...string) []map[string]interface{} {
func (mm *MysqlMetadata) GetColumns(tableNames ...string) []Column {
tableName := ""
for i := 0; i < len(tableNames); i++ {
if i != 0 {
@@ -71,9 +66,22 @@ func (mm *MysqlMetadata) GetColumns(tableNames ...string) []map[string]interface
}
tableName = tableName + "'" + tableNames[i] + "'"
}
result, err := mm.di.innerSelect(fmt.Sprintf(MYSQL_COLUMN_MA, tableName))
_, res, err := mm.di.SelectData(fmt.Sprintf(GetLocalSql(MYSQL_META_FILE, MYSQL_COLUMN_MA_KEY), tableName))
biz.ErrIsNilAppendErr(err, "获取数据库列信息失败: %s")
return result
columns := make([]Column, 0)
for _, re := range res {
columns = append(columns, Column{
TableName: re["tableName"].(string),
ColumnName: re["columnName"].(string),
ColumnType: utils.Any2String(re["columnType"]),
ColumnComment: utils.Any2String(re["columnComment"]),
Nullable: utils.Any2String(re["nullable"]),
ColumnKey: utils.Any2String(re["columnKey"]),
ColumnDefault: utils.Any2String(re["columnDefault"]),
})
}
return columns
}
// 获取表主键字段名,不存在主键标识则默认第一个字段
@@ -81,36 +89,59 @@ func (mm *MysqlMetadata) GetPrimaryKey(tablename string) string {
columns := mm.GetColumns(tablename)
biz.IsTrue(len(columns) > 0, "[%s] 表不存在", tablename)
for _, v := range columns {
if v["columnKey"].(string) == "PRI" {
return v["columnName"].(string)
if v.ColumnKey == "PRI" {
return v.ColumnName
}
}
return columns[0]["columnName"].(string)
return columns[0].ColumnName
}
// 获取表信息比GetTableMetedatas获取更详细的表信息
func (mm *MysqlMetadata) GetTableInfos() []map[string]interface{} {
res, err := mm.di.innerSelect(MYSQL_TABLE_INFO)
func (mm *MysqlMetadata) GetTableInfos() []Table {
_, res, err := mm.di.SelectData(GetLocalSql(MYSQL_META_FILE, MYSQL_TABLE_INFO_KEY))
biz.ErrIsNilAppendErr(err, "获取表信息失败: %s")
return res
tables := make([]Table, 0)
for _, re := range res {
tables = append(tables, Table{
TableName: re["tableName"].(string),
TableComment: utils.Any2String(re["tableComment"]),
CreateTime: utils.Any2String(re["createTime"]),
TableRows: utils.Any2Int(re["tableRows"]),
DataLength: utils.Any2Int64(re["dataLength"]),
IndexLength: utils.Any2Int64(re["indexLength"]),
})
}
return tables
}
// 获取表索引信息
func (mm *MysqlMetadata) GetTableIndex(tableName string) []map[string]interface{} {
res, err := mm.di.innerSelect(fmt.Sprintf(MYSQL_INDEX_INFO, tableName))
func (mm *MysqlMetadata) GetTableIndex(tableName string) []Index {
_, res, err := mm.di.SelectData(fmt.Sprintf(GetLocalSql(MYSQL_META_FILE, MYSQL_INDEX_INFO_KEY), tableName))
biz.ErrIsNilAppendErr(err, "获取表索引信息失败: %s")
indexs := make([]Index, 0)
for _, re := range res {
indexs = append(indexs, Index{
IndexName: re["indexName"].(string),
ColumnName: utils.Any2String(re["columnName"]),
IndexType: utils.Any2String(re["indexType"]),
IndexComment: utils.Any2String(re["indexComment"]),
NonUnique: utils.Any2Int(re["nonUnique"]),
SeqInIndex: utils.Any2Int(re["seqInIndex"]),
})
}
// 把查询结果以索引名分组,索引字段以逗号连接
result := make([]map[string]interface{}, 0)
result := make([]Index, 0)
key := ""
for _, v := range res {
for _, v := range indexs {
// 当前的索引名
in := v["indexName"].(string)
in := v.IndexName
if key == in {
// 索引字段已根据名称和顺序排序,故取最后一个即可
i := len(result) - 1
// 同索引字段以逗号连接
result[i]["columnName"] = result[i]["columnName"].(string) + "," + v["columnName"].(string)
result[i].ColumnName = result[i].ColumnName + "," + v.ColumnName
} else {
key = in
result = append(result, v)
@@ -120,11 +151,11 @@ func (mm *MysqlMetadata) GetTableIndex(tableName string) []map[string]interface{
}
// 获取建表ddl
func (mm *MysqlMetadata) GetCreateTableDdl(tableName string) []map[string]interface{} {
res, _ := mm.di.innerSelect(fmt.Sprintf("show create table %s ", tableName))
return res
func (mm *MysqlMetadata) GetCreateTableDdl(tableName string) string {
_, res, _ := mm.di.SelectData(fmt.Sprintf("show create table %s ", tableName))
return res[0]["Create Table"].(string)
}
func (mm *MysqlMetadata) GetTableRecord(tableName string, pageNum, pageSize int) ([]string, []map[string]interface{}, error) {
func (mm *MysqlMetadata) GetTableRecord(tableName string, pageNum, pageSize int) ([]string, []map[string]any, error) {
return mm.di.SelectData(fmt.Sprintf("SELECT * FROM %s LIMIT %d, %d", tableName, (pageNum-1)*pageSize, pageSize))
}

View File

@@ -57,38 +57,12 @@ func (pd *PqSqlDialer) DialTimeout(network, address string, timeout time.Duratio
// ---------------------------------- pgsql元数据 -----------------------------------
const (
// postgres 表信息元数据
PGSQL_TABLE_MA = `SELECT obj_description(c.oid) AS "tableComment", c.relname AS "tableName" FROM pg_class c
JOIN pg_namespace n ON c.relnamespace = n.oid WHERE n.nspname = (select current_schema()) AND c.reltype > 0`
PGSQL_TABLE_INFO = `SELECT obj_description(c.oid) AS "tableComment", c.relname AS "tableName" FROM pg_class c
JOIN pg_namespace n ON c.relnamespace = n.oid WHERE n.nspname = (select current_schema()) AND c.reltype > 0`
PGSQL_INDEX_INFO = `SELECT indexname AS "indexName", indexdef AS "indexComment"
FROM pg_indexes WHERE schemaname = (select current_schema()) AND tablename = '%s'`
PGSQL_COLUMN_MA = `SELECT
C.relname AS "tableName",
A.attname AS "columnName",
tc.is_nullable AS "nullable",
concat_ws ( '', t.typname, SUBSTRING ( format_type ( a.atttypid, a.atttypmod ) FROM '\(.*\)' ) ) AS "columnType",
(CASE WHEN ( SELECT COUNT(*) FROM pg_constraint WHERE conrelid = a.attrelid AND conkey[1]= attnum AND contype = 'p' ) > 0 THEN 'PRI' ELSE '' END ) AS "columnKey",
d.description AS "columnComment"
FROM
pg_attribute a LEFT JOIN pg_description d ON d.objoid = a.attrelid
AND d.objsubid = A.attnum
LEFT JOIN pg_class c ON A.attrelid = c.oid
LEFT JOIN pg_namespace pn ON c.relnamespace = pn.oid
LEFT JOIN pg_type t ON a.atttypid = t.oid
JOIN information_schema.columns tc ON tc.column_name = a.attname AND tc.table_name = C.relname AND tc.table_schema = pn.nspname
WHERE
A.attnum >= 0
AND pn.nspname = (select current_schema())
AND C.relname in (%s)
ORDER BY
C.relname DESC,
A.attnum ASC
`
PGSQL_META_FILE = "metasql/pgsql_meta.sql"
PGSQL_TABLE_MA_KEY = "PGSQL_TABLE_MA"
PGSQL_TABLE_INFO_KEY = "PGSQL_TABLE_INFO"
PGSQL_INDEX_INFO_KEY = "PGSQL_INDEX_INFO"
PGSQL_COLUMN_MA_KEY = "PGSQL_COLUMN_MA"
PGSQL_TABLE_DDL_KEY = "PGSQL_TABLE_DDL_FUNC"
)
type PgsqlMetadata struct {
@@ -96,14 +70,22 @@ type PgsqlMetadata struct {
}
// 获取表基础元信息, 如表名等
func (pm *PgsqlMetadata) GetTables() []map[string]interface{} {
res, err := pm.di.innerSelect(PGSQL_TABLE_MA)
func (pm *PgsqlMetadata) GetTables() []Table {
_, res, err := pm.di.SelectData(GetLocalSql(PGSQL_META_FILE, PGSQL_TABLE_MA_KEY))
biz.ErrIsNilAppendErr(err, "获取表基本信息失败: %s")
return res
tables := make([]Table, 0)
for _, re := range res {
tables = append(tables, Table{
TableName: re["tableName"].(string),
TableComment: utils.Any2String(re["tableComment"]),
})
}
return tables
}
// 获取列元信息, 如列名等
func (pm *PgsqlMetadata) GetColumns(tableNames ...string) []map[string]interface{} {
func (pm *PgsqlMetadata) GetColumns(tableNames ...string) []Column {
tableName := ""
for i := 0; i < len(tableNames); i++ {
if i != 0 {
@@ -111,43 +93,88 @@ func (pm *PgsqlMetadata) GetColumns(tableNames ...string) []map[string]interface
}
tableName = tableName + "'" + tableNames[i] + "'"
}
result, err := pm.di.innerSelect(fmt.Sprintf(PGSQL_COLUMN_MA, tableName))
_, res, err := pm.di.SelectData(fmt.Sprintf(GetLocalSql(PGSQL_META_FILE, PGSQL_COLUMN_MA_KEY), tableName))
biz.ErrIsNilAppendErr(err, "获取数据库列信息失败: %s")
return result
columns := make([]Column, 0)
for _, re := range res {
columns = append(columns, Column{
TableName: re["tableName"].(string),
ColumnName: re["columnName"].(string),
ColumnType: utils.Any2String(re["columnType"]),
ColumnComment: utils.Any2String(re["columnComment"]),
Nullable: utils.Any2String(re["nullable"]),
ColumnKey: utils.Any2String(re["columnKey"]),
ColumnDefault: utils.Any2String(re["columnDefault"]),
})
}
return columns
}
func (pm *PgsqlMetadata) GetPrimaryKey(tablename string) string {
columns := pm.GetColumns(tablename)
biz.IsTrue(len(columns) > 0, "[%s] 表不存在", tablename)
for _, v := range columns {
if v["columnKey"].(string) == "PRI" {
return v["columnName"].(string)
if v.ColumnKey == "PRI" {
return v.ColumnName
}
}
return columns[0]["columnName"].(string)
return columns[0].ColumnName
}
// 获取表信息比GetTables获取更详细的表信息
func (pm *PgsqlMetadata) GetTableInfos() []map[string]interface{} {
res, err := pm.di.innerSelect(PGSQL_TABLE_INFO)
func (pm *PgsqlMetadata) GetTableInfos() []Table {
_, res, err := pm.di.SelectData(GetLocalSql(PGSQL_META_FILE, PGSQL_TABLE_INFO_KEY))
biz.ErrIsNilAppendErr(err, "获取表信息失败: %s")
return res
tables := make([]Table, 0)
for _, re := range res {
tables = append(tables, Table{
TableName: re["tableName"].(string),
TableComment: utils.Any2String(re["tableComment"]),
CreateTime: utils.Any2String(re["createTime"]),
TableRows: utils.Any2Int(re["tableRows"]),
DataLength: utils.Any2Int64(re["dataLength"]),
IndexLength: utils.Any2Int64(re["indexLength"]),
})
}
return tables
}
// 获取表索引信息
func (pm *PgsqlMetadata) GetTableIndex(tableName string) []map[string]interface{} {
res, err := pm.di.innerSelect(fmt.Sprintf(PGSQL_INDEX_INFO, tableName))
func (pm *PgsqlMetadata) GetTableIndex(tableName string) []Index {
_, res, err := pm.di.SelectData(fmt.Sprintf(GetLocalSql(PGSQL_META_FILE, PGSQL_INDEX_INFO_KEY), tableName))
biz.ErrIsNilAppendErr(err, "获取表索引信息失败: %s")
return res
indexs := make([]Index, 0)
for _, re := range res {
indexs = append(indexs, Index{
IndexName: re["indexName"].(string),
ColumnName: utils.Any2String(re["columnName"]),
IndexType: utils.Any2String(re["indexType"]),
IndexComment: utils.Any2String(re["indexComment"]),
NonUnique: utils.Any2Int(re["nonUnique"]),
SeqInIndex: utils.Any2Int(re["seqInIndex"]),
})
}
return indexs
}
// 获取建表ddl
func (pm *PgsqlMetadata) GetCreateTableDdl(tableName string) []map[string]interface{} {
biz.IsTrue(tableName == "", "暂不支持获取pgsql建表DDL")
return nil
func (pm *PgsqlMetadata) GetCreateTableDdl(tableName string) string {
_, err := pm.di.Exec(GetLocalSql(PGSQL_META_FILE, PGSQL_TABLE_DDL_KEY))
biz.ErrIsNilAppendErr(err, "创建ddl函数失败: %s")
_, schemaRes, _ := pm.di.SelectData("select current_schema() as schema")
schemaName := schemaRes[0]["schema"].(string)
ddlSql := fmt.Sprintf("select showcreatetable('%s','%s') as sql", schemaName, tableName)
_, res, err := pm.di.SelectData(ddlSql)
biz.ErrIsNilAppendErr(err, "获取表ddl失败: %s")
return res[0]["sql"].(string)
}
func (pm *PgsqlMetadata) GetTableRecord(tableName string, pageNum, pageSize int) ([]string, []map[string]interface{}, error) {
func (pm *PgsqlMetadata) GetTableRecord(tableName string, pageNum, pageSize int) ([]string, []map[string]any, error) {
return pm.di.SelectData(fmt.Sprintf("SELECT * FROM %s OFFSET %d LIMIT %d", tableName, (pageNum-1)*pageSize, pageSize))
}

View File

@@ -11,7 +11,7 @@ import (
)
// 将结果scan至结构体copy至 sqlx库: https://github.com/jmoiron/sqlx
func scanAll(rows *sql.Rows, dest interface{}, structOnly bool) error {
func scanAll(rows *sql.Rows, dest any, structOnly bool) error {
var v, vp reflect.Value
value := reflect.ValueOf(dest)
@@ -50,7 +50,7 @@ func scanAll(rows *sql.Rows, dest interface{}, structOnly bool) error {
}
if !scannable {
var values []interface{}
var values []any
var m *Mapper = mapper()
fields := m.TraversalsByName(base, columns)
@@ -58,7 +58,7 @@ func scanAll(rows *sql.Rows, dest interface{}, structOnly bool) error {
if f, err := missingFields(fields); err != nil {
return fmt.Errorf("missing destination name %s in %T", columns[f], dest)
}
values = make([]interface{}, len(columns))
values = make([]any, len(columns))
for rows.Next() {
// create a new struct type (which returns PtrTo) and indirect it
@@ -178,7 +178,7 @@ func missingFields(transversals [][]int) (field int, err error) {
// when iterating over many rows. Empty traversals will get an interface pointer.
// Because of the necessity of requesting ptrs or values, it's considered a bit too
// specialized for inclusion in reflectx itself.
func fieldsByTraversal(v reflect.Value, traversals [][]int, values []interface{}, ptrs bool) error {
func fieldsByTraversal(v reflect.Value, traversals [][]int, values []any, ptrs bool) error {
v = reflect.Indirect(v)
if v.Kind() != reflect.Struct {
return errors.New("argument not a struct")
@@ -186,7 +186,7 @@ func fieldsByTraversal(v reflect.Value, traversals [][]int, values []interface{}
for i, traversal := range traversals {
if len(traversal) == 0 {
values[i] = new(interface{})
values[i] = new(any)
continue
}
f := FieldByIndexes(v, traversal)

View File

@@ -7,7 +7,7 @@ import (
type Db interface {
// 分页获取机器信息列表
GetDbList(condition *entity.DbQuery, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetDbList(condition *entity.DbQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
Count(condition *entity.DbQuery) int64

View File

@@ -11,5 +11,5 @@ type DbSqlExec interface {
DeleteBy(condition *entity.DbSqlExec)
// 分页获取
GetPageList(condition *entity.DbSqlExec, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetPageList(condition *entity.DbSqlExec, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
}

View File

@@ -17,10 +17,10 @@ func newDbRepo() repository.Db {
}
// 分页获取数据库信息列表
func (d *dbRepoImpl) GetDbList(condition *entity.DbQuery, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
func (d *dbRepoImpl) GetDbList(condition *entity.DbQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult {
sql := "SELECT d.* FROM t_db d WHERE 1 = 1 "
values := make([]interface{}, 0)
values := make([]any, 0)
if condition.Host != "" {
sql = sql + " AND d.host LIKE ?"
values = append(values, "%"+condition.Host+"%")
@@ -41,7 +41,7 @@ func (d *dbRepoImpl) GetDbList(condition *entity.DbQuery, pageParam *model.PageP
}
func (d *dbRepoImpl) Count(condition *entity.DbQuery) int64 {
where := make(map[string]interface{})
where := make(map[string]any)
if len(condition.TagIds) > 0 {
where["tag_id"] = condition.TagIds
}

View File

@@ -22,6 +22,6 @@ func (d *dbSqlExecRepoImpl) DeleteBy(condition *entity.DbSqlExec) {
}
// 分页获取
func (d *dbSqlExecRepoImpl) GetPageList(condition *entity.DbSqlExec, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
func (d *dbSqlExecRepoImpl) GetPageList(condition *entity.DbSqlExec, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult {
return model.GetPage(pageParam, condition, condition, toEntity, orderBy...)
}

View File

@@ -19,37 +19,37 @@ type MachineForm struct {
}
type MachineRunForm struct {
MachineId int64 `binding:"required"`
Cmd string `binding:"required"`
MachineId int64 `json:"machineId" binding:"required"`
Cmd string `json:"cmd" binding:"required"`
}
type MachineFileForm struct {
Id uint64
Name string `binding:"required"`
MachineId uint64 `binding:"required"`
Type int `binding:"required"`
Path string `binding:"required"`
Id uint64 `json:"id"`
Name string `json:"name" binding:"required"`
MachineId uint64 `json:"machineId" binding:"required"`
Type int `json:"type" binding:"required"`
Path string `json:"path" binding:"required"`
}
type MachineScriptForm struct {
Id uint64
Name string `binding:"required"`
MachineId uint64 `binding:"required"`
Type int `binding:"required"`
Description string `binding:"required"`
Params string
Script string `binding:"required"`
Id uint64 `json:"id"`
Name string `json:"name" binding:"required"`
MachineId uint64 `json:"machineId" binding:"required"`
Type int `json:"type" binding:"required"`
Description string `json:"description" binding:"required"`
Params string `json:"params"`
Script string `json:"script" binding:"required"`
}
type MachineCreateFileForm struct {
Path string `binding:"required"`
Type string `binding:"required"`
Path string `json:"path" binding:"required"`
Type string `json:"type" binding:"required"`
}
type MachineFileUpdateForm struct {
Content string `binding:"required"`
Id uint64 `binding:"required"`
Path string `binding:"required"`
Content string `json:"content" binding:"required"`
Id uint64 `json:"id" binding:"required"`
Path string `json:"path" binding:"required"`
}
// 授权凭证

View File

@@ -8,7 +8,7 @@ import (
)
type AuthCert interface {
GetPageList(condition *entity.AuthCert, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetPageList(condition *entity.AuthCert, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
Save(ac *entity.AuthCert)
@@ -29,7 +29,7 @@ type authCertAppImpl struct {
authCertRepo repository.AuthCert
}
func (a *authCertAppImpl) GetPageList(condition *entity.AuthCert, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
func (a *authCertAppImpl) GetPageList(condition *entity.AuthCert, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult {
return a.authCertRepo.GetPageList(condition, pageParam, toEntity)
}

View File

@@ -30,7 +30,7 @@ type Machine interface {
GetById(id uint64, cols ...string) *entity.Machine
// 分页获取机器信息列表
GetMachineList(condition *entity.MachineQuery, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetMachineList(condition *entity.MachineQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
// 获取机器连接
GetCli(id uint64) *machine.Cli
@@ -52,7 +52,7 @@ type machineAppImpl struct {
}
// 分页获取机器信息列表
func (m *machineAppImpl) GetMachineList(condition *entity.MachineQuery, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
func (m *machineAppImpl) GetMachineList(condition *entity.MachineQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult {
return m.machineRepo.GetMachineList(condition, pageParam, toEntity, orderBy...)
}

View File

@@ -17,7 +17,7 @@ import (
type MachineFile interface {
// 分页获取机器文件信息列表
GetPageList(condition *entity.MachineFile, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetPageList(condition *entity.MachineFile, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
// 根据条件获取
GetMachineFile(condition *entity.MachineFile, cols ...string) error
@@ -67,7 +67,7 @@ type machineFileAppImpl struct {
}
// 分页获取机器脚本信息列表
func (m *machineFileAppImpl) GetPageList(condition *entity.MachineFile, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
func (m *machineFileAppImpl) GetPageList(condition *entity.MachineFile, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult {
return m.machineFileRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
}

View File

@@ -9,7 +9,7 @@ import (
type MachineScript interface {
// 分页获取机器脚本信息列表
GetPageList(condition *entity.MachineScript, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetPageList(condition *entity.MachineScript, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
// 根据条件获取
GetMachineScript(condition *entity.MachineScript, cols ...string) error
@@ -40,7 +40,7 @@ const Common_Script_Machine_Id = 9999999
// machineScriptRepo: persistence.MachineScriptDao}
// 分页获取机器脚本信息列表
func (m *machineScriptAppImpl) GetPageList(condition *entity.MachineScript, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
func (m *machineScriptAppImpl) GetPageList(condition *entity.MachineScript, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult {
return m.machineScriptRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
}

View File

@@ -6,7 +6,7 @@ import (
)
type AuthCert interface {
GetPageList(condition *entity.AuthCert, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetPageList(condition *entity.AuthCert, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
Insert(ac *entity.AuthCert)

View File

@@ -7,7 +7,7 @@ import (
type Machine interface {
// 分页获取机器信息列表
GetMachineList(condition *entity.MachineQuery, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetMachineList(condition *entity.MachineQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
Count(condition *entity.MachineQuery) int64

View File

@@ -7,7 +7,7 @@ import (
type MachineFile interface {
// 分页获取机器脚本信息列表
GetPageList(condition *entity.MachineFile, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetPageList(condition *entity.MachineFile, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
// 根据条件获取
GetMachineFile(condition *entity.MachineFile, cols ...string) error

View File

@@ -7,7 +7,7 @@ import (
type MachineScript interface {
// 分页获取机器脚本信息列表
GetPageList(condition *entity.MachineScript, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetPageList(condition *entity.MachineScript, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
// 根据条件获取
GetMachineScript(condition *entity.MachineScript, cols ...string) error

View File

@@ -6,7 +6,7 @@ import (
)
type MachineTaskConfig interface {
GetPageList(condition *entity.MachineTaskConfig, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetPageList(condition *entity.MachineTaskConfig, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
// 根据条件获取
GetBy(condition *entity.MachineTaskConfig, cols ...string) error

View File

@@ -140,7 +140,7 @@ func (c *Cli) GetMachine() *Info {
// 机器客户端连接缓存,指定时间内没有访问则会被关闭
var cliCache = cache.NewTimedCache(constant.MachineConnExpireTime, 5*time.Second).
WithUpdateAccessTime(true).
OnEvicted(func(_, value interface{}) {
OnEvicted(func(_, value any) {
value.(*Cli).Close()
})
@@ -172,7 +172,7 @@ func DeleteCli(id uint64) {
// 从缓存中获取客户端信息,不存在则回调获取机器信息函数,并新建
func GetCli(machineId uint64, getMachine func(uint64) *Info) (*Cli, error) {
cli, err := cliCache.ComputeIfAbsent(machineId, func(_ interface{}) (interface{}, error) {
cli, err := cliCache.ComputeIfAbsent(machineId, func(_ any) (any, error) {
me := getMachine(machineId)
err := IfUseSshTunnelChangeIpPort(me, getMachine)
if err != nil {

View File

@@ -68,7 +68,7 @@ func TestTemplateRev(t *testing.T) {
//next := temp[ei:]
//key := temp[index+1 : ei-1]
//value := SubString(str, index, UnicodeIndex(str, next))
res := make(map[string]interface{})
res := make(map[string]any)
utils.ReverStrTemplate(temp, str, res)
fmt.Println(res)
}

View File

@@ -57,7 +57,7 @@ func (rec *Recorder) WriteHeader(height, width int) {
}
func (rec *Recorder) WriteData(rectype RecType, data string) {
recData := make([]interface{}, 3)
recData := make([]any, 3)
recData[0] = float64(time.Since(rec.StartTime).Microseconds()) / float64(1000000)
recData[1] = rectype
recData[2] = data

View File

@@ -13,7 +13,7 @@ func newAuthCertRepo() repository.AuthCert {
return new(authCertRepoImpl)
}
func (m *authCertRepoImpl) GetPageList(condition *entity.AuthCert, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
func (m *authCertRepoImpl) GetPageList(condition *entity.AuthCert, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult {
return model.GetPage(pageParam, condition, condition, toEntity)
}

View File

@@ -15,10 +15,10 @@ func newMachineRepo() repository.Machine {
}
// 分页获取机器信息列表
func (m *machineRepoImpl) GetMachineList(condition *entity.MachineQuery, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
func (m *machineRepoImpl) GetMachineList(condition *entity.MachineQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult {
sql := "SELECT m.* FROM t_machine m WHERE 1 = 1 "
values := make([]interface{}, 0)
values := make([]any, 0)
if condition.Ip != "" {
sql = sql + " AND m.ip LIKE ?"
values = append(values, "%"+condition.Ip+"%")
@@ -40,7 +40,7 @@ func (m *machineRepoImpl) GetMachineList(condition *entity.MachineQuery, pagePar
}
func (m *machineRepoImpl) Count(condition *entity.MachineQuery) int64 {
where := make(map[string]interface{})
where := make(map[string]any)
if len(condition.TagIds) > 0 {
where["tag_id"] = condition.TagIds
}

View File

@@ -14,7 +14,7 @@ func newMachineFileRepo() repository.MachineFile {
}
// 分页获取机器文件信息列表
func (m *machineFileRepoImpl) GetPageList(condition *entity.MachineFile, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
func (m *machineFileRepoImpl) GetPageList(condition *entity.MachineFile, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult {
return model.GetPage(pageParam, condition, condition, toEntity, orderBy...)
}

View File

@@ -14,7 +14,7 @@ func newMachineScriptRepo() repository.MachineScript {
}
// 分页获取机器信息列表
func (m *machineScriptRepoImpl) GetPageList(condition *entity.MachineScript, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
func (m *machineScriptRepoImpl) GetPageList(condition *entity.MachineScript, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult {
return model.GetPage(pageParam, condition, condition, toEntity, orderBy...)
}

View File

@@ -1,7 +1,7 @@
package form
type Mongo struct {
Id uint64
Id uint64 `json:"id"`
Uri string `binding:"required" json:"uri"`
SshTunnelMachineId int `json:"sshTunnelMachineId"` // ssh隧道机器id
Name string `binding:"required" json:"name"`
@@ -10,30 +10,30 @@ type Mongo struct {
}
type MongoCommand struct {
Database string `binding:"required" json:"database"`
Collection string `binding:"required" json:"collection"`
Filter map[string]interface{} `json:"filter"`
Database string `binding:"required" json:"database"`
Collection string `binding:"required" json:"collection"`
Filter map[string]any `json:"filter"`
}
type MongoRunCommand struct {
Database string `binding:"required" json:"database"`
Command map[string]interface{} `json:"command"`
Database string `binding:"required" json:"database"`
Command map[string]any `json:"command"`
}
type MongoFindCommand struct {
MongoCommand
Sort map[string]interface{} `json:"sort"`
Skip int64
Limit int64
Sort map[string]any `json:"sort"`
Skip int64 `json:"skip"`
Limit int64 `json:"limit"`
}
type MongoUpdateByIdCommand struct {
MongoCommand
DocId interface{} `binding:"required" json:"docId"`
Update map[string]interface{} `json:"update"`
DocId any `binding:"required" json:"docId"`
Update map[string]any `json:"update"`
}
type MongoInsertCommand struct {
MongoCommand
Doc map[string]interface{} `json:"doc"`
Doc map[string]any `json:"doc"`
}

View File

@@ -23,7 +23,7 @@ import (
type Mongo interface {
// 分页获取机器脚本信息列表
GetPageList(condition *entity.MongoQuery, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetPageList(condition *entity.MongoQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
Count(condition *entity.MongoQuery) int64
@@ -54,7 +54,7 @@ type mongoAppImpl struct {
}
// 分页获取数据库信息列表
func (d *mongoAppImpl) GetPageList(condition *entity.MongoQuery, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
func (d *mongoAppImpl) GetPageList(condition *entity.MongoQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult {
return d.mongoRepo.GetList(condition, pageParam, toEntity, orderBy...)
}
@@ -102,7 +102,7 @@ func (d *mongoAppImpl) GetMongoCli(id uint64) *mongo.Client {
// mongo客户端连接缓存指定时间内没有访问则会被关闭
var mongoCliCache = cache.NewTimedCache(constant.MongoConnExpireTime, 5*time.Second).
WithUpdateAccessTime(true).
OnEvicted(func(key interface{}, value interface{}) {
OnEvicted(func(key any, value any) {
global.Log.Info("删除mongo连接缓存: id = ", key)
value.(*MongoInstance).Close()
})
@@ -122,7 +122,7 @@ func init() {
// 获取mongo的连接实例
func GetMongoInstance(mongoId uint64, getMongoEntity func(uint64) *entity.Mongo) (*MongoInstance, error) {
mi, err := mongoCliCache.ComputeIfAbsent(mongoId, func(_ interface{}) (interface{}, error) {
mi, err := mongoCliCache.ComputeIfAbsent(mongoId, func(_ any) (any, error) {
c, err := connect(getMongoEntity(mongoId))
if err != nil {
return nil, err

View File

@@ -7,7 +7,7 @@ import (
type Mongo interface {
// 分页获取列表
GetList(condition *entity.MongoQuery, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetList(condition *entity.MongoQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
Count(condition *entity.MongoQuery) int64

View File

@@ -17,14 +17,14 @@ func newMongoRepo() repository.Mongo {
}
// 分页获取数据库信息列表
func (d *mongoRepoImpl) GetList(condition *entity.MongoQuery, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
func (d *mongoRepoImpl) GetList(condition *entity.MongoQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult {
sql := "SELECT d.* FROM t_mongo d WHERE 1=1 "
if len(condition.TagIds) > 0 {
sql = sql + " AND d.tag_id IN " + fmt.Sprintf("(%s)", strings.Join(utils.NumberArr2StrArr(condition.TagIds), ","))
}
values := make([]interface{}, 0)
values := make([]any, 0)
if condition.TagPathLike != "" {
values = append(values, condition.TagPathLike+"%")
sql = sql + " AND d.tag_path LIKE ?"
@@ -34,7 +34,7 @@ func (d *mongoRepoImpl) GetList(condition *entity.MongoQuery, pageParam *model.P
}
func (d *mongoRepoImpl) Count(condition *entity.MongoQuery) int64 {
where := make(map[string]interface{})
where := make(map[string]any)
if len(condition.TagIds) > 0 {
where["tag_id"] = condition.TagIds
}

View File

@@ -1,9 +1,9 @@
package form
type Redis struct {
Id uint64
Id uint64 `json:"id"`
Name string `json:"name"`
Host string `binding:"required" json:"host"`
Host string `json:"host" binding:"required"`
Password string `json:"password"`
Mode string `json:"mode"`
Db string `json:"db"`
@@ -25,34 +25,34 @@ type Expire struct {
type KeyInfo struct {
Key string `binding:"required" json:"key"`
Timed int64
Timed int64 `json:"timed"`
}
type StringValue struct {
KeyInfo
Value interface{} `binding:"required" json:"value"`
Value any `binding:"required" json:"value"`
}
type HashValue struct {
KeyInfo
Value []map[string]interface{} `binding:"required" json:"value"`
Value []map[string]any `binding:"required" json:"value"`
}
type SetValue struct {
KeyInfo
Value []interface{} `binding:"required" json:"value"`
Value []any `binding:"required" json:"value"`
}
type ListValue struct {
KeyInfo
Value []interface{} `binding:"required" json:"value"`
Value []any `binding:"required" json:"value"`
}
// list lset命令参数入参
type ListSetValue struct {
Key string `binding:"required" json:"key"`
Index int64
Value interface{} `binding:"required" json:"value"`
Index int64 `json:"index"`
Value any `binding:"required" json:"value"`
}
type RedisScanForm struct {

View File

@@ -23,7 +23,7 @@ func (r *Redis) Hscan(rc *req.Ctx) {
keySize, err := cmdable.HLen(contextTodo, key).Result()
biz.ErrIsNilAppendErr(err, "hlen err: %s")
rc.ResData = map[string]interface{}{
rc.ResData = map[string]any{
"keys": keys,
"cursor": nextCursor,
"keySize": keySize,
@@ -52,6 +52,7 @@ func (r *Redis) Hset(rc *req.Ctx) {
g := rc.GinCtx
hashValue := new(form.HashValue)
ginx.BindJsonAndValid(g, hashValue)
rc.ReqParam = hashValue
hv := hashValue.Value[0]
res, err := r.getRedisIns(rc).GetCmdable().HSet(context.TODO(), hashValue.Key, hv["field"].(string), hv["value"]).Result()

View File

@@ -148,7 +148,7 @@ func (r *Redis) Scan(rc *req.Ctx) {
func (r *Redis) TtlKey(rc *req.Ctx) {
ri, key := r.checkKeyAndGetRedisIns(rc)
ttl, err := ri.GetCmdable().TTL(context.Background(), key).Result()
biz.ErrIsNil(err, "ttl失败: %s")
biz.ErrIsNilAppendErr(err, "ttl失败: %s")
if ttl == -1 {
rc.ResData = -1
@@ -187,3 +187,10 @@ func (r *Redis) PersistKey(rc *req.Ctx) {
rc.ReqParam = fmt.Sprintf("%s -> 移除key[%s]的过期时间", ri.Info.GetLogDesc(), key)
ri.GetCmdable().Persist(context.Background(), key)
}
// 清空库
func (r *Redis) FlushDb(rc *req.Ctx) {
ri := r.getRedisIns(rc)
rc.ReqParam = fmt.Sprintf("%s -> flushdb", ri.Info.GetLogDesc())
ri.GetCmdable().FlushDB(context.Background())
}

View File

@@ -22,7 +22,7 @@ func (r *Redis) GetListValue(rc *req.Ctx) {
res, err := cmdable.LRange(ctx, key, int64(start), int64(stop)).Result()
biz.ErrIsNilAppendErr(err, "获取list值失败: %s")
rc.ResData = map[string]interface{}{
rc.ResData = map[string]any{
"len": len,
"list": res,
}

View File

@@ -185,7 +185,7 @@ func (r *Redis) ClusterInfo(rc *req.Ctx) {
}
nodesRes = append(nodesRes, node)
}
rc.ResData = map[string]interface{}{
rc.ResData = map[string]any{
"clusterInfo": info,
"clusterNodes": nodesRes,
}

View File

@@ -49,7 +49,7 @@ func (r *Redis) Sscan(rc *req.Ctx) {
cmd := r.getRedisIns(rc).GetCmdable()
keys, cursor, err := cmd.SScan(context.TODO(), scan.Key, scan.Cursor, scan.Match, scan.Count).Result()
biz.ErrIsNilAppendErr(err, "sscan失败: %s")
rc.ResData = map[string]interface{}{
rc.ResData = map[string]any{
"keys": keys,
"cursor": cursor,
}

View File

@@ -28,7 +28,7 @@ func (r *Redis) ZScan(rc *req.Ctx) {
keys, cursor, err := ri.GetCmdable().ZScan(context.TODO(), key, cursor, match, int64(count)).Result()
biz.ErrIsNilAppendErr(err, "sscan失败: %s")
rc.ResData = map[string]interface{}{
rc.ResData = map[string]any{
"keys": keys,
"cursor": cursor,
}

View File

@@ -23,7 +23,7 @@ import (
type Redis interface {
// 分页获取机器脚本信息列表
GetPageList(condition *entity.RedisQuery, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetPageList(condition *entity.RedisQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
Count(condition *entity.RedisQuery) int64
@@ -55,7 +55,7 @@ type redisAppImpl struct {
}
// 分页获取机器脚本信息列表
func (r *redisAppImpl) GetPageList(condition *entity.RedisQuery, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
func (r *redisAppImpl) GetPageList(condition *entity.RedisQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult {
return r.redisRepo.GetRedisList(condition, pageParam, toEntity, orderBy...)
}
@@ -219,13 +219,14 @@ func getRedisSentinelCient(re *entity.Redis, db int) *RedisInstance {
// sentinel模式host为 masterName=host:port,host:port
masterNameAndHosts := strings.Split(re.Host, "=")
sentinelOptions := &redis.FailoverOptions{
MasterName: masterNameAndHosts[0],
SentinelAddrs: strings.Split(masterNameAndHosts[1], ","),
Password: re.Password, // no password set
DB: db, // use default DB
DialTimeout: 8 * time.Second,
ReadTimeout: -1, // Disable timeouts, because SSH does not support deadlines.
WriteTimeout: -1,
MasterName: masterNameAndHosts[0],
SentinelAddrs: strings.Split(masterNameAndHosts[1], ","),
Password: re.Password, // no password set
SentinelPassword: re.Password, // 哨兵节点密码需与redis节点密码一致
DB: db, // use default DB
DialTimeout: 8 * time.Second,
ReadTimeout: -1, // Disable timeouts, because SSH does not support deadlines.
WriteTimeout: -1,
}
if re.SshTunnelMachineId > 0 {
sentinelOptions.Dialer = getRedisDialer(re.SshTunnelMachineId)
@@ -251,7 +252,7 @@ func getRedisDialer(machineId int) func(ctx context.Context, network, addr strin
// redis客户端连接缓存指定时间内没有访问则会被关闭
var redisCache = cache.NewTimedCache(constant.RedisConnExpireTime, 5*time.Second).
WithUpdateAccessTime(true).
OnEvicted(func(key interface{}, value interface{}) {
OnEvicted(func(key any, value any) {
global.Log.Info(fmt.Sprintf("删除redis连接缓存 id = %s", key))
value.(*RedisInstance).Close()
})

View File

@@ -7,7 +7,7 @@ import (
type Redis interface {
// 分页获取机器信息列表
GetRedisList(condition *entity.RedisQuery, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetRedisList(condition *entity.RedisQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
Count(condition *entity.RedisQuery) int64

View File

@@ -17,9 +17,9 @@ func newRedisRepo() repository.Redis {
}
// 分页获取机器信息列表
func (r *redisRepoImpl) GetRedisList(condition *entity.RedisQuery, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
func (r *redisRepoImpl) GetRedisList(condition *entity.RedisQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult {
sql := "SELECT d.* FROM t_redis d WHERE 1=1 "
values := make([]interface{}, 0)
values := make([]any, 0)
if condition.Host != "" {
sql = sql + " AND d.host LIKE ?"
values = append(values, "%"+condition.Host+"%")
@@ -36,7 +36,7 @@ func (r *redisRepoImpl) GetRedisList(condition *entity.RedisQuery, pageParam *mo
}
func (r *redisRepoImpl) Count(condition *entity.RedisQuery) int64 {
where := make(map[string]interface{})
where := make(map[string]any)
if len(condition.TagIds) > 0 {
where["tag_id"] = condition.TagIds
}

View File

@@ -91,6 +91,14 @@ func InitRedisRouter(router *gin.RouterGroup) {
Handle(rs.PersistKey)
})
flushDbL := req.NewLogInfo("redis-flushdb").WithSave(true)
redis.DELETE(":id/:db/flushdb", func(c *gin.Context) {
req.NewCtxWithGin(c).
WithLog(flushDbL).
WithRequiredPermission(saveDataP).
Handle(rs.FlushDb)
})
// 获取string类型值
redis.GET(":id/:db/string-value", func(c *gin.Context) {
req.NewCtxWithGin(c).Handle(rs.GetStringValue)

View File

@@ -57,7 +57,7 @@ func (a *Account) Login(rc *req.Ctx) {
// 保存登录消息
go a.saveLogin(account, clientIp)
rc.ResData = map[string]interface{}{
rc.ResData = map[string]any{
"token": req.CreateToken(account.Id, account.Username),
"name": account.Name,
"username": account.Username,
@@ -84,7 +84,7 @@ func (a *Account) GetPermissions(rc *req.Ctx) {
}
// 保存该账号的权限codes
req.SavePermissionCodes(account.Id, permissions)
rc.ResData = map[string]interface{}{
rc.ResData = map[string]any{
"menus": menus.ToTrees(0),
"permissions": permissions,
}
@@ -268,20 +268,20 @@ func (a *Account) SaveRoles(rc *req.Ctx) {
// 将,拼接的字符串进行切割
idsStr := strings.Split(form.RoleIds, ",")
var newIds []interface{}
var newIds []any
for _, v := range idsStr {
id, _ := strconv.Atoi(v)
newIds = append(newIds, uint64(id))
}
// 将[]uint64转为[]interface{}
// 将[]uint64转为[]any
oIds := a.RoleApp.GetAccountRoleIds(uint64(form.Id))
var oldIds []interface{}
var oldIds []any
for _, v := range oIds {
oldIds = append(oldIds, v)
}
addIds, delIds, _ := utils.ArrayCompare(newIds, oldIds, func(i1, i2 interface{}) bool {
addIds, delIds, _ := utils.ArrayCompare(newIds, oldIds, func(i1, i2 any) bool {
return i1.(uint64) == i2.(uint64)
})

View File

@@ -7,5 +7,5 @@ import (
func GenerateCaptcha(rc *req.Ctx) {
id, image := captcha.Generate()
rc.ResData = map[string]interface{}{"base64Captcha": image, "cid": id}
rc.ResData = map[string]any{"base64Captcha": image, "cid": id}
}

View File

@@ -1,7 +1,7 @@
package form
type AccountCreateForm struct {
Id uint64
Id uint64 `json:"id"`
Name string `json:"name" binding:"required"`
Username string `json:"username" binding:"required,min=4,max=16"`
Password string `json:"password"`

View File

@@ -1,10 +1,10 @@
package form
type ConfigForm struct {
Id int
Name string
Key string
Params string
Value string
Id int `json:"id"`
Name string `json:"name"`
Key string `json:"key"`
Params string `json:"params"`
Value string `json:"value"`
Remark string `json:"remark"`
}

View File

@@ -4,6 +4,6 @@ package form
type LoginForm struct {
Username string `json:"username" binding:"required"`
Password string `binding:"required"`
Captcha string
Cid string
Captcha string `json:"captcha"`
Cid string `json:"cid"`
}

View File

@@ -1,23 +1,23 @@
package form
type ResourceForm struct {
Pid int
Id int
Code string `binding:"required"`
Name string `binding:"required"`
Type int `binding:"required,oneof=1 2"`
Weight int
Meta map[string]interface{}
Pid int `json:"pid"`
Id int `json:"id"`
Code string `json:"code" binding:"required"`
Name string `json:"name" binding:"required"`
Type int `json:"type" binding:"required,oneof=1 2"`
Weight int `json:"weight"`
Meta map[string]any `json:"meta"`
}
type MenuResourceMeta struct {
RouteName string `binding:"required"`
Component string `binding:"required"`
Redirect string
Path string `binding:"required"`
IsKeepAlive bool //
IsHide bool // 是否在菜单栏显示,默认显示
IsAffix bool // tag标签是否不可删除
IsIframe bool
Link string
RouteName string `json:"routeName" binding:"required"`
Component string `json:"component" binding:"required"`
Redirect string `json:"redirect"`
Path string `json:"path" binding:"required"`
IsKeepAlive bool `json:"isKeepAlive"` //
IsHide bool `json:"isHide"` // 是否在菜单栏显示,默认显示
IsAffix bool `json:"isAffix"` // tag标签是否不可删除
IsIframe bool `json:"isIframe"`
Link string `json:"link"`
}

View File

@@ -2,21 +2,21 @@ package form
// 分配角色资源表单信息
type RoleResourceForm struct {
Id int
ResourceIds string
Id int `json:"id"`
ResourceIds string `json:"resourceIds"`
}
// 保存角色信息表单
type RoleForm struct {
Id int
Id int `json:"id"`
Status int `json:"status"` // 1可用-1不可用
Name string `binding:"required"`
Code string `binding:"required"`
Name string `json:"name" binding:"required"`
Code string `json:"code" binding:"required"`
Remark string `json:"remark"`
}
// 账号分配角色表单
type AccountRoleForm struct {
Id int `binding:"required"`
RoleIds string
Id int `json:"id" binding:"required"`
RoleIds string `json:"roleIds"`
}

View File

@@ -2,6 +2,7 @@ package api
import (
"encoding/json"
"fmt"
"mayfly-go/internal/sys/api/form"
"mayfly-go/internal/sys/api/vo"
"mayfly-go/internal/sys/application"
@@ -46,8 +47,20 @@ func (r *Resource) DelResource(rc *req.Ctx) {
}
func (r *Resource) ChangeStatus(rc *req.Ctx) {
re := &entity.Resource{}
re.Id = uint64(ginx.PathParamInt(rc.GinCtx, "id"))
re.Status = int8(ginx.PathParamInt(rc.GinCtx, "status"))
r.ResourceApp.Save(re)
rid := uint64(ginx.PathParamInt(rc.GinCtx, "id"))
status := int8(ginx.PathParamInt(rc.GinCtx, "status"))
rc.ReqParam = fmt.Sprintf("id = %d, status = %d", rid, status)
r.ResourceApp.ChangeStatus(rid, status)
}
func (r *Resource) Sort(rc *req.Ctx) {
var rs []form.ResourceForm
rc.GinCtx.ShouldBindJSON(&rs)
rc.ReqParam = rs
for _, v := range rs {
sortE := &entity.Resource{Pid: v.Pid, Weight: v.Weight}
sortE.Id = uint64(v.Id)
r.ResourceApp.Sort(sortE)
}
}

View File

@@ -69,20 +69,20 @@ func (r *Role) SaveResource(rc *req.Ctx) {
// 将,拼接的字符串进行切割
idsStr := strings.Split(form.ResourceIds, ",")
var newIds []interface{}
var newIds []any
for _, v := range idsStr {
id, _ := strconv.Atoi(v)
newIds = append(newIds, uint64(id))
}
// 将[]uint64转为[]interface{}
// 将[]uint64转为[]any
oIds := r.RoleApp.GetRoleResourceIds(uint64(form.Id))
var oldIds []interface{}
var oldIds []any
for _, v := range oIds {
oldIds = append(oldIds, v)
}
addIds, delIds, _ := utils.ArrayCompare(newIds, oldIds, func(i1, i2 interface{}) bool {
addIds, delIds, _ := utils.ArrayCompare(newIds, oldIds, func(i1, i2 any) bool {
return i1.(uint64) == i2.(uint64)
})

View File

@@ -53,6 +53,7 @@ type ResourceManageVO struct {
Name string `json:"name"`
Type int `json:"type"`
Status int `json:"status"`
Weight int `json:"weight"`
Creator string `json:"creator"`
CreateTime *time.Time `json:"createTime"`
}

View File

@@ -13,7 +13,7 @@ import (
type Account interface {
GetAccount(condition *entity.Account, cols ...string) error
GetPageList(condition *entity.Account, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetPageList(condition *entity.Account, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
Create(account *entity.Account)
@@ -37,7 +37,7 @@ func (a *accountAppImpl) GetAccount(condition *entity.Account, cols ...string) e
return a.accountRepo.GetAccount(condition, cols...)
}
func (a *accountAppImpl) GetPageList(condition *entity.Account, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
func (a *accountAppImpl) GetPageList(condition *entity.Account, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult {
return a.accountRepo.GetPageList(condition, pageParam, toEntity)
}

View File

@@ -13,7 +13,7 @@ import (
const SysConfigKeyPrefix = "sys:config:"
type Config interface {
GetPageList(condition *entity.Config, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetPageList(condition *entity.Config, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
Save(config *entity.Config)
@@ -31,7 +31,7 @@ type configAppImpl struct {
configRepo repository.Config
}
func (a *configAppImpl) GetPageList(condition *entity.Config, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
func (a *configAppImpl) GetPageList(condition *entity.Config, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult {
return a.configRepo.GetPageList(condition, pageParam, toEntity)
}

View File

@@ -9,7 +9,7 @@ import (
)
type Msg interface {
GetPageList(condition *entity.Msg, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetPageList(condition *entity.Msg, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
Create(msg *entity.Msg)
@@ -27,7 +27,7 @@ type msgAppImpl struct {
msgRepo repository.Msg
}
func (a *msgAppImpl) GetPageList(condition *entity.Msg, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
func (a *msgAppImpl) GetPageList(condition *entity.Msg, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult {
return a.msgRepo.GetPageList(condition, pageParam, toEntity)
}

View File

@@ -0,0 +1,169 @@
package application
import (
"mayfly-go/internal/sys/domain/entity"
"mayfly-go/internal/sys/domain/repository"
"mayfly-go/pkg/biz"
"mayfly-go/pkg/global"
"mayfly-go/pkg/model"
"mayfly-go/pkg/utils"
"strings"
"time"
)
type Resource interface {
GetResourceList(condition *entity.Resource, toEntity any, orderBy ...string)
GetById(id uint64, cols ...string) *entity.Resource
GetByIdIn(ids []uint64, toEntity any, cols ...string)
Save(entity *entity.Resource)
ChangeStatus(resourceId uint64, status int8)
Sort(re *entity.Resource)
Delete(id uint64)
GetAccountResources(accountId uint64, toEntity any)
}
func newResourceApp(resourceRepo repository.Resource) Resource {
return &resourceAppImpl{
resourceRepo: resourceRepo,
}
}
type resourceAppImpl struct {
resourceRepo repository.Resource
}
func (r *resourceAppImpl) GetResourceList(condition *entity.Resource, toEntity any, orderBy ...string) {
r.resourceRepo.GetResourceList(condition, toEntity, orderBy...)
}
func (r *resourceAppImpl) GetById(id uint64, cols ...string) *entity.Resource {
return r.resourceRepo.GetById(id, cols...)
}
func (r *resourceAppImpl) GetByIdIn(ids []uint64, toEntity any, orderBy ...string) {
r.resourceRepo.GetByIdIn(ids, toEntity, orderBy...)
}
func (r *resourceAppImpl) Save(resource *entity.Resource) {
// 更新操作
if resource.Id != 0 {
if resource.Code != "" {
oldRes := r.GetById(resource.Id, "Code")
// 如果修改了code则校验新code是否存在
if oldRes.Code != resource.Code {
r.checkCode(resource.Code)
}
}
model.UpdateById(resource)
return
}
// 生成随机八位唯一标识符
ui := utils.RandString(8)
if pid := resource.Pid; pid != 0 {
pResource := r.GetById(uint64(pid))
biz.IsTrue(pResource != nil, "该父资源不存在")
resource.UiPath = pResource.UiPath + ui + entity.ResourceUiPathSp
} else {
resource.UiPath = ui + entity.ResourceUiPathSp
}
// 默认启用状态
if resource.Status == 0 {
resource.Status = entity.ResourceStatusEnable
}
r.checkCode(resource.Code)
resource.Weight = int(time.Now().Unix())
model.Insert(resource)
}
func (r *resourceAppImpl) ChangeStatus(resourceId uint64, status int8) {
resource := r.resourceRepo.GetById(resourceId)
biz.NotNil(resource, "资源不存在")
resource.Status = status
r.resourceRepo.UpdateByUiPathLike(resource)
}
func (r *resourceAppImpl) Sort(sortResource *entity.Resource) {
resource := r.resourceRepo.GetById(sortResource.Id)
biz.NotNil(resource, "资源不存在")
// 未改变父节点,则更新排序值即可
if sortResource.Pid == resource.Pid {
saveE := &entity.Resource{Weight: sortResource.Weight}
saveE.Id = sortResource.Id
r.Save(saveE)
return
}
// 若资源原本唯一标识路径为xxxx/yyyy/zzzz/,则获取其父节点路径标识 xxxx/yyyy/ 与自身节点标识 zzzz/
splitStr := strings.Split(resource.UiPath, entity.ResourceUiPathSp)
// 获取 zzzz/
resourceUi := splitStr[len(splitStr)-2] + entity.ResourceUiPathSp
// 获取父资源路径 xxxx/yyyy/
var parentResourceUiPath string
if len(splitStr) > 2 {
parentResourceUiPath = strings.Split(resource.UiPath, resourceUi)[0]
} else {
parentResourceUiPath = resourceUi
}
newParentResourceUiPath := ""
if sortResource.Pid != 0 {
newParentResource := r.resourceRepo.GetById(uint64(sortResource.Pid))
biz.NotNil(newParentResource, "父资源不存在")
newParentResourceUiPath = newParentResource.UiPath
}
children := r.resourceRepo.GetChildren(resource.UiPath)
for _, v := range children {
if v.Id == sortResource.Id {
continue
}
updateUiPath := &entity.Resource{}
updateUiPath.Id = v.Id
if parentResourceUiPath == resourceUi {
updateUiPath.UiPath = newParentResourceUiPath + v.UiPath
} else {
updateUiPath.UiPath = strings.ReplaceAll(v.UiPath, parentResourceUiPath, newParentResourceUiPath)
}
r.Save(updateUiPath)
}
// 更新零值使用map因为pid=0表示根节点
updateMap := map[string]interface{}{
"pid": sortResource.Pid,
"weight": sortResource.Weight,
"ui_path": newParentResourceUiPath + resourceUi,
}
condition := new(entity.Resource)
condition.Id = sortResource.Id
global.Db.Model(condition).Updates(updateMap)
}
func (r *resourceAppImpl) checkCode(code string) {
biz.IsTrue(!strings.Contains(code, ","), "code不能包含','")
biz.IsEquals(model.CountBy(&entity.Resource{Code: code}), int64(0), "该code已存在")
}
func (r *resourceAppImpl) Delete(id uint64) {
resource := r.resourceRepo.GetById(id)
biz.NotNil(resource, "资源不存在")
// 删除当前节点及其所有子节点
children := r.resourceRepo.GetChildren(resource.UiPath)
for _, v := range children {
r.resourceRepo.Delete(v.Id)
// 删除角色关联的资源信息
model.DeleteByCondition(&entity.RoleResource{ResourceId: v.Id})
}
}
func (r *resourceAppImpl) GetAccountResources(accountId uint64, toEntity any) {
r.resourceRepo.GetAccountResources(accountId, toEntity)
}

View File

@@ -1,91 +0,0 @@
package application
import (
"mayfly-go/internal/sys/domain/entity"
"mayfly-go/internal/sys/domain/repository"
"mayfly-go/pkg/biz"
"mayfly-go/pkg/model"
"strings"
)
type Resource interface {
GetResourceList(condition *entity.Resource, toEntity interface{}, orderBy ...string)
GetById(id uint64, cols ...string) *entity.Resource
GetByIdIn(ids []uint64, toEntity interface{}, cols ...string)
Save(entity *entity.Resource)
Delete(id uint64)
GetAccountResources(accountId uint64, toEntity interface{})
}
func newResourceApp(resourceRepo repository.Resource) Resource {
return &resourceAppImpl{
resourceRepo: resourceRepo,
}
}
type resourceAppImpl struct {
resourceRepo repository.Resource
}
func (r *resourceAppImpl) GetResourceList(condition *entity.Resource, toEntity interface{}, orderBy ...string) {
r.resourceRepo.GetResourceList(condition, toEntity, orderBy...)
}
func (r *resourceAppImpl) GetById(id uint64, cols ...string) *entity.Resource {
return r.resourceRepo.GetById(id, cols...)
}
func (r *resourceAppImpl) GetByIdIn(ids []uint64, toEntity interface{}, orderBy ...string) {
r.resourceRepo.GetByIdIn(ids, toEntity, orderBy...)
}
func (r *resourceAppImpl) Save(resource *entity.Resource) {
if resource.Id != 0 {
if resource.Code != "" {
oldRes := r.GetById(resource.Id, "Code")
// 如果修改了code则校验新code是否存在
if oldRes.Code != resource.Code {
r.checkCode(resource.Code)
}
}
model.UpdateById(resource)
} else {
if pid := resource.Pid; pid != 0 {
biz.IsTrue(r.GetById(uint64(pid)) != nil, "该父资源不存在")
}
// 默认启用状态
if resource.Status == 0 {
resource.Status = entity.ResourceStatusEnable
}
r.checkCode(resource.Code)
model.Insert(resource)
}
}
func (r *resourceAppImpl) checkCode(code string) {
biz.IsTrue(!strings.Contains(code, ","), "code不能包含','")
biz.IsEquals(model.CountBy(&entity.Resource{Code: code}), int64(0), "该code已存在")
}
func (r *resourceAppImpl) Delete(id uint64) {
// 查找pid == id的资源
condition := &entity.Resource{Pid: int(id)}
var resources resourceList
r.resourceRepo.GetResourceList(condition, &resources)
biz.IsTrue(len(resources) == 0, "请先删除该资源的所有子资源")
model.DeleteById(condition, id)
// 删除角色关联的资源信息
model.DeleteByCondition(&entity.RoleResource{ResourceId: id})
}
func (r *resourceAppImpl) GetAccountResources(accountId uint64, toEntity interface{}) {
r.resourceRepo.GetAccountResources(accountId, toEntity)
}
type resourceList []entity.Resource

View File

@@ -8,7 +8,7 @@ import (
)
type Role interface {
GetPageList(condition *entity.Role, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetPageList(condition *entity.Role, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
SaveRole(role *entity.Role)
@@ -16,7 +16,7 @@ type Role interface {
GetRoleResourceIds(roleId uint64) []uint64
GetRoleResources(roleId uint64, toEntity interface{})
GetRoleResources(roleId uint64, toEntity any)
// 保存角色资源关联记录
SaveRoleResource(rr *entity.RoleResource)
@@ -32,7 +32,7 @@ type Role interface {
DeleteAccountRole(accountId, roleId uint64)
GetAccountRoles(accountId uint64, toEntity interface{})
GetAccountRoles(accountId uint64, toEntity any)
}
func newRoleApp(roleRepo repository.Role) Role {
@@ -45,7 +45,7 @@ type roleAppImpl struct {
roleRepo repository.Role
}
func (m *roleAppImpl) GetPageList(condition *entity.Role, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
func (m *roleAppImpl) GetPageList(condition *entity.Role, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult {
return m.roleRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
}
@@ -71,7 +71,7 @@ func (m *roleAppImpl) GetRoleResourceIds(roleId uint64) []uint64 {
return m.roleRepo.GetRoleResourceIds(roleId)
}
func (m *roleAppImpl) GetRoleResources(roleId uint64, toEntity interface{}) {
func (m *roleAppImpl) GetRoleResources(roleId uint64, toEntity any) {
m.roleRepo.GetRoleResources(roleId, toEntity)
}
@@ -95,6 +95,6 @@ func (m *roleAppImpl) DeleteAccountRole(accountId, roleId uint64) {
m.roleRepo.DeleteAccountRole(accountId, roleId)
}
func (m *roleAppImpl) GetAccountRoles(accountId uint64, toEntity interface{}) {
func (m *roleAppImpl) GetAccountRoles(accountId uint64, toEntity any) {
m.roleRepo.GetAccountRoles(accountId, toEntity)
}

View File

@@ -13,7 +13,7 @@ import (
)
type Syslog interface {
GetPageList(condition *entity.Syslog, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetPageList(condition *entity.Syslog, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
// 从请求上下文的参数保存系统日志
SaveFromReq(req *req.Ctx)
@@ -29,7 +29,7 @@ type syslogAppImpl struct {
syslogRepo repository.Syslog
}
func (m *syslogAppImpl) GetPageList(condition *entity.Syslog, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult {
func (m *syslogAppImpl) GetPageList(condition *entity.Syslog, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult {
return m.syslogRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
}

View File

@@ -5,6 +5,7 @@ import "mayfly-go/pkg/model"
type Resource struct {
model.Model
Pid int `json:"pid"`
UiPath string // 唯一标识路径
Type int8 `json:"type"` // 1菜单路由2资源按钮等
Status int8 `json:"status"` // 1可用-1不可用
Code string `json:"code"`
@@ -24,4 +25,7 @@ const (
// 资源状态
ResourceTypeMenu int8 = 1
ResourceTypePermission int8 = 2
// 唯一标识路径分隔符
ResourceUiPathSp string = "/"
)

View File

@@ -9,7 +9,7 @@ type Account interface {
// 根据条件获取账号信息
GetAccount(condition *entity.Account, cols ...string) error
GetPageList(condition *entity.Account, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetPageList(condition *entity.Account, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
Insert(account *entity.Account)

View File

@@ -6,7 +6,7 @@ import (
)
type Config interface {
GetPageList(condition *entity.Config, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetPageList(condition *entity.Config, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
Insert(config *entity.Config)

View File

@@ -6,7 +6,7 @@ import (
)
type Msg interface {
GetPageList(condition *entity.Msg, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetPageList(condition *entity.Msg, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
Insert(msg *entity.Msg)
}

View File

@@ -6,16 +6,22 @@ import (
type Resource interface {
// 获取资源列表
GetResourceList(condition *entity.Resource, toEntity interface{}, orderBy ...string)
GetResourceList(condition *entity.Resource, toEntity any, orderBy ...string)
GetById(id uint64, cols ...string) *entity.Resource
GetByIdIn(ids []uint64, toEntity interface{}, orderBy ...string)
GetByIdIn(ids []uint64, toEntity any, orderBy ...string)
Delete(id uint64)
GetByCondition(condition *entity.Resource, cols ...string) error
// 获取账号资源列表
GetAccountResources(accountId uint64, toEntity interface{})
GetAccountResources(accountId uint64, toEntity any)
// 获取所有子节点id
GetChildren(uiPath string) []entity.Resource
// 根据uiPath右匹配更新所有相关类资源
UpdateByUiPathLike(resource *entity.Resource)
}

View File

@@ -6,14 +6,14 @@ import (
)
type Role interface {
GetPageList(condition *entity.Role, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetPageList(condition *entity.Role, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
Delete(id uint64)
// 获取角色拥有的资源id数组从role_resource表获取
GetRoleResourceIds(roleId uint64) []uint64
GetRoleResources(roleId uint64, toEntity interface{})
GetRoleResources(roleId uint64, toEntity any)
SaveRoleResource(rr *entity.RoleResource)
@@ -27,5 +27,5 @@ type Role interface {
DeleteAccountRole(accountId, roleId uint64)
// 获取账号角色信息列表
GetAccountRoles(accountId uint64, toEntity interface{})
GetAccountRoles(accountId uint64, toEntity any)
}

View File

@@ -6,7 +6,7 @@ import (
)
type Syslog interface {
GetPageList(condition *entity.Syslog, pageParam *model.PageParam, toEntity interface{}, orderBy ...string) *model.PageResult
GetPageList(condition *entity.Syslog, pageParam *model.PageParam, toEntity any, orderBy ...string) *model.PageResult
Insert(log *entity.Syslog)
}

Some files were not shown because too many files have changed in this diff Show More