mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-02 15:30:25 +08:00
refactor: 样式调整
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
<div>
|
||||
<transition name="el-zoom-in-top">
|
||||
<!-- 查询表单 -->
|
||||
<SearchForm v-show="isShowSearch" :items="searchItems" v-model="queryForm_" :search="queryData" :reset="reset" :search-col="searchCol">
|
||||
<SearchForm v-if="isShowSearch" :items="searchItems" v-model="queryForm_" :search="queryData" :reset="reset" :search-col="searchCol">
|
||||
<!-- 遍历父组件传入的 solts 透传给子组件 -->
|
||||
<template v-for="(_, key) in useSlots()" v-slot:[key]>
|
||||
<slot :name="key"></slot>
|
||||
@@ -10,7 +10,7 @@
|
||||
</SearchForm>
|
||||
</transition>
|
||||
|
||||
<el-card>
|
||||
<div class="card">
|
||||
<div class="table-main">
|
||||
<!-- 表格头部 操作按钮 -->
|
||||
<div class="table-header">
|
||||
@@ -121,7 +121,7 @@
|
||||
:page-sizes="pageSizes"
|
||||
/>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -190,6 +190,18 @@ body,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.flex-justify-between {
|
||||
display: flex;
|
||||
align-items: center; // 垂直方向水平居中
|
||||
justify-content: space-between; // 使第一个子元素靠近父容器的起始位置,最后一个子元素靠近终止位置,而其他子元素均匀分布在它们之间
|
||||
}
|
||||
|
||||
.flex-align-center {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 宽高 100%
|
||||
------------------------------- */
|
||||
.w100 {
|
||||
@@ -276,6 +288,10 @@ body,
|
||||
.pl#{$i} {
|
||||
padding-left: #{$i}px !important;
|
||||
}
|
||||
|
||||
.pd#{$i} {
|
||||
padding: #{$i}px !important;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -335,12 +351,15 @@ body,
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.toolbar {
|
||||
width: 100%;
|
||||
padding: 4px;
|
||||
overflow: hidden;
|
||||
line-height: 24px;
|
||||
border: 1px solid var(--el-border-color-light, #ebeef5);
|
||||
/* custom card */
|
||||
.card {
|
||||
box-sizing: border-box;
|
||||
padding: 20px;
|
||||
overflow-x: hidden;
|
||||
background-color: var(--el-bg-color);
|
||||
border: 1px solid var(--el-border-color-light);
|
||||
border-radius: 6px;
|
||||
box-shadow: 0 0 12px rgb(0 0 0 / 5%);
|
||||
}
|
||||
|
||||
.fl {
|
||||
@@ -361,10 +380,6 @@ body,
|
||||
z-index: inherit !important;
|
||||
}
|
||||
|
||||
.f12 {
|
||||
font-size: 12px
|
||||
}
|
||||
|
||||
.pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -396,6 +411,7 @@ body,
|
||||
.default-theme.splitpanes--horizontal>.splitpanes__splitter {
|
||||
border-top: 1px solid var(--bg-main-color);
|
||||
}
|
||||
|
||||
// 竖线样式
|
||||
.splitpanes.default-theme .splitpanes__splitter::before,
|
||||
.splitpanes.default-theme .splitpanes__splitter::after {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="tag-tree">
|
||||
<el-input v-model="filterText" placeholder="输入关键字->搜索已展开节点信息" clearable size="small" class="mb5" />
|
||||
<el-scrollbar :style="{ height: state.height, maxHeight: state.height, backgroundColor: 'var(--el-fill-color-blank)' }">
|
||||
<div class="tag-tree card pd5">
|
||||
<el-scrollbar>
|
||||
<el-input v-model="filterText" placeholder="输入关键字->搜索已展开节点信息" clearable size="small" class="mb5 w100" />
|
||||
<el-tree
|
||||
ref="treeRef"
|
||||
:highlight-current="true"
|
||||
@@ -32,8 +32,9 @@
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
|
||||
<contextmenu :dropdown="state.dropdown" :items="state.contextmenuItems" ref="contextmenuRef" @currentContextmenuClick="onCurrentContextmenuClick" />
|
||||
</el-scrollbar>
|
||||
<contextmenu :dropdown="state.dropdown" :items="state.contextmenuItems" ref="contextmenuRef" @currentContextmenuClick="onCurrentContextmenuClick" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -43,7 +44,6 @@ import { NodeType, TagTreeNode } from './tag';
|
||||
import TagInfo from './TagInfo.vue';
|
||||
import { Contextmenu } from '@/components/contextmenu';
|
||||
import { tagApi } from '../tag/api';
|
||||
import { useEventListener, useWindowSize } from '@vueuse/core';
|
||||
|
||||
const props = defineProps({
|
||||
resourceType: {
|
||||
@@ -74,8 +74,6 @@ const emit = defineEmits(['nodeClick', 'currentContextmenuClick']);
|
||||
const treeRef: any = ref(null);
|
||||
const contextmenuRef = ref();
|
||||
|
||||
const { height: vh } = useWindowSize();
|
||||
|
||||
const state = reactive({
|
||||
height: 600 as any,
|
||||
filterText: '',
|
||||
@@ -88,14 +86,7 @@ const state = reactive({
|
||||
});
|
||||
const { filterText } = toRefs(state);
|
||||
|
||||
onMounted(async () => {
|
||||
setHeight();
|
||||
useEventListener(window, 'resize', setHeight);
|
||||
});
|
||||
|
||||
const setHeight = () => {
|
||||
state.height = vh.value - 138 + 'px';
|
||||
};
|
||||
onMounted(async () => {});
|
||||
|
||||
watch(filterText, (val) => {
|
||||
treeRef.value?.filter(val);
|
||||
@@ -195,8 +186,7 @@ defineExpose({
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.tag-tree {
|
||||
border-radius: var(--el-input-border-radius, var(--el-border-radius-base));
|
||||
border: 1px solid var(--el-border-color-light, #ebeef5);
|
||||
height: calc(100vh - 108px);
|
||||
|
||||
.el-tree {
|
||||
display: inline-block;
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
</el-col>
|
||||
<el-col style="text-align: center" :span="1">:</el-col>
|
||||
<el-col :span="5">
|
||||
<el-input type="number" v-model.number="form.port" placeholder="请输入端口"></el-input>
|
||||
<el-input type="number" v-model.number="form.port" placeholder="端口"></el-input>
|
||||
</el-col>
|
||||
</el-form-item>
|
||||
<el-form-item prop="username" label="用户名" required>
|
||||
@@ -49,7 +49,7 @@
|
||||
<el-tab-pane label="其他配置" name="other">
|
||||
<el-form-item prop="params" label="连接参数">
|
||||
<el-input v-model.trim="form.params" placeholder="其他连接参数,形如: key1=value1&key2=value2">
|
||||
<template #suffix>
|
||||
<!-- <template #suffix>
|
||||
<el-link
|
||||
target="_blank"
|
||||
href="https://github.com/go-sql-driver/mysql#parameters"
|
||||
@@ -58,7 +58,7 @@
|
||||
class="mr5"
|
||||
>参数参考</el-link
|
||||
>
|
||||
</template>
|
||||
</template> -->
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
@@ -47,101 +47,103 @@
|
||||
</Pane>
|
||||
|
||||
<Pane>
|
||||
<el-row>
|
||||
<el-col :span="24" v-if="state.db">
|
||||
<el-descriptions :column="4" size="small" border class="ml5">
|
||||
<el-descriptions-item label-align="right" label="操作"
|
||||
><el-button
|
||||
:disabled="!state.db || !nowDbInst.id"
|
||||
type="primary"
|
||||
icon="Search"
|
||||
@click="addQueryTab({ id: nowDbInst.id, dbs: nowDbInst.databases }, state.db)"
|
||||
size="small"
|
||||
>新建查询</el-button
|
||||
></el-descriptions-item
|
||||
>
|
||||
<div class="card db-op pd5">
|
||||
<el-row>
|
||||
<el-col :span="24" v-if="state.db">
|
||||
<el-descriptions :column="4" size="small" border>
|
||||
<el-descriptions-item label-align="right" label="操作"
|
||||
><el-button
|
||||
:disabled="!state.db || !nowDbInst.id"
|
||||
type="primary"
|
||||
icon="Search"
|
||||
@click="addQueryTab({ id: nowDbInst.id, dbs: nowDbInst.databases }, state.db)"
|
||||
size="small"
|
||||
>新建查询</el-button
|
||||
></el-descriptions-item
|
||||
>
|
||||
|
||||
<el-descriptions-item label-align="right" label="tag">{{ nowDbInst.tagPath }}</el-descriptions-item>
|
||||
<el-descriptions-item label-align="right" label="tag">{{ nowDbInst.tagPath }}</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label-align="right">
|
||||
<template #label>
|
||||
<div>
|
||||
<SvgIcon :name="getDbDialect(nowDbInst.type).getInfo().icon" :size="18" />
|
||||
实例
|
||||
</div>
|
||||
</template>
|
||||
{{ nowDbInst.id }}
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
{{ nowDbInst.name }}
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
{{ nowDbInst.host }}
|
||||
</el-descriptions-item>
|
||||
|
||||
<el-descriptions-item label="库名" label-align="right">{{ state.db }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<div id="data-exec" class="mt5 ml5">
|
||||
<el-tabs
|
||||
v-if="state.tabs.size > 0"
|
||||
type="card"
|
||||
@tab-remove="onRemoveTab"
|
||||
@tab-change="onTabChange"
|
||||
style="width: 100%"
|
||||
v-model="state.activeName"
|
||||
class="h100"
|
||||
>
|
||||
<el-tab-pane class="h100" closable v-for="dt in state.tabs.values()" :label="dt.label" :name="dt.key" :key="dt.key">
|
||||
<template #label>
|
||||
<el-popover :show-after="1000" placement="bottom-start" trigger="hover" :width="250">
|
||||
<template #reference> {{ dt.label }} </template>
|
||||
<template #default>
|
||||
<el-descriptions :column="1" size="small">
|
||||
<el-descriptions-item label="tagPath">
|
||||
{{ dt.params.tagPath }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="名称">
|
||||
{{ dt.params.name }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="host">
|
||||
<SvgIcon :name="getDbDialect(dt.params.type).getInfo().icon" :size="18" />
|
||||
{{ dt.params.host }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="库名">
|
||||
{{ dt.params.dbName }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
<el-descriptions-item label-align="right">
|
||||
<template #label>
|
||||
<div>
|
||||
<SvgIcon :name="getDbDialect(nowDbInst.type).getInfo().icon" :size="18" />
|
||||
实例
|
||||
</div>
|
||||
</template>
|
||||
</el-popover>
|
||||
</template>
|
||||
{{ nowDbInst.id }}
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
{{ nowDbInst.name }}
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
{{ nowDbInst.host }}
|
||||
</el-descriptions-item>
|
||||
|
||||
<db-table-data-op
|
||||
v-if="dt.type === TabType.TableData"
|
||||
:db-id="dt.dbId"
|
||||
:db-name="dt.db"
|
||||
:table-name="dt.params.table"
|
||||
:table-height="state.dataTabsTableHeight"
|
||||
></db-table-data-op>
|
||||
<el-descriptions-item label="库名" label-align="right">{{ state.db }}</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<db-sql-editor
|
||||
v-if="dt.type === TabType.Query"
|
||||
:db-id="dt.dbId"
|
||||
:db-name="dt.db"
|
||||
:sql-name="dt.params.sqlName"
|
||||
@save-sql-success="reloadSqls"
|
||||
>
|
||||
</db-sql-editor>
|
||||
<div id="data-exec" class="mt5">
|
||||
<el-tabs
|
||||
v-if="state.tabs.size > 0"
|
||||
type="card"
|
||||
@tab-remove="onRemoveTab"
|
||||
@tab-change="onTabChange"
|
||||
style="width: 100%"
|
||||
v-model="state.activeName"
|
||||
class="h100"
|
||||
>
|
||||
<el-tab-pane class="h100" closable v-for="dt in state.tabs.values()" :label="dt.label" :name="dt.key" :key="dt.key">
|
||||
<template #label>
|
||||
<el-popover :show-after="1000" placement="bottom-start" trigger="hover" :width="250">
|
||||
<template #reference> {{ dt.label }} </template>
|
||||
<template #default>
|
||||
<el-descriptions :column="1" size="small">
|
||||
<el-descriptions-item label="tagPath">
|
||||
{{ dt.params.tagPath }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="名称">
|
||||
{{ dt.params.name }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="host">
|
||||
<SvgIcon :name="getDbDialect(dt.params.type).getInfo().icon" :size="18" />
|
||||
{{ dt.params.host }}
|
||||
</el-descriptions-item>
|
||||
<el-descriptions-item label="库名">
|
||||
{{ dt.params.dbName }}
|
||||
</el-descriptions-item>
|
||||
</el-descriptions>
|
||||
</template>
|
||||
</el-popover>
|
||||
</template>
|
||||
|
||||
<db-tables-op
|
||||
v-if="dt.type == TabType.TablesOp"
|
||||
:db-id="dt.params.id"
|
||||
:db="dt.params.db"
|
||||
:db-type="dt.params.type"
|
||||
:height="state.tablesOpHeight"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<db-table-data-op
|
||||
v-if="dt.type === TabType.TableData"
|
||||
:db-id="dt.dbId"
|
||||
:db-name="dt.db"
|
||||
:table-name="dt.params.table"
|
||||
:table-height="state.dataTabsTableHeight"
|
||||
></db-table-data-op>
|
||||
|
||||
<db-sql-editor
|
||||
v-if="dt.type === TabType.Query"
|
||||
:db-id="dt.dbId"
|
||||
:db-name="dt.db"
|
||||
:sql-name="dt.params.sqlName"
|
||||
@save-sql-success="reloadSqls"
|
||||
>
|
||||
</db-sql-editor>
|
||||
|
||||
<db-tables-op
|
||||
v-if="dt.type == TabType.TablesOp"
|
||||
:db-id="dt.params.id"
|
||||
:db="dt.params.db"
|
||||
:db-type="dt.params.type"
|
||||
:height="state.tablesOpHeight"
|
||||
/>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</div>
|
||||
</Pane>
|
||||
</Splitpanes>
|
||||
@@ -397,8 +399,8 @@ onBeforeUnmount(() => {
|
||||
* 设置editor高度和数据表高度
|
||||
*/
|
||||
const setHeight = () => {
|
||||
state.dataTabsTableHeight = window.innerHeight - 255 + 'px';
|
||||
state.tablesOpHeight = window.innerHeight - 212 + 'px';
|
||||
state.dataTabsTableHeight = window.innerHeight - 270 + 'px';
|
||||
state.tablesOpHeight = window.innerHeight - 225 + 'px';
|
||||
};
|
||||
|
||||
// 选择数据库,改变当前正在操作的数据库信息
|
||||
@@ -607,6 +609,10 @@ const getNowDbInfo = () => {
|
||||
font-size: 9px;
|
||||
}
|
||||
|
||||
.db-op {
|
||||
height: calc(100vh - 108px);
|
||||
}
|
||||
|
||||
#data-exec {
|
||||
.el-tabs {
|
||||
--el-tabs-header-height: 30px;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div>
|
||||
<div>
|
||||
<div class="toolbar">
|
||||
<div class="fl">
|
||||
<div class="card pd5 flex-justify-between">
|
||||
<div>
|
||||
<el-link @click="onRunSql()" :underline="false" class="ml15" icon="VideoPlay"> </el-link>
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
</el-upload>
|
||||
</div>
|
||||
|
||||
<div class="fr">
|
||||
<div>
|
||||
<el-button @click="saveSql()" type="primary" icon="document-add" plain size="small">保存SQL</el-button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -44,7 +44,7 @@
|
||||
@resize="resizeTableHeight"
|
||||
horizontal
|
||||
class="default-theme"
|
||||
style="height: calc(100vh - 220px)"
|
||||
style="height: calc(100vh - 233px)"
|
||||
>
|
||||
<Pane :size="state.editorSize" max-size="80">
|
||||
<MonacoEditor ref="monacoEditorRef" class="mt5" v-model="state.sql" language="sql" height="100%" :id="'MonacoTextarea-' + getKey()" />
|
||||
@@ -128,7 +128,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { h, nextTick, onMounted, reactive, toRefs, ref } from 'vue';
|
||||
import { h, nextTick, onMounted, reactive, toRefs, ref, unref } from 'vue';
|
||||
import { getToken } from '@/common/utils/storage';
|
||||
import { notBlank } from '@/common/assert';
|
||||
import { format as sqlFormatter } from 'sql-formatter';
|
||||
@@ -276,7 +276,7 @@ const onRemoveTab = (targetId: number) => {
|
||||
const resizeTableHeight = (e: any) => {
|
||||
const vh = window.innerHeight;
|
||||
state.editorSize = e[0].size;
|
||||
const plitpaneHeight = vh - 210;
|
||||
const plitpaneHeight = vh - 223;
|
||||
const editorHeight = plitpaneHeight * (state.editorSize / 100);
|
||||
state.tableDataHeight = plitpaneHeight - editorHeight - 40 + 'px';
|
||||
};
|
||||
@@ -336,7 +336,7 @@ const onRunSql = async (newTab = false) => {
|
||||
// 不是新建tab执行,则在当前激活的tab上执行sql
|
||||
i = state.execResTabs.findIndex((x) => x.id == state.activeTab);
|
||||
execRes = state.execResTabs[i];
|
||||
if (execRes.loading?.value) {
|
||||
if (unref(execRes.loading)) {
|
||||
ElMessage.error('当前结果集tab正在执行, 请使用新标签执行');
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -47,11 +47,11 @@
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
|
||||
<el-tooltip :show-after="500" v-if="hasUpdatedFileds" class="box-item" effect="dark" content="提交修改" placement="top">
|
||||
<el-link @click="submitUpdateFields()" type="success" :underline="false" class="f12">提交</el-link>
|
||||
<el-link @click="submitUpdateFields()" type="success" :underline="false" class="font12">提交</el-link>
|
||||
</el-tooltip>
|
||||
<el-divider v-if="hasUpdatedFileds" direction="vertical" border-style="dashed" />
|
||||
<el-tooltip :show-after="500" v-if="hasUpdatedFileds" class="box-item" effect="dark" content="取消修改" placement="top">
|
||||
<el-link @click="cancelUpdateFields" type="warning" :underline="false" class="f12">取消</el-link>
|
||||
<el-link @click="cancelUpdateFields" type="warning" :underline="false" class="font12">取消</el-link>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
<template>
|
||||
<div class="file-manage">
|
||||
<el-dialog title="进程信息" v-model="dialogVisible" :destroy-on-close="true" :show-close="true" :before-close="handleClose" width="65%">
|
||||
<div class="toolbar">
|
||||
<div class="card pd5">
|
||||
<el-row>
|
||||
<el-col :span="4">
|
||||
<el-input size="small" placeholder="进程名" v-model="params.name" plain clearable></el-input>
|
||||
</el-col>
|
||||
<el-col :span="4" class="ml5">
|
||||
<el-select @change="getProcess" size="small" v-model="params.sortType" placeholder="请选择排序类型">
|
||||
<el-select class="w100" @change="getProcess" size="small" v-model="params.sortType" placeholder="请选择排序类型">
|
||||
<el-option key="cpu" label="cpu降序" value="1"> </el-option>
|
||||
<el-option key="cpu" label="mem降序" value="2"> </el-option>
|
||||
</el-select>
|
||||
</el-col>
|
||||
<el-col :span="4" class="ml5">
|
||||
<el-select @change="getProcess" size="small" v-model="params.count" placeholder="请选择进程个数">
|
||||
<el-select class="w100" @change="getProcess" size="small" v-model="params.count" placeholder="请选择进程个数">
|
||||
<el-option key="10" label="10" value="10"> </el-option>
|
||||
<el-option key="15" label="15" value="15"> </el-option>
|
||||
<el-option key="20" label="20" value="20"> </el-option>
|
||||
|
||||
@@ -44,9 +44,9 @@
|
||||
</Pane>
|
||||
|
||||
<Pane>
|
||||
<div id="mongo-tab" class="ml5" style="border: 1px solid var(--el-border-color-light, #ebeef5); margin-top: 1px">
|
||||
<div class="mongo-data-tab card pd5">
|
||||
<el-row v-if="nowColl">
|
||||
<el-descriptions :column="10" size="small" border>
|
||||
<el-descriptions class="w100" :column="10" size="small" border>
|
||||
<!-- <el-descriptions-item label-align="right" label="tag">xxx</el-descriptions-item> -->
|
||||
|
||||
<el-descriptions-item label="ns" label-align="right">
|
||||
@@ -74,7 +74,7 @@
|
||||
</el-row>
|
||||
|
||||
<el-row type="flex">
|
||||
<el-tabs @tab-remove="removeDataTab" style="width: 100%; margin-left: 5px" v-model="state.activeName">
|
||||
<el-tabs @tab-remove="removeDataTab" class="w100 ml5" v-model="state.activeName">
|
||||
<el-tab-pane closable v-for="dt in state.dataTabs" :key="dt.key" :label="dt.label" :name="dt.key">
|
||||
<el-row>
|
||||
<el-col :span="2">
|
||||
@@ -96,27 +96,29 @@
|
||||
</el-input>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :style="`height: ${dataHeight}; overflow: auto;`">
|
||||
<el-col :span="6" v-for="item in dt.datas" :key="item">
|
||||
<el-card :body-style="{ padding: '0px', position: 'relative' }">
|
||||
<el-input type="textarea" v-model="item.value" :rows="10" />
|
||||
<div style="padding: 3px; float: right" class="mr5 mongo-doc-btns">
|
||||
<div>
|
||||
<el-link @click="onEditDoc(item)" :underline="false" type="success" icon="MagicStick"></el-link>
|
||||
<el-scrollbar class="mongo-data-tab-data">
|
||||
<el-row>
|
||||
<el-col :span="6" v-for="item in dt.datas" :key="item">
|
||||
<el-card :body-style="{ padding: '0px', position: 'relative' }">
|
||||
<el-input type="textarea" v-model="item.value" :rows="10" />
|
||||
<div style="padding: 3px; float: right" class="mr5 mongo-doc-btns">
|
||||
<div>
|
||||
<el-link @click="onEditDoc(item)" :underline="false" type="success" icon="MagicStick"></el-link>
|
||||
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
<el-divider direction="vertical" border-style="dashed" />
|
||||
|
||||
<el-popconfirm @confirm="onDeleteDoc(item.value)" title="确定删除该文档?" width="160">
|
||||
<template #reference>
|
||||
<el-link v-auth="perms.delData" :underline="false" type="danger" icon="DocumentDelete">
|
||||
</el-link>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
<el-popconfirm @confirm="onDeleteDoc(item.value)" title="确定删除该文档?" width="160">
|
||||
<template #reference>
|
||||
<el-link v-auth="perms.delData" :underline="false" type="danger" icon="DocumentDelete">
|
||||
</el-link>
|
||||
</template>
|
||||
</el-popconfirm>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-scrollbar>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-row>
|
||||
@@ -253,7 +255,6 @@ const NodeTypeColl = new NodeType(MongoNodeType.Coll).withNodeClickFunc((nodeDat
|
||||
const findParamInputRef: any = ref(null);
|
||||
const state = reactive({
|
||||
tags: [],
|
||||
dataHeight: `${window.innerHeight - 220}px`,
|
||||
mongoList: [] as any,
|
||||
activeName: '', // 当前操作的tab
|
||||
dataTabs: {} as any, // 数据tabs
|
||||
@@ -282,7 +283,7 @@ const state = reactive({
|
||||
},
|
||||
});
|
||||
|
||||
const { dataHeight, findDialog, docEditDialog } = toRefs(state);
|
||||
const { findDialog, docEditDialog } = toRefs(state);
|
||||
|
||||
const nowColl = computed(() => {
|
||||
return getNowDataTab();
|
||||
@@ -506,7 +507,17 @@ const getNowDataTab = () => {
|
||||
max-width: 120px;
|
||||
}
|
||||
|
||||
#mongo-tab {
|
||||
.mongo-data-tab {
|
||||
height: calc(100vh - 108px);
|
||||
}
|
||||
|
||||
.mongo-data-tab {
|
||||
margin-top: 1px;
|
||||
|
||||
.mongo-data-tab-data {
|
||||
height: calc(100vh - 230px);
|
||||
}
|
||||
|
||||
.el-tabs__header {
|
||||
margin: 0 0 5px;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="redis-data-op">
|
||||
<Splitpanes class="default-theme">
|
||||
<Pane size="20" max-size="30">
|
||||
<tag-tree :resource-type="TagResourceTypeEnum.Redis.value" :tag-path-node-type="NodeTypeTagPath">
|
||||
@@ -34,68 +34,68 @@
|
||||
</Pane>
|
||||
|
||||
<Pane min-size="20" size="30">
|
||||
<div class="key-list-vtree">
|
||||
<el-row>
|
||||
<el-col :span="2">
|
||||
<el-input v-model="state.keySeparator" placeholder="分割符" size="small" class="ml5" />
|
||||
</el-col>
|
||||
<el-col :span="18">
|
||||
<el-input @clear="clear" v-model="scanParam.match" placeholder="match 支持*模糊key" clearable size="small" class="ml10" />
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-button
|
||||
class="ml15"
|
||||
:disabled="!scanParam.id || !scanParam.db"
|
||||
@click="searchKey()"
|
||||
type="success"
|
||||
icon="search"
|
||||
size="small"
|
||||
plain
|
||||
></el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<div class="key-list-vtree card pd5">
|
||||
<el-scrollbar>
|
||||
<el-row>
|
||||
<el-col :span="2">
|
||||
<el-input v-model="state.keySeparator" placeholder="分割符" size="small" class="ml5" />
|
||||
</el-col>
|
||||
<el-col :span="18">
|
||||
<el-input @clear="clear" v-model="scanParam.match" placeholder="match 支持*模糊key" clearable size="small" class="ml10" />
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-button
|
||||
class="ml15"
|
||||
:disabled="!scanParam.id || !scanParam.db"
|
||||
@click="searchKey()"
|
||||
type="success"
|
||||
icon="search"
|
||||
size="small"
|
||||
plain
|
||||
></el-button>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row class="mb5 mt5">
|
||||
<el-col :span="19">
|
||||
<el-button class="ml5" :disabled="!scanParam.id || !scanParam.db" @click="scan(true)" type="success" icon="more" size="small" plain
|
||||
>加载更多</el-button
|
||||
>
|
||||
<el-row class="mb5 mt5">
|
||||
<el-col :span="19">
|
||||
<el-button
|
||||
class="ml5"
|
||||
:disabled="!scanParam.id || !scanParam.db"
|
||||
@click="scan(true)"
|
||||
type="success"
|
||||
icon="more"
|
||||
size="small"
|
||||
plain
|
||||
>加载更多</el-button
|
||||
>
|
||||
|
||||
<el-button
|
||||
v-auth="'redis:data:save'"
|
||||
:disabled="!scanParam.id || !scanParam.db"
|
||||
@click="showNewKeyDialog"
|
||||
type="primary"
|
||||
icon="plus"
|
||||
size="small"
|
||||
plain
|
||||
>新增key</el-button
|
||||
>
|
||||
<el-button
|
||||
v-auth="'redis:data:save'"
|
||||
:disabled="!scanParam.id || !scanParam.db"
|
||||
@click="showNewKeyDialog"
|
||||
type="primary"
|
||||
icon="plus"
|
||||
size="small"
|
||||
plain
|
||||
>新增key</el-button
|
||||
>
|
||||
|
||||
<el-button
|
||||
:disabled="!scanParam.id || !scanParam.db"
|
||||
@click="flushDb"
|
||||
type="danger"
|
||||
plain
|
||||
v-auth="'redis:data:del'"
|
||||
size="small"
|
||||
icon="delete"
|
||||
>flush</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<span style="display: inline-block" class="mt5">keys:{{ state.dbsize }}</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-button
|
||||
:disabled="!scanParam.id || !scanParam.db"
|
||||
@click="flushDb"
|
||||
type="danger"
|
||||
plain
|
||||
v-auth="'redis:data:del'"
|
||||
size="small"
|
||||
icon="delete"
|
||||
>flush</el-button
|
||||
>
|
||||
</el-col>
|
||||
<el-col :span="5">
|
||||
<span style="display: inline-block" class="mt5">keys:{{ state.dbsize }}</span>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-scrollbar
|
||||
:style="{
|
||||
maxHeight: state.keyTreeHeight,
|
||||
height: state.keyTreeHeight,
|
||||
backgroundColor: 'var(--el-fill-color-blank)',
|
||||
border: '1px solid var(--el-border-color-light, #ebeef5)',
|
||||
}"
|
||||
>
|
||||
<el-tree
|
||||
ref="keyTreeRef"
|
||||
:highlight-current="true"
|
||||
@@ -130,7 +130,7 @@
|
||||
</Pane>
|
||||
|
||||
<Pane min-size="40">
|
||||
<div class="">
|
||||
<div class="key-detail card pd5">
|
||||
<el-tabs @tab-remove="removeDataTab" v-model="state.activeName">
|
||||
<el-tab-pane closable v-for="dt in state.dataTabs" :key="dt.key" :label="dt.label" :name="dt.key">
|
||||
<key-detail :redisId="scanParam.id" :db="scanParam.db" :key-info="dt.keyInfo" @change-key="searchKey()" @del-key="delKey" />
|
||||
@@ -178,10 +178,9 @@ import { TagTreeNode, NodeType } from '../component/tag';
|
||||
import TagTree from '../component/TagTree.vue';
|
||||
import { keysToTree, sortByTreeNodes, keysToList } from './utils';
|
||||
import { Contextmenu, ContextmenuItem } from '@/components/contextmenu';
|
||||
import { sleep } from '../../../common/utils/loading';
|
||||
import { sleep } from '@/common/utils/loading';
|
||||
import { TagResourceTypeEnum } from '@/common/commonEnum';
|
||||
import { Splitpanes, Pane } from 'splitpanes';
|
||||
import { useEventListener } from '@vueuse/core';
|
||||
|
||||
const KeyDetail = defineAsyncComponent(() => import('./KeyDetail.vue'));
|
||||
|
||||
@@ -316,15 +315,7 @@ const state = reactive({
|
||||
|
||||
const { scanParam, keyTreeData, newKeyDialog } = toRefs(state);
|
||||
|
||||
onMounted(async () => {
|
||||
setHeight();
|
||||
// 监听浏览器窗口大小变化,更新对应组件高度
|
||||
useEventListener(window, 'resize', setHeight);
|
||||
});
|
||||
|
||||
const setHeight = () => {
|
||||
state.keyTreeHeight = window.innerHeight - 165 + 'px';
|
||||
};
|
||||
onMounted(async () => {});
|
||||
|
||||
const scan = async (appendKey = false) => {
|
||||
isTrue(state.scanParam.id != null, '请先选择redis');
|
||||
@@ -581,24 +572,27 @@ const delKey = (key: string) => {
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.key-list-vtree {
|
||||
height: 100%;
|
||||
}
|
||||
.redis-data-op {
|
||||
.key-list-vtree,
|
||||
.key-detail {
|
||||
height: calc(100vh - 108px);
|
||||
}
|
||||
|
||||
.key-list-vtree .folder-label {
|
||||
font-weight: bold;
|
||||
}
|
||||
.key-list-vtree .folder-label {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.key-list-vtree .key-label {
|
||||
color: #67c23a;
|
||||
}
|
||||
.key-list-vtree .key-label {
|
||||
color: #67c23a;
|
||||
}
|
||||
|
||||
.key-list-vtree .key-list-custom-node {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
/*note the following 2 items should be same value, may not consist with itemSize*/
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
.key-list-vtree .key-list-custom-node {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
/*note the following 2 items should be same value, may not consist with itemSize*/
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -107,10 +107,10 @@ defineExpose({ getContent });
|
||||
|
||||
.format-viewer-container .el-textarea textarea {
|
||||
font-size: 14px;
|
||||
height: calc(100vh - 536px + v-bind(height));
|
||||
height: calc(100vh - 546px + v-bind(height));
|
||||
}
|
||||
|
||||
.format-viewer-container .monaco-editor-content {
|
||||
height: calc(100vh - 550px + v-bind(height)) !important;
|
||||
height: calc(100vh - 560px + v-bind(height)) !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
<template>
|
||||
<div class="menu">
|
||||
<div class="toolbar">
|
||||
<el-input v-model="filterTag" placeholder="输入关键字过滤(右击进行操作)" style="width: 220px; margin-right: 10px" />
|
||||
<el-button v-auth="'tag:save'" type="primary" icon="plus" @click="showSaveTagDialog(null)">添加</el-button>
|
||||
<div class="tag-tree-list card">
|
||||
<div class="card pd10">
|
||||
<el-input v-model="filterTag" clearable placeholder="输入关键字过滤(右击进行操作)" style="width: 220px; margin-right: 10px" />
|
||||
<el-button v-if="useUserInfo().userInfo.username == 'admin'" v-auth="'tag:save'" type="primary" icon="plus" @click="showSaveTagDialog(null)"
|
||||
>添加</el-button
|
||||
>
|
||||
<div style="float: right">
|
||||
<el-tooltip placement="top">
|
||||
<template #content>
|
||||
@@ -17,33 +19,34 @@
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
<el-tree
|
||||
ref="tagTreeRef"
|
||||
class="none-select"
|
||||
:indent="38"
|
||||
node-key="id"
|
||||
:props="props"
|
||||
:data="data"
|
||||
@node-expand="handleNodeExpand"
|
||||
@node-collapse="handleNodeCollapse"
|
||||
@node-contextmenu="nodeContextmenu"
|
||||
@node-click="treeNodeClick"
|
||||
:default-expanded-keys="defaultExpandedKeys"
|
||||
:expand-on-click-node="true"
|
||||
:filter-node-method="filterNode"
|
||||
>
|
||||
<template #default="{ data }">
|
||||
<span class="custom-tree-node">
|
||||
<span style="font-size: 13px">
|
||||
{{ data.code }}
|
||||
<span style="color: #3c8dbc">【</span>
|
||||
{{ data.name }}
|
||||
<span style="color: #3c8dbc">】</span>
|
||||
<el-tag v-if="data.children !== null" size="small">{{ data.children.length }}</el-tag>
|
||||
<el-scrollbar class="tag-tree-data">
|
||||
<el-tree
|
||||
ref="tagTreeRef"
|
||||
class="none-select"
|
||||
node-key="id"
|
||||
:props="props"
|
||||
:data="data"
|
||||
@node-expand="handleNodeExpand"
|
||||
@node-collapse="handleNodeCollapse"
|
||||
@node-contextmenu="nodeContextmenu"
|
||||
@node-click="treeNodeClick"
|
||||
:default-expanded-keys="defaultExpandedKeys"
|
||||
:expand-on-click-node="true"
|
||||
:filter-node-method="filterNode"
|
||||
>
|
||||
<template #default="{ data }">
|
||||
<span class="custom-tree-node">
|
||||
<span style="font-size: 13px">
|
||||
{{ data.code }}
|
||||
<span style="color: #3c8dbc">【</span>
|
||||
{{ data.name }}
|
||||
<span style="color: #3c8dbc">】</span>
|
||||
<el-tag v-if="data.children !== null" size="small">{{ data.children.length }}</el-tag>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</template>
|
||||
</el-tree>
|
||||
</el-scrollbar>
|
||||
|
||||
<el-dialog width="500px" :title="saveTabDialog.title" :before-close="cancelSaveTag" v-model="saveTabDialog.visible">
|
||||
<el-form ref="tagForm" :rules="rules" :model="saveTabDialog.form" label-width="auto">
|
||||
@@ -113,6 +116,7 @@ import { TagResourceTypeEnum } from '../../../common/commonEnum';
|
||||
import EnumValue from '@/common/Enum';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { hasPerm } from '@/components/auth/auth';
|
||||
import { useUserInfo } from '@/store/userInfo';
|
||||
|
||||
interface Tree {
|
||||
id: number;
|
||||
@@ -390,12 +394,14 @@ const removeDeafultExpandId = (id: any) => {
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.menu {
|
||||
height: 100%;
|
||||
.tag-tree-list {
|
||||
.tag-tree-data {
|
||||
height: calc(100vh - 200px);
|
||||
|
||||
.el-tree-node__content {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
.el-tree-node__content {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="account-dialog">
|
||||
<el-dialog :title="account == null ? '' : '分配“' + account.username + '”的角色'" v-model="dialogVisible" :before-close="cancel" :show-close="false">
|
||||
<div class="toolbar">
|
||||
<div style="float: left">
|
||||
<div class="card pd5">
|
||||
<div>
|
||||
<el-input placeholder="请输入角色名" style="width: 150px" v-model="query.name" @clear="clear()" clearable> </el-input>
|
||||
<el-button class="ml5" @click="search" type="success" icon="search"></el-button>
|
||||
</div>
|
||||
@@ -17,15 +17,17 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<el-pagination
|
||||
@current-change="handlePageChange"
|
||||
style="text-align: center; margin-top: 20px"
|
||||
background
|
||||
layout="prev, pager, next, total, jumper"
|
||||
:total="total"
|
||||
v-model:current-page="query.pageNum"
|
||||
:page-size="query.pageSize"
|
||||
></el-pagination>
|
||||
<el-row type="flex" justify="end">
|
||||
<el-pagination
|
||||
@current-change="handlePageChange"
|
||||
style="text-align: center; margin-top: 20px"
|
||||
background
|
||||
layout="prev, pager, next, total, jumper"
|
||||
:total="total"
|
||||
v-model:current-page="query.pageNum"
|
||||
:page-size="query.pageSize"
|
||||
></el-pagination>
|
||||
</el-row>
|
||||
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
|
||||
@@ -1,44 +1,52 @@
|
||||
<template>
|
||||
<div class="menu">
|
||||
<div class="toolbar">
|
||||
<div class="card system-resouce-list">
|
||||
<div class="card pd10 flex-justify-between">
|
||||
<div>
|
||||
<span style="font-size: 14px"> <SvgIcon name="info-filled" />红色、橙色字体表示禁用状态 (右击资源进行操作) </span>
|
||||
<el-input v-model="filterResource" clearable placeholder="输入关键字过滤(右击进行操作)" style="width: 220px; margin-right: 10px" />
|
||||
<el-button v-auth="perms.addResource" type="primary" icon="plus" @click="addResource(false)">添加</el-button>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span> <SvgIcon name="info-filled" />红色、橙色字体表示禁用状态 (右击资源进行操作) </span>
|
||||
</div>
|
||||
<el-button v-auth="perms.addResource" 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"
|
||||
@node-contextmenu="nodeContextmenu"
|
||||
@node-click="treeNodeClick"
|
||||
:default-expanded-keys="defaultExpandedKeys"
|
||||
:expand-on-click-node="true"
|
||||
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>
|
||||
<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>
|
||||
<el-scrollbar class="tree-data">
|
||||
<el-tree
|
||||
ref="resourceTreeRef"
|
||||
class="none-select"
|
||||
:indent="38"
|
||||
node-key="id"
|
||||
:props="props"
|
||||
:data="data"
|
||||
@node-expand="handleNodeExpand"
|
||||
@node-collapse="handleNodeCollapse"
|
||||
@node-contextmenu="nodeContextmenu"
|
||||
@node-click="treeNodeClick"
|
||||
:default-expanded-keys="defaultExpandedKeys"
|
||||
:expand-on-click-node="true"
|
||||
draggable
|
||||
:allow-drop="allowDrop"
|
||||
@node-drop="handleDrop"
|
||||
:filter-node-method="filterNode"
|
||||
>
|
||||
<template #default="{ data }">
|
||||
<span class="custom-tree-node">
|
||||
<span style="font-size: 13px" v-if="data.type === menuTypeValue">
|
||||
<span style="color: #3c8dbc">【</span>
|
||||
<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>
|
||||
<span style="font-size: 13px" v-if="data.type === permissionTypeValue">
|
||||
<span style="color: #3c8dbc">【</span>
|
||||
<span :style="data.status == 1 ? 'color: #67c23a;' : 'color: #f67c6c;'">{{ data.name }}</span>
|
||||
<span style="color: #3c8dbc">】</span>
|
||||
</span>
|
||||
</span>
|
||||
<span style="font-size: 13px" v-if="data.type === permissionTypeValue">
|
||||
<span style="color: #3c8dbc">【</span>
|
||||
<span :style="data.status == 1 ? 'color: #67c23a;' : 'color: #f67c6c;'">{{ data.name }}</span>
|
||||
<span style="color: #3c8dbc">】</span>
|
||||
</span>
|
||||
</span>
|
||||
</template>
|
||||
</el-tree>
|
||||
</template>
|
||||
</el-tree>
|
||||
</el-scrollbar>
|
||||
|
||||
<ResourceEdit
|
||||
:title="dialogForm.title"
|
||||
@@ -94,7 +102,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref, toRefs, reactive, onMounted } from 'vue';
|
||||
import { ref, toRefs, reactive, onMounted, watch } from 'vue';
|
||||
import { ElMessage, ElMessageBox } from 'element-plus';
|
||||
import ResourceEdit from './ResourceEdit.vue';
|
||||
import { ResourceTypeEnum } from '../enums';
|
||||
@@ -119,6 +127,8 @@ const props = {
|
||||
};
|
||||
|
||||
const contextmenuRef = ref();
|
||||
const filterResource = ref();
|
||||
const resourceTreeRef = ref();
|
||||
|
||||
const contextmenuInfo = new ContextmenuItem('info', '详情').withIcon('View').withOnClick((data: any) => info(data));
|
||||
|
||||
@@ -195,6 +205,17 @@ onMounted(() => {
|
||||
search();
|
||||
});
|
||||
|
||||
watch(filterResource, (val) => {
|
||||
resourceTreeRef.value!.filter(val);
|
||||
});
|
||||
|
||||
const filterNode = (value: string, data: any) => {
|
||||
if (!value) {
|
||||
return true;
|
||||
}
|
||||
return data.name.includes(value);
|
||||
};
|
||||
|
||||
const search = async () => {
|
||||
let res = await resourceApi.list.request(null);
|
||||
state.data = res;
|
||||
@@ -380,11 +401,15 @@ const info = async (data: any) => {
|
||||
};
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.menu {
|
||||
.system-resouce-list {
|
||||
.el-tree-node__content {
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
}
|
||||
|
||||
.tree-data {
|
||||
height: calc(100vh - 200px);
|
||||
}
|
||||
}
|
||||
|
||||
.none-select {
|
||||
|
||||
@@ -18,7 +18,7 @@ require (
|
||||
github.com/gorilla/websocket v1.5.1
|
||||
github.com/kanzihuang/vitess/go/vt/sqlparser v0.0.0-20231018071450-ac8d9f0167e9
|
||||
github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20230712084735-068dc2aee82d
|
||||
github.com/mojocn/base64Captcha v1.3.5 // 验证码
|
||||
github.com/mojocn/base64Captcha v1.3.6 // 验证码
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/pkg/sftp v1.13.6
|
||||
github.com/pquerna/otp v1.4.0
|
||||
@@ -78,7 +78,7 @@ require (
|
||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230519143937-03e91628a987
|
||||
golang.org/x/image v0.0.0-20220302094943-723b81ca9867 // indirect
|
||||
golang.org/x/image v0.13.0 // indirect
|
||||
golang.org/x/net v0.18.0 // indirect
|
||||
golang.org/x/sync v0.1.0 // indirect
|
||||
golang.org/x/sys v0.15.0 // indirect
|
||||
|
||||
@@ -88,9 +88,12 @@ func (p *tagTreeAppImpl) Save(ctx context.Context, tag *entity.TagTree) error {
|
||||
|
||||
tag.CodePath = parentTag.CodePath + tag.Code + entity.CodePathSeparator
|
||||
} else {
|
||||
if accountId != consts.AdminId {
|
||||
return errorx.NewBiz("非管理员无法添加根标签")
|
||||
}
|
||||
tag.CodePath = tag.Code + entity.CodePathSeparator
|
||||
}
|
||||
if err := p.CanAccess(accountId, tag.CodePath); err != nil {
|
||||
if p.CanAccess(accountId, tag.CodePath) != nil {
|
||||
return errorx.NewBiz("无权添加该标签")
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,8 @@ func Generate() (string, string, error) {
|
||||
|
||||
c := base64Captcha.NewCaptcha(driver, store)
|
||||
// 获取
|
||||
return c.Generate()
|
||||
id, b64s, _, err := c.Generate()
|
||||
return id, b64s, err
|
||||
}
|
||||
|
||||
// 验证验证码
|
||||
|
||||
Reference in New Issue
Block a user