refactor: 样式调整

This commit is contained in:
meilin.huang
2023-12-14 13:05:21 +08:00
parent 5c72b1de57
commit 18cf2e54c4
17 changed files with 391 additions and 337 deletions

View File

@@ -2,7 +2,7 @@
<div> <div>
<transition name="el-zoom-in-top"> <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 透传给子组件 --> <!-- 遍历父组件传入的 solts 透传给子组件 -->
<template v-for="(_, key) in useSlots()" v-slot:[key]> <template v-for="(_, key) in useSlots()" v-slot:[key]>
<slot :name="key"></slot> <slot :name="key"></slot>
@@ -10,7 +10,7 @@
</SearchForm> </SearchForm>
</transition> </transition>
<el-card> <div class="card">
<div class="table-main"> <div class="table-main">
<!-- 表格头部 操作按钮 --> <!-- 表格头部 操作按钮 -->
<div class="table-header"> <div class="table-header">
@@ -121,7 +121,7 @@
:page-sizes="pageSizes" :page-sizes="pageSizes"
/> />
</el-row> </el-row>
</el-card> </div>
</div> </div>
</template> </template>

View File

@@ -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% /* 宽高 100%
------------------------------- */ ------------------------------- */
.w100 { .w100 {
@@ -276,6 +288,10 @@ body,
.pl#{$i} { .pl#{$i} {
padding-left: #{$i}px !important; padding-left: #{$i}px !important;
} }
.pd#{$i} {
padding: #{$i}px !important;
}
} }
@@ -335,12 +351,15 @@ body,
user-select: none; user-select: none;
} }
.toolbar { /* custom card */
width: 100%; .card {
padding: 4px; box-sizing: border-box;
overflow: hidden; padding: 20px;
line-height: 24px; overflow-x: hidden;
border: 1px solid var(--el-border-color-light, #ebeef5); 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 { .fl {
@@ -361,10 +380,6 @@ body,
z-index: inherit !important; z-index: inherit !important;
} }
.f12 {
font-size: 12px
}
.pointer { .pointer {
cursor: pointer; cursor: pointer;
} }
@@ -396,6 +411,7 @@ body,
.default-theme.splitpanes--horizontal>.splitpanes__splitter { .default-theme.splitpanes--horizontal>.splitpanes__splitter {
border-top: 1px solid var(--bg-main-color); border-top: 1px solid var(--bg-main-color);
} }
// 竖线样式 // 竖线样式
.splitpanes.default-theme .splitpanes__splitter::before, .splitpanes.default-theme .splitpanes__splitter::before,
.splitpanes.default-theme .splitpanes__splitter::after { .splitpanes.default-theme .splitpanes__splitter::after {

View File

@@ -1,7 +1,7 @@
<template> <template>
<div class="tag-tree"> <div class="tag-tree card pd5">
<el-input v-model="filterText" placeholder="输入关键字->搜索已展开节点信息" clearable size="small" class="mb5" /> <el-scrollbar>
<el-scrollbar :style="{ height: state.height, maxHeight: state.height, backgroundColor: 'var(--el-fill-color-blank)' }"> <el-input v-model="filterText" placeholder="输入关键字->搜索已展开节点信息" clearable size="small" class="mb5 w100" />
<el-tree <el-tree
ref="treeRef" ref="treeRef"
:highlight-current="true" :highlight-current="true"
@@ -32,8 +32,9 @@
</span> </span>
</template> </template>
</el-tree> </el-tree>
</el-scrollbar>
<contextmenu :dropdown="state.dropdown" :items="state.contextmenuItems" ref="contextmenuRef" @currentContextmenuClick="onCurrentContextmenuClick" /> <contextmenu :dropdown="state.dropdown" :items="state.contextmenuItems" ref="contextmenuRef" @currentContextmenuClick="onCurrentContextmenuClick" />
</el-scrollbar>
</div> </div>
</template> </template>
@@ -43,7 +44,6 @@ import { NodeType, TagTreeNode } from './tag';
import TagInfo from './TagInfo.vue'; import TagInfo from './TagInfo.vue';
import { Contextmenu } from '@/components/contextmenu'; import { Contextmenu } from '@/components/contextmenu';
import { tagApi } from '../tag/api'; import { tagApi } from '../tag/api';
import { useEventListener, useWindowSize } from '@vueuse/core';
const props = defineProps({ const props = defineProps({
resourceType: { resourceType: {
@@ -74,8 +74,6 @@ const emit = defineEmits(['nodeClick', 'currentContextmenuClick']);
const treeRef: any = ref(null); const treeRef: any = ref(null);
const contextmenuRef = ref(); const contextmenuRef = ref();
const { height: vh } = useWindowSize();
const state = reactive({ const state = reactive({
height: 600 as any, height: 600 as any,
filterText: '', filterText: '',
@@ -88,14 +86,7 @@ const state = reactive({
}); });
const { filterText } = toRefs(state); const { filterText } = toRefs(state);
onMounted(async () => { onMounted(async () => {});
setHeight();
useEventListener(window, 'resize', setHeight);
});
const setHeight = () => {
state.height = vh.value - 138 + 'px';
};
watch(filterText, (val) => { watch(filterText, (val) => {
treeRef.value?.filter(val); treeRef.value?.filter(val);
@@ -195,8 +186,7 @@ defineExpose({
<style lang="scss" scoped> <style lang="scss" scoped>
.tag-tree { .tag-tree {
border-radius: var(--el-input-border-radius, var(--el-border-radius-base)); height: calc(100vh - 108px);
border: 1px solid var(--el-border-color-light, #ebeef5);
.el-tree { .el-tree {
display: inline-block; display: inline-block;

View File

@@ -21,7 +21,7 @@
</el-col> </el-col>
<el-col style="text-align: center" :span="1">:</el-col> <el-col style="text-align: center" :span="1">:</el-col>
<el-col :span="5"> <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-col>
</el-form-item> </el-form-item>
<el-form-item prop="username" label="用户名" required> <el-form-item prop="username" label="用户名" required>
@@ -49,7 +49,7 @@
<el-tab-pane label="其他配置" name="other"> <el-tab-pane label="其他配置" name="other">
<el-form-item prop="params" label="连接参数"> <el-form-item prop="params" label="连接参数">
<el-input v-model.trim="form.params" placeholder="其他连接参数,形如: key1=value1&key2=value2"> <el-input v-model.trim="form.params" placeholder="其他连接参数,形如: key1=value1&key2=value2">
<template #suffix> <!-- <template #suffix>
<el-link <el-link
target="_blank" target="_blank"
href="https://github.com/go-sql-driver/mysql#parameters" href="https://github.com/go-sql-driver/mysql#parameters"
@@ -58,7 +58,7 @@
class="mr5" class="mr5"
>参数参考</el-link >参数参考</el-link
> >
</template> </template> -->
</el-input> </el-input>
</el-form-item> </el-form-item>

View File

@@ -47,9 +47,10 @@
</Pane> </Pane>
<Pane> <Pane>
<div class="card db-op pd5">
<el-row> <el-row>
<el-col :span="24" v-if="state.db"> <el-col :span="24" v-if="state.db">
<el-descriptions :column="4" size="small" border class="ml5"> <el-descriptions :column="4" size="small" border>
<el-descriptions-item label-align="right" label="操作" <el-descriptions-item label-align="right" label="操作"
><el-button ><el-button
:disabled="!state.db || !nowDbInst.id" :disabled="!state.db || !nowDbInst.id"
@@ -82,7 +83,7 @@
</el-col> </el-col>
</el-row> </el-row>
<div id="data-exec" class="mt5 ml5"> <div id="data-exec" class="mt5">
<el-tabs <el-tabs
v-if="state.tabs.size > 0" v-if="state.tabs.size > 0"
type="card" type="card"
@@ -143,6 +144,7 @@
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</div> </div>
</div>
</Pane> </Pane>
</Splitpanes> </Splitpanes>
</div> </div>
@@ -397,8 +399,8 @@ onBeforeUnmount(() => {
* 设置editor高度和数据表高度 * 设置editor高度和数据表高度
*/ */
const setHeight = () => { const setHeight = () => {
state.dataTabsTableHeight = window.innerHeight - 255 + 'px'; state.dataTabsTableHeight = window.innerHeight - 270 + 'px';
state.tablesOpHeight = window.innerHeight - 212 + 'px'; state.tablesOpHeight = window.innerHeight - 225 + 'px';
}; };
// 选择数据库,改变当前正在操作的数据库信息 // 选择数据库,改变当前正在操作的数据库信息
@@ -607,6 +609,10 @@ const getNowDbInfo = () => {
font-size: 9px; font-size: 9px;
} }
.db-op {
height: calc(100vh - 108px);
}
#data-exec { #data-exec {
.el-tabs { .el-tabs {
--el-tabs-header-height: 30px; --el-tabs-header-height: 30px;

View File

@@ -1,8 +1,8 @@
<template> <template>
<div> <div>
<div> <div>
<div class="toolbar"> <div class="card pd5 flex-justify-between">
<div class="fl"> <div>
<el-link @click="onRunSql()" :underline="false" class="ml15" icon="VideoPlay"> </el-link> <el-link @click="onRunSql()" :underline="false" class="ml15" icon="VideoPlay"> </el-link>
<el-divider direction="vertical" border-style="dashed" /> <el-divider direction="vertical" border-style="dashed" />
@@ -33,7 +33,7 @@
</el-upload> </el-upload>
</div> </div>
<div class="fr"> <div>
<el-button @click="saveSql()" type="primary" icon="document-add" plain size="small">保存SQL</el-button> <el-button @click="saveSql()" type="primary" icon="document-add" plain size="small">保存SQL</el-button>
</div> </div>
</div> </div>
@@ -44,7 +44,7 @@
@resize="resizeTableHeight" @resize="resizeTableHeight"
horizontal horizontal
class="default-theme" class="default-theme"
style="height: calc(100vh - 220px)" style="height: calc(100vh - 233px)"
> >
<Pane :size="state.editorSize" max-size="80"> <Pane :size="state.editorSize" max-size="80">
<MonacoEditor ref="monacoEditorRef" class="mt5" v-model="state.sql" language="sql" height="100%" :id="'MonacoTextarea-' + getKey()" /> <MonacoEditor ref="monacoEditorRef" class="mt5" v-model="state.sql" language="sql" height="100%" :id="'MonacoTextarea-' + getKey()" />
@@ -128,7 +128,7 @@
</template> </template>
<script lang="ts" setup> <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 { getToken } from '@/common/utils/storage';
import { notBlank } from '@/common/assert'; import { notBlank } from '@/common/assert';
import { format as sqlFormatter } from 'sql-formatter'; import { format as sqlFormatter } from 'sql-formatter';
@@ -276,7 +276,7 @@ const onRemoveTab = (targetId: number) => {
const resizeTableHeight = (e: any) => { const resizeTableHeight = (e: any) => {
const vh = window.innerHeight; const vh = window.innerHeight;
state.editorSize = e[0].size; state.editorSize = e[0].size;
const plitpaneHeight = vh - 210; const plitpaneHeight = vh - 223;
const editorHeight = plitpaneHeight * (state.editorSize / 100); const editorHeight = plitpaneHeight * (state.editorSize / 100);
state.tableDataHeight = plitpaneHeight - editorHeight - 40 + 'px'; state.tableDataHeight = plitpaneHeight - editorHeight - 40 + 'px';
}; };
@@ -336,7 +336,7 @@ const onRunSql = async (newTab = false) => {
// 不是新建tab执行则在当前激活的tab上执行sql // 不是新建tab执行则在当前激活的tab上执行sql
i = state.execResTabs.findIndex((x) => x.id == state.activeTab); i = state.execResTabs.findIndex((x) => x.id == state.activeTab);
execRes = state.execResTabs[i]; execRes = state.execResTabs[i];
if (execRes.loading?.value) { if (unref(execRes.loading)) {
ElMessage.error('当前结果集tab正在执行, 请使用新标签执行'); ElMessage.error('当前结果集tab正在执行, 请使用新标签执行');
return; return;
} }

View File

@@ -47,11 +47,11 @@
<el-divider direction="vertical" border-style="dashed" /> <el-divider direction="vertical" border-style="dashed" />
<el-tooltip :show-after="500" v-if="hasUpdatedFileds" class="box-item" effect="dark" content="提交修改" placement="top"> <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-tooltip>
<el-divider v-if="hasUpdatedFileds" direction="vertical" border-style="dashed" /> <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-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> </el-tooltip>
</div> </div>
</el-col> </el-col>

View File

@@ -1,19 +1,19 @@
<template> <template>
<div class="file-manage"> <div class="file-manage">
<el-dialog title="进程信息" v-model="dialogVisible" :destroy-on-close="true" :show-close="true" :before-close="handleClose" width="65%"> <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-row>
<el-col :span="4"> <el-col :span="4">
<el-input size="small" placeholder="进程名" v-model="params.name" plain clearable></el-input> <el-input size="small" placeholder="进程名" v-model="params.name" plain clearable></el-input>
</el-col> </el-col>
<el-col :span="4" class="ml5"> <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="cpu降序" value="1"> </el-option>
<el-option key="cpu" label="mem降序" value="2"> </el-option> <el-option key="cpu" label="mem降序" value="2"> </el-option>
</el-select> </el-select>
</el-col> </el-col>
<el-col :span="4" class="ml5"> <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="10" label="10" value="10"> </el-option>
<el-option key="15" label="15" value="15"> </el-option> <el-option key="15" label="15" value="15"> </el-option>
<el-option key="20" label="20" value="20"> </el-option> <el-option key="20" label="20" value="20"> </el-option>

View File

@@ -44,9 +44,9 @@
</Pane> </Pane>
<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-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-align="right" label="tag">xxx</el-descriptions-item> -->
<el-descriptions-item label="ns" label-align="right"> <el-descriptions-item label="ns" label-align="right">
@@ -74,7 +74,7 @@
</el-row> </el-row>
<el-row type="flex"> <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-tab-pane closable v-for="dt in state.dataTabs" :key="dt.key" :label="dt.label" :name="dt.key">
<el-row> <el-row>
<el-col :span="2"> <el-col :span="2">
@@ -96,7 +96,8 @@
</el-input> </el-input>
</el-col> </el-col>
</el-row> </el-row>
<el-row :style="`height: ${dataHeight}; overflow: auto;`"> <el-scrollbar class="mongo-data-tab-data">
<el-row>
<el-col :span="6" v-for="item in dt.datas" :key="item"> <el-col :span="6" v-for="item in dt.datas" :key="item">
<el-card :body-style="{ padding: '0px', position: 'relative' }"> <el-card :body-style="{ padding: '0px', position: 'relative' }">
<el-input type="textarea" v-model="item.value" :rows="10" /> <el-input type="textarea" v-model="item.value" :rows="10" />
@@ -117,6 +118,7 @@
</el-card> </el-card>
</el-col> </el-col>
</el-row> </el-row>
</el-scrollbar>
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</el-row> </el-row>
@@ -253,7 +255,6 @@ const NodeTypeColl = new NodeType(MongoNodeType.Coll).withNodeClickFunc((nodeDat
const findParamInputRef: any = ref(null); const findParamInputRef: any = ref(null);
const state = reactive({ const state = reactive({
tags: [], tags: [],
dataHeight: `${window.innerHeight - 220}px`,
mongoList: [] as any, mongoList: [] as any,
activeName: '', // 当前操作的tab activeName: '', // 当前操作的tab
dataTabs: {} as any, // 数据tabs 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(() => { const nowColl = computed(() => {
return getNowDataTab(); return getNowDataTab();
@@ -506,7 +507,17 @@ const getNowDataTab = () => {
max-width: 120px; 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 { .el-tabs__header {
margin: 0 0 5px; margin: 0 0 5px;

View File

@@ -1,5 +1,5 @@
<template> <template>
<div> <div class="redis-data-op">
<Splitpanes class="default-theme"> <Splitpanes class="default-theme">
<Pane size="20" max-size="30"> <Pane size="20" max-size="30">
<tag-tree :resource-type="TagResourceTypeEnum.Redis.value" :tag-path-node-type="NodeTypeTagPath"> <tag-tree :resource-type="TagResourceTypeEnum.Redis.value" :tag-path-node-type="NodeTypeTagPath">
@@ -34,7 +34,8 @@
</Pane> </Pane>
<Pane min-size="20" size="30"> <Pane min-size="20" size="30">
<div class="key-list-vtree"> <div class="key-list-vtree card pd5">
<el-scrollbar>
<el-row> <el-row>
<el-col :span="2"> <el-col :span="2">
<el-input v-model="state.keySeparator" placeholder="分割符" size="small" class="ml5" /> <el-input v-model="state.keySeparator" placeholder="分割符" size="small" class="ml5" />
@@ -57,7 +58,14 @@
<el-row class="mb5 mt5"> <el-row class="mb5 mt5">
<el-col :span="19"> <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
class="ml5"
:disabled="!scanParam.id || !scanParam.db"
@click="scan(true)"
type="success"
icon="more"
size="small"
plain
>加载更多</el-button >加载更多</el-button
> >
@@ -88,14 +96,6 @@
</el-col> </el-col>
</el-row> </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 <el-tree
ref="keyTreeRef" ref="keyTreeRef"
:highlight-current="true" :highlight-current="true"
@@ -130,7 +130,7 @@
</Pane> </Pane>
<Pane min-size="40"> <Pane min-size="40">
<div class=""> <div class="key-detail card pd5">
<el-tabs @tab-remove="removeDataTab" v-model="state.activeName"> <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"> <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" /> <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 TagTree from '../component/TagTree.vue';
import { keysToTree, sortByTreeNodes, keysToList } from './utils'; import { keysToTree, sortByTreeNodes, keysToList } from './utils';
import { Contextmenu, ContextmenuItem } from '@/components/contextmenu'; import { Contextmenu, ContextmenuItem } from '@/components/contextmenu';
import { sleep } from '../../../common/utils/loading'; import { sleep } from '@/common/utils/loading';
import { TagResourceTypeEnum } from '@/common/commonEnum'; import { TagResourceTypeEnum } from '@/common/commonEnum';
import { Splitpanes, Pane } from 'splitpanes'; import { Splitpanes, Pane } from 'splitpanes';
import { useEventListener } from '@vueuse/core';
const KeyDetail = defineAsyncComponent(() => import('./KeyDetail.vue')); const KeyDetail = defineAsyncComponent(() => import('./KeyDetail.vue'));
@@ -316,15 +315,7 @@ const state = reactive({
const { scanParam, keyTreeData, newKeyDialog } = toRefs(state); const { scanParam, keyTreeData, newKeyDialog } = toRefs(state);
onMounted(async () => { onMounted(async () => {});
setHeight();
// 监听浏览器窗口大小变化,更新对应组件高度
useEventListener(window, 'resize', setHeight);
});
const setHeight = () => {
state.keyTreeHeight = window.innerHeight - 165 + 'px';
};
const scan = async (appendKey = false) => { const scan = async (appendKey = false) => {
isTrue(state.scanParam.id != null, '请先选择redis'); isTrue(state.scanParam.id != null, '请先选择redis');
@@ -581,8 +572,10 @@ const delKey = (key: string) => {
</script> </script>
<style lang="scss"> <style lang="scss">
.key-list-vtree { .redis-data-op {
height: 100%; .key-list-vtree,
.key-detail {
height: calc(100vh - 108px);
} }
.key-list-vtree .folder-label { .key-list-vtree .folder-label {
@@ -601,4 +594,5 @@ const delKey = (key: string) => {
height: 22px; height: 22px;
line-height: 22px; line-height: 22px;
} }
}
</style> </style>

View File

@@ -107,10 +107,10 @@ defineExpose({ getContent });
.format-viewer-container .el-textarea textarea { .format-viewer-container .el-textarea textarea {
font-size: 14px; font-size: 14px;
height: calc(100vh - 536px + v-bind(height)); height: calc(100vh - 546px + v-bind(height));
} }
.format-viewer-container .monaco-editor-content { .format-viewer-container .monaco-editor-content {
height: calc(100vh - 550px + v-bind(height)) !important; height: calc(100vh - 560px + v-bind(height)) !important;
} }
</style> </style>

View File

@@ -1,8 +1,10 @@
<template> <template>
<div class="menu"> <div class="tag-tree-list card">
<div class="toolbar"> <div class="card pd10">
<el-input v-model="filterTag" placeholder="输入关键字过滤(右击进行操作)" style="width: 220px; margin-right: 10px" /> <el-input v-model="filterTag" clearable placeholder="输入关键字过滤(右击进行操作)" style="width: 220px; margin-right: 10px" />
<el-button v-auth="'tag:save'" type="primary" icon="plus" @click="showSaveTagDialog(null)">添加</el-button> <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"> <div style="float: right">
<el-tooltip placement="top"> <el-tooltip placement="top">
<template #content> <template #content>
@@ -17,10 +19,10 @@
</el-tooltip> </el-tooltip>
</div> </div>
</div> </div>
<el-scrollbar class="tag-tree-data">
<el-tree <el-tree
ref="tagTreeRef" ref="tagTreeRef"
class="none-select" class="none-select"
:indent="38"
node-key="id" node-key="id"
:props="props" :props="props"
:data="data" :data="data"
@@ -44,6 +46,7 @@
</span> </span>
</template> </template>
</el-tree> </el-tree>
</el-scrollbar>
<el-dialog width="500px" :title="saveTabDialog.title" :before-close="cancelSaveTag" v-model="saveTabDialog.visible"> <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"> <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 EnumValue from '@/common/Enum';
import { useRouter } from 'vue-router'; import { useRouter } from 'vue-router';
import { hasPerm } from '@/components/auth/auth'; import { hasPerm } from '@/components/auth/auth';
import { useUserInfo } from '@/store/userInfo';
interface Tree { interface Tree {
id: number; id: number;
@@ -390,14 +394,16 @@ const removeDeafultExpandId = (id: any) => {
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
.menu { .tag-tree-list {
height: 100%; .tag-tree-data {
height: calc(100vh - 200px);
.el-tree-node__content { .el-tree-node__content {
height: 40px; height: 40px;
line-height: 40px; line-height: 40px;
} }
} }
}
.none-select { .none-select {
moz-user-select: -moz-none; moz-user-select: -moz-none;

View File

@@ -1,8 +1,8 @@
<template> <template>
<div class="account-dialog"> <div class="account-dialog">
<el-dialog :title="account == null ? '' : '分配“' + account.username + '”的角色'" v-model="dialogVisible" :before-close="cancel" :show-close="false"> <el-dialog :title="account == null ? '' : '分配“' + account.username + '”的角色'" v-model="dialogVisible" :before-close="cancel" :show-close="false">
<div class="toolbar"> <div class="card pd5">
<div style="float: left"> <div>
<el-input placeholder="请输入角色名" style="width: 150px" v-model="query.name" @clear="clear()" clearable> </el-input> <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> <el-button class="ml5" @click="search" type="success" icon="search"></el-button>
</div> </div>
@@ -17,6 +17,7 @@
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
<el-row type="flex" justify="end">
<el-pagination <el-pagination
@current-change="handlePageChange" @current-change="handlePageChange"
style="text-align: center; margin-top: 20px" style="text-align: center; margin-top: 20px"
@@ -26,6 +27,7 @@
v-model:current-page="query.pageNum" v-model:current-page="query.pageNum"
:page-size="query.pageSize" :page-size="query.pageSize"
></el-pagination> ></el-pagination>
</el-row>
<template #footer> <template #footer>
<div class="dialog-footer"> <div class="dialog-footer">

View File

@@ -1,12 +1,18 @@
<template> <template>
<div class="menu"> <div class="card system-resouce-list">
<div class="toolbar"> <div class="card pd10 flex-justify-between">
<div> <div>
<span style="font-size: 14px"> <SvgIcon name="info-filled" />红色橙色字体表示禁用状态 (右击资源进行操作) </span> <el-input v-model="filterResource" clearable placeholder="输入关键字过滤(右击进行操作)" style="width: 220px; margin-right: 10px" />
</div>
<el-button v-auth="perms.addResource" type="primary" icon="plus" @click="addResource(false)">添加</el-button> <el-button v-auth="perms.addResource" type="primary" icon="plus" @click="addResource(false)">添加</el-button>
</div> </div>
<div>
<span> <SvgIcon name="info-filled" />红色橙色字体表示禁用状态 (右击资源进行操作) </span>
</div>
</div>
<el-scrollbar class="tree-data">
<el-tree <el-tree
ref="resourceTreeRef"
class="none-select" class="none-select"
:indent="38" :indent="38"
node-key="id" node-key="id"
@@ -21,6 +27,7 @@
draggable draggable
:allow-drop="allowDrop" :allow-drop="allowDrop"
@node-drop="handleDrop" @node-drop="handleDrop"
:filter-node-method="filterNode"
> >
<template #default="{ data }"> <template #default="{ data }">
<span class="custom-tree-node"> <span class="custom-tree-node">
@@ -39,6 +46,7 @@
</span> </span>
</template> </template>
</el-tree> </el-tree>
</el-scrollbar>
<ResourceEdit <ResourceEdit
:title="dialogForm.title" :title="dialogForm.title"
@@ -94,7 +102,7 @@
</template> </template>
<script lang="ts" setup> <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 { ElMessage, ElMessageBox } from 'element-plus';
import ResourceEdit from './ResourceEdit.vue'; import ResourceEdit from './ResourceEdit.vue';
import { ResourceTypeEnum } from '../enums'; import { ResourceTypeEnum } from '../enums';
@@ -119,6 +127,8 @@ const props = {
}; };
const contextmenuRef = ref(); const contextmenuRef = ref();
const filterResource = ref();
const resourceTreeRef = ref();
const contextmenuInfo = new ContextmenuItem('info', '详情').withIcon('View').withOnClick((data: any) => info(data)); const contextmenuInfo = new ContextmenuItem('info', '详情').withIcon('View').withOnClick((data: any) => info(data));
@@ -195,6 +205,17 @@ onMounted(() => {
search(); 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 () => { const search = async () => {
let res = await resourceApi.list.request(null); let res = await resourceApi.list.request(null);
state.data = res; state.data = res;
@@ -380,11 +401,15 @@ const info = async (data: any) => {
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
.menu { .system-resouce-list {
.el-tree-node__content { .el-tree-node__content {
height: 40px; height: 40px;
line-height: 40px; line-height: 40px;
} }
.tree-data {
height: calc(100vh - 200px);
}
} }
.none-select { .none-select {

View File

@@ -18,7 +18,7 @@ require (
github.com/gorilla/websocket v1.5.1 github.com/gorilla/websocket v1.5.1
github.com/kanzihuang/vitess/go/vt/sqlparser v0.0.0-20231018071450-ac8d9f0167e9 github.com/kanzihuang/vitess/go/vt/sqlparser v0.0.0-20231018071450-ac8d9f0167e9
github.com/lionsoul2014/ip2region/binding/golang v0.0.0-20230712084735-068dc2aee82d 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/errors v0.9.1
github.com/pkg/sftp v1.13.6 github.com/pkg/sftp v1.13.6
github.com/pquerna/otp v1.4.0 github.com/pquerna/otp v1.4.0
@@ -78,7 +78,7 @@ require (
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
golang.org/x/arch v0.3.0 // indirect golang.org/x/arch v0.3.0 // indirect
golang.org/x/exp v0.0.0-20230519143937-03e91628a987 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/net v0.18.0 // indirect
golang.org/x/sync v0.1.0 // indirect golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.15.0 // indirect golang.org/x/sys v0.15.0 // indirect

View File

@@ -88,9 +88,12 @@ func (p *tagTreeAppImpl) Save(ctx context.Context, tag *entity.TagTree) error {
tag.CodePath = parentTag.CodePath + tag.Code + entity.CodePathSeparator tag.CodePath = parentTag.CodePath + tag.Code + entity.CodePathSeparator
} else { } else {
if accountId != consts.AdminId {
return errorx.NewBiz("非管理员无法添加根标签")
}
tag.CodePath = tag.Code + entity.CodePathSeparator 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("无权添加该标签") return errorx.NewBiz("无权添加该标签")
} }

View File

@@ -22,7 +22,8 @@ func Generate() (string, string, error) {
c := base64Captcha.NewCaptcha(driver, store) c := base64Captcha.NewCaptcha(driver, store)
// 获取 // 获取
return c.Generate() id, b64s, _, err := c.Generate()
return id, b64s, err
} }
// 验证验证码 // 验证验证码