mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-04 00:10:25 +08:00
refactor: 样式优化
This commit is contained in:
@@ -10,9 +10,9 @@
|
|||||||
"lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue src/"
|
"lint-fix": "eslint --fix --ext .js --ext .jsx --ext .vue src/"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@element-plus/icons-vue": "^2.3.1",
|
"@element-plus/icons-vue": "^2.3.2",
|
||||||
"@logicflow/core": "^2.0.16",
|
"@logicflow/core": "^2.1.1",
|
||||||
"@logicflow/extension": "^2.0.21",
|
"@logicflow/extension": "^2.1.2",
|
||||||
"@vueuse/core": "^13.6.0",
|
"@vueuse/core": "^13.6.0",
|
||||||
"@xterm/addon-fit": "^0.10.0",
|
"@xterm/addon-fit": "^0.10.0",
|
||||||
"@xterm/addon-search": "^0.15.0",
|
"@xterm/addon-search": "^0.15.0",
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
"crypto-js": "^4.2.0",
|
"crypto-js": "^4.2.0",
|
||||||
"dayjs": "^1.11.13",
|
"dayjs": "^1.11.13",
|
||||||
"echarts": "^6.0.0",
|
"echarts": "^6.0.0",
|
||||||
"element-plus": "^2.10.5",
|
"element-plus": "^2.10.7",
|
||||||
"js-base64": "^3.7.7",
|
"js-base64": "^3.7.7",
|
||||||
"jsencrypt": "^3.3.2",
|
"jsencrypt": "^3.3.2",
|
||||||
"monaco-editor": "^0.52.2",
|
"monaco-editor": "^0.52.2",
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
"eslint-plugin-vue": "^10.4.0",
|
"eslint-plugin-vue": "^10.4.0",
|
||||||
"postcss": "^8.5.6",
|
"postcss": "^8.5.6",
|
||||||
"prettier": "^3.6.1",
|
"prettier": "^3.6.1",
|
||||||
"sass": "^1.89.2",
|
"sass": "^1.90.0",
|
||||||
"tailwindcss": "^4.1.11",
|
"tailwindcss": "^4.1.11",
|
||||||
"typescript": "^5.9.2",
|
"typescript": "^5.9.2",
|
||||||
"vite": "npm:rolldown-vite@latest",
|
"vite": "npm:rolldown-vite@latest",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-main class="layout-main !h-full">
|
<el-main class="layout-main h-full">
|
||||||
<el-scrollbar ref="layoutScrollbarRef" view-class="!h-full">
|
<el-scrollbar ref="layoutScrollbarRef" view-class="h-full">
|
||||||
<LayoutParentView />
|
<LayoutParentView />
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts" name="layoutMain">
|
<script setup lang="ts" name="layoutMain">
|
||||||
import { getCurrentInstance, watch, defineAsyncComponent } from 'vue';
|
import { watch, defineAsyncComponent, useTemplateRef, nextTick, onMounted } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { useThemeConfig } from '@/store/themeConfig';
|
import { useThemeConfig } from '@/store/themeConfig';
|
||||||
@@ -21,22 +21,33 @@ import { useThemeConfig } from '@/store/themeConfig';
|
|||||||
const LayoutParentView = defineAsyncComponent(() => import('@/layout/routerView/parent.vue'));
|
const LayoutParentView = defineAsyncComponent(() => import('@/layout/routerView/parent.vue'));
|
||||||
const Footer = defineAsyncComponent(() => import('@/layout/footer/index.vue'));
|
const Footer = defineAsyncComponent(() => import('@/layout/footer/index.vue'));
|
||||||
|
|
||||||
const { proxy } = getCurrentInstance() as any;
|
const layoutScrollbarRef = useTemplateRef('layoutScrollbarRef');
|
||||||
const { themeConfig } = storeToRefs(useThemeConfig());
|
const { themeConfig } = storeToRefs(useThemeConfig());
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
|
||||||
// 监听 themeConfig 配置文件的变化,更新菜单 el-scrollbar 的高度
|
// 监听 themeConfig 配置文件的变化,更新菜单 el-scrollbar 的高度
|
||||||
watch(themeConfig.value, (val) => {
|
watch(themeConfig.value, (val) => {
|
||||||
if (val.isFixedHeaderChange !== val.isFixedHeader) {
|
if (val.isFixedHeaderChange !== val.isFixedHeader) {
|
||||||
if (!proxy.$refs.layoutScrollbarRef) return false;
|
if (!layoutScrollbarRef.value) {
|
||||||
proxy.$refs.layoutScrollbarRef.update();
|
return;
|
||||||
|
}
|
||||||
|
layoutScrollbarRef.value.update();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 监听路由的变化
|
// 监听路由的变化
|
||||||
watch(
|
watch(
|
||||||
() => route.path,
|
() => route.path,
|
||||||
() => {
|
() => {
|
||||||
proxy.$refs.layoutScrollbarRef.wrapRef.scrollTop = 0;
|
nextTick(() => {
|
||||||
|
if (!layoutScrollbarRef.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setTimeout(() => {
|
||||||
|
layoutScrollbarRef.value.update();
|
||||||
|
}, 500);
|
||||||
|
layoutScrollbarRef.value.setScrollTop();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-container class="layout-container flex-center layout-backtop">
|
<el-container class="layout-container layout-backtop !flex-col">
|
||||||
<Header />
|
<Header />
|
||||||
<Main />
|
<Main />
|
||||||
</el-container>
|
</el-container>
|
||||||
|
|||||||
@@ -34,13 +34,12 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup name="navMenuHorizontal">
|
<script lang="ts" setup name="navMenuHorizontal">
|
||||||
import { reactive, computed, onMounted, inject, defineAsyncComponent } from 'vue';
|
import { reactive, computed, onMounted, inject } from 'vue';
|
||||||
import { useRoute, onBeforeRouteUpdate } from 'vue-router';
|
import { useRoute, onBeforeRouteUpdate } from 'vue-router';
|
||||||
|
import SubItem from '@/layout/navMenu/subItem.vue';
|
||||||
import { useRoutesList } from '@/store/routesList';
|
import { useRoutesList } from '@/store/routesList';
|
||||||
import { useThemeConfig } from '@/store/themeConfig';
|
import { useThemeConfig } from '@/store/themeConfig';
|
||||||
|
|
||||||
const SubItem = defineAsyncComponent(() => import('@/layout/navMenu/subItem.vue'));
|
|
||||||
|
|
||||||
// 定义父组件传过来的值
|
// 定义父组件传过来的值
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
// 菜单列表
|
// 菜单列表
|
||||||
@@ -117,42 +116,29 @@ onBeforeRouteUpdate((to) => {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
margin-right: 30px;
|
margin-right: 30px;
|
||||||
|
|
||||||
.horizontal-menu {
|
::v-deep(.el-scrollbar__bar.is-vertical) {
|
||||||
border: none !important;
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
::v-deep(a) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-menu.el-menu--horizontal {
|
||||||
|
display: flex;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
|
border-bottom: none !important;
|
||||||
::v-deep(.el-menu-item) {
|
|
||||||
height: 42px;
|
|
||||||
line-height: 42px;
|
|
||||||
padding: 0 15px !important;
|
|
||||||
margin: 0 5px;
|
|
||||||
border-radius: 6px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep(.el-sub-menu__title) {
|
|
||||||
height: 42px;
|
|
||||||
line-height: 42px;
|
|
||||||
padding: 0 25px 0 15px !important; /* 右边留出更多空间给箭头图标 */
|
|
||||||
margin: 0 5px;
|
|
||||||
border-radius: 6px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep(.el-sub-menu__icon-arrow) {
|
|
||||||
right: 5px !important;
|
|
||||||
margin-top: -5px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
::v-deep(.el-menu-item.is-active),
|
|
||||||
::v-deep(.el-sub-menu.is-active .el-sub-menu__title) {
|
|
||||||
color: #409eff;
|
|
||||||
background-color: rgba(64, 158, 255, 0.1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 菜单项基础样式
|
||||||
|
.horizontal-menu :deep(.el-menu-item),
|
||||||
|
.horizontal-menu :deep(.el-sub-menu__title) {
|
||||||
|
margin: 0 5px !important;
|
||||||
|
justify-content: center;
|
||||||
|
max-width: 160px;
|
||||||
|
min-width: 100px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -131,35 +131,10 @@ $spacing: 8px;
|
|||||||
|
|
||||||
// 横向菜单
|
// 横向菜单
|
||||||
.el-menu--horizontal {
|
.el-menu--horizontal {
|
||||||
background: var(--bg-topBar);
|
|
||||||
|
|
||||||
.el-menu-item,
|
.el-menu-item,
|
||||||
.el-sub-menu {
|
.el-sub-menu {
|
||||||
height: $menuHeight;
|
|
||||||
line-height: $menuHeight;
|
|
||||||
color: var(--bg-topBarColor);
|
color: var(--bg-topBarColor);
|
||||||
border-radius: $radius;
|
|
||||||
padding: 0 10px !important; // 减小内边距
|
|
||||||
|
|
||||||
.el-sub-menu__title {
|
|
||||||
height: $menuHeight;
|
|
||||||
line-height: $menuHeight;
|
|
||||||
color: var(--bg-topBarColor);
|
|
||||||
border-radius: $radius;
|
|
||||||
padding: 0 10px !important; // 减小内边距
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-menu-item.is-active,
|
|
||||||
.el-sub-menu.is-active .el-sub-menu__title {
|
|
||||||
color: #409eff;
|
|
||||||
background-color: rgba(64, 158, 255, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-menu-item:hover,
|
|
||||||
.el-sub-menu:not(.is-active):hover .el-sub-menu__title {
|
|
||||||
background-color: rgba(64, 158, 255, 0.05);
|
|
||||||
transform: translateY(-1px);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -171,33 +146,15 @@ $spacing: 8px;
|
|||||||
|
|
||||||
.el-menu-item,
|
.el-menu-item,
|
||||||
.el-sub-menu__title {
|
.el-sub-menu__title {
|
||||||
height: $menuHeight;
|
|
||||||
line-height: $menuHeight;
|
|
||||||
color: var(--bg-topBarColor);
|
color: var(--bg-topBarColor);
|
||||||
border-radius: $radius;
|
|
||||||
transition: all 0.2s ease;
|
|
||||||
padding: 0 10px !important; // 减小内边距
|
padding: 0 10px !important; // 减小内边距
|
||||||
border-bottom: none !important;
|
border-bottom: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-menu-item:not(.is-active):hover,
|
|
||||||
.el-sub-menu:not(.is-active):hover .el-sub-menu__title {
|
|
||||||
color: var(--bg-topBarColor);
|
|
||||||
background-color: rgba(0, 0, 0, 0.03);
|
|
||||||
}
|
|
||||||
|
|
||||||
.el-menu-item.is-active,
|
|
||||||
.el-sub-menu.is-active .el-sub-menu__title {
|
|
||||||
background-color: rgba(64, 158, 255, 0.1);
|
|
||||||
color: #409eff;
|
|
||||||
font-weight: 500;
|
|
||||||
border-bottom: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 为水平菜单的子菜单项正确处理箭头图标位置
|
// 为水平菜单的子菜单项正确处理箭头图标位置
|
||||||
.el-sub-menu {
|
.el-sub-menu {
|
||||||
.el-sub-menu__title {
|
.el-sub-menu__title {
|
||||||
padding-right: 20px !important; // 调整箭头图标空间
|
padding-right: 22px !important; // 调整箭头图标空间
|
||||||
border-bottom: none !important;
|
border-bottom: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ import { useI18nCreateTitle, useI18nDeleteConfirm, useI18nDeleteSuccessMsg, useI
|
|||||||
import { tmplApi } from '../api';
|
import { tmplApi } from '../api';
|
||||||
import { TmplStatusEnum, TmplTypeEnum, ChannelTypeEnum } from '../enums';
|
import { TmplStatusEnum, TmplTypeEnum, ChannelTypeEnum } from '../enums';
|
||||||
import TmplEdit from './TmplEdit.vue';
|
import TmplEdit from './TmplEdit.vue';
|
||||||
import EnumValue from '../../../common/Enum';
|
import EnumValue from '@/common/Enum';
|
||||||
import AccountSelectFormItem from '@/views/system/account/components/AccountSelectFormItem.vue';
|
import AccountSelectFormItem from '@/views/system/account/components/AccountSelectFormItem.vue';
|
||||||
|
|
||||||
const perms = {
|
const perms = {
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-card class="h-full flex" body-class="!p-1 flex flex-col w-full">
|
<el-card class="h-full flex tag-tree-card" body-class="!p-0 flex flex-col w-full">
|
||||||
<el-input v-model="filterText" :placeholder="$t('tag.tagFilterPlaceholder')" clearable size="small" class="!mb-1 w-full" />
|
<div class="tag-tree-header">
|
||||||
|
<el-input v-model="filterText" :placeholder="$t('tag.tagFilterPlaceholder')" clearable size="small" class="tag-tree-search w-full">
|
||||||
|
<template #prefix>
|
||||||
|
<SvgIcon class="tag-tree-search-icon" name="search" />
|
||||||
|
</template>
|
||||||
|
</el-input>
|
||||||
|
</div>
|
||||||
<el-scrollbar>
|
<el-scrollbar>
|
||||||
<el-tree
|
<el-tree
|
||||||
class="min-w-full inline-block"
|
class="min-w-full inline-block"
|
||||||
@@ -30,7 +36,7 @@
|
|||||||
|
|
||||||
<slot v-else :node="node" :data="data" name="prefix"></slot>
|
<slot v-else :node="node" :data="data" name="prefix"></slot>
|
||||||
|
|
||||||
<span class="ml-0.5" :title="data.labelRemark">
|
<span class="ml-1" :title="data.labelRemark">
|
||||||
<slot name="label" :data="data" v-if="!data.disabled"> {{ $t(data.label) }}</slot>
|
<slot name="label" :data="data" v-if="!data.disabled"> {{ $t(data.label) }}</slot>
|
||||||
<!-- 禁用状态 -->
|
<!-- 禁用状态 -->
|
||||||
<slot name="disabledLabel" :data="data" v-else>
|
<slot name="disabledLabel" :data="data" v-else>
|
||||||
@@ -40,7 +46,7 @@
|
|||||||
</slot>
|
</slot>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<span class="absolute right-2.5 mt-0.5 text-[10px] text-gray-400">
|
<span class="ml-auto pr-1.5 text-[10px] text-gray-400">
|
||||||
<slot :node="node" :data="data" name="suffix"></slot>
|
<slot :node="node" :data="data" name="suffix"></slot>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -59,6 +65,7 @@ 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 { isPrefixSubsequence } from '@/common/utils/string';
|
import { isPrefixSubsequence } from '@/common/utils/string';
|
||||||
|
import SvgIcon from '@/components/svgIcon/index.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
resourceType: {
|
resourceType: {
|
||||||
@@ -248,4 +255,22 @@ defineExpose({
|
|||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped>
|
||||||
|
.tag-tree-card {
|
||||||
|
:deep(.el-card__body) {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-tree-header {
|
||||||
|
padding: 4px 6px;
|
||||||
|
border-bottom: 1px solid var(--el-border-color-light);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag-tree-search {
|
||||||
|
:deep(.el-input__wrapper) {
|
||||||
|
border-radius: 14px;
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 字段名列 -->
|
<!-- 字段名列 -->
|
||||||
<div v-else @contextmenu="headerContextmenuClick($event, column)" style="position: relative">
|
<div v-else style="position: relative" @mouseenter="showColumnAction(column)" @mouseleave="hideColumnAction">
|
||||||
<!-- 字段列的数据类型 -->
|
<!-- 字段列的数据类型 -->
|
||||||
<div class="column-type">
|
<div class="column-type">
|
||||||
<span v-if="column.dataTypeSubscript === 'icon-clock'">
|
<span v-if="column.dataTypeSubscript === 'icon-clock'">
|
||||||
@@ -65,9 +65,56 @@
|
|||||||
|
|
||||||
<!-- 字段列右部分内容 -->
|
<!-- 字段列右部分内容 -->
|
||||||
<div class="column-right">
|
<div class="column-right">
|
||||||
<span v-if="column.title == nowSortColumn?.columnName">
|
<el-dropdown
|
||||||
<SvgIcon color="var(--el-color-primary)" :name="nowSortColumn?.order == 'asc' ? 'top' : 'bottom'"></SvgIcon>
|
@command="handleColumnCommand(column, $event)"
|
||||||
</span>
|
@visibleChange="onColumnActionVisibleChange(column, $event)"
|
||||||
|
trigger="click"
|
||||||
|
v-if="column.key !== rowNoColumn.key"
|
||||||
|
size="small"
|
||||||
|
>
|
||||||
|
<span class="column-actions-trigger">
|
||||||
|
<!-- 排序箭头图标 -->
|
||||||
|
<SvgIcon
|
||||||
|
v-if="
|
||||||
|
column.title == nowSortColumn?.columnName &&
|
||||||
|
!showColumnActions[column.key] &&
|
||||||
|
!columnActionVisible[column.key]
|
||||||
|
"
|
||||||
|
:color="'var(--el-color-primary)'"
|
||||||
|
:name="nowSortColumn?.order == 'asc' ? 'top' : 'bottom'"
|
||||||
|
:size="14"
|
||||||
|
/>
|
||||||
|
<!-- 更多操作图标 -->
|
||||||
|
<SvgIcon
|
||||||
|
v-if="columnActionVisible[column.key] || showColumnActions[column.key]"
|
||||||
|
name="MoreFilled"
|
||||||
|
:size="14"
|
||||||
|
:color="'var(--el-color-primary)'"
|
||||||
|
class="column-more-icon"
|
||||||
|
:class="{ 'column-more-icon-visible': columnActionVisible[column.key] || showColumnActions[column.key] }"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
<template #dropdown>
|
||||||
|
<el-dropdown-menu>
|
||||||
|
<el-dropdown-item command="sort-asc">
|
||||||
|
<SvgIcon name="top" class="mr-1" />
|
||||||
|
{{ $t('db.asc') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item command="sort-desc">
|
||||||
|
<SvgIcon name="bottom" class="mr-1" />
|
||||||
|
{{ $t('db.desc') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item v-if="!column.fixed" command="fix">
|
||||||
|
<SvgIcon name="Paperclip" class="mr-1" />
|
||||||
|
{{ $t('db.fixed') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
<el-dropdown-item v-else command="unfix">
|
||||||
|
<SvgIcon name="Minus" class="mr-1" />
|
||||||
|
{{ $t('db.cancelFiexd') }}
|
||||||
|
</el-dropdown-item>
|
||||||
|
</el-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
</el-dropdown>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -214,43 +261,9 @@ const props = defineProps({
|
|||||||
const contextmenuRef = ref();
|
const contextmenuRef = ref();
|
||||||
const tableRef = ref();
|
const tableRef = ref();
|
||||||
|
|
||||||
/** 表头 menu items **/
|
// 用于控制列操作按钮的显示
|
||||||
|
const showColumnActions = ref({} as any);
|
||||||
const cmHeaderAsc = new ContextmenuItem('asc', 'db.asc')
|
const columnActionVisible = ref({} as any);
|
||||||
.withIcon('top')
|
|
||||||
.withOnClick((data: any) => {
|
|
||||||
onTableSortChange({ columnName: data.dataKey, order: 'asc' });
|
|
||||||
})
|
|
||||||
.withHideFunc(() => !props.showColumnTip);
|
|
||||||
|
|
||||||
const cmHeaderDesc = new ContextmenuItem('desc', 'db.desc')
|
|
||||||
.withIcon('bottom')
|
|
||||||
.withOnClick((data: any) => {
|
|
||||||
onTableSortChange({ columnName: data.dataKey, order: 'desc' });
|
|
||||||
})
|
|
||||||
.withHideFunc(() => !props.showColumnTip);
|
|
||||||
|
|
||||||
const cmHeaderFixed = new ContextmenuItem('fixed', 'db.fixed')
|
|
||||||
.withIcon('Paperclip')
|
|
||||||
.withOnClick((data: any) => {
|
|
||||||
state.columns.forEach((column: any) => {
|
|
||||||
if (column.dataKey == data.dataKey) {
|
|
||||||
column.fixed = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.withHideFunc((data: any) => data.fixed);
|
|
||||||
|
|
||||||
const cmHeaderCancelFixed = new ContextmenuItem('cancelFixed', 'db.cancelFiexd')
|
|
||||||
.withIcon('Minus')
|
|
||||||
.withOnClick((data: any) => {
|
|
||||||
state.columns.forEach((column: any) => {
|
|
||||||
if (column.dataKey == data.dataKey) {
|
|
||||||
column.fixed = false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
})
|
|
||||||
.withHideFunc((data: any) => !data.fixed);
|
|
||||||
|
|
||||||
/** 表数据 contextmenu items **/
|
/** 表数据 contextmenu items **/
|
||||||
|
|
||||||
@@ -508,6 +521,55 @@ const cancelLoading = async () => {
|
|||||||
endLoading();
|
endLoading();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示列操作按钮
|
||||||
|
*/
|
||||||
|
const showColumnAction = (column: any) => {
|
||||||
|
showColumnActions.value[column.key] = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 隐藏列操作按钮
|
||||||
|
*/
|
||||||
|
const hideColumnAction = () => {
|
||||||
|
showColumnActions.value = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理列操作命令
|
||||||
|
*/
|
||||||
|
const handleColumnCommand = (column: any, command: string) => {
|
||||||
|
switch (command) {
|
||||||
|
case 'sort-asc':
|
||||||
|
onTableSortChange({ columnName: column.dataKey, order: 'asc' });
|
||||||
|
break;
|
||||||
|
case 'sort-desc':
|
||||||
|
onTableSortChange({ columnName: column.dataKey, order: 'desc' });
|
||||||
|
break;
|
||||||
|
case 'fix':
|
||||||
|
state.columns.forEach((col: any) => {
|
||||||
|
if (col.dataKey == column.dataKey) {
|
||||||
|
col.fixed = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'unfix':
|
||||||
|
state.columns.forEach((col: any) => {
|
||||||
|
if (col.dataKey == column.dataKey) {
|
||||||
|
col.fixed = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// 点击了取消固定等操作后,可能更多的icon还是显示在列上,所以需要重新置为空对象。暂时不懂是组件bug还是啥
|
||||||
|
columnActionVisible.value = {};
|
||||||
|
};
|
||||||
|
|
||||||
|
const onColumnActionVisibleChange = (column: any, visible: boolean) => {
|
||||||
|
columnActionVisible.value = {}; // 只显示一个列的更多icon
|
||||||
|
columnActionVisible.value[column.key] = visible;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 当前单元格是否允许编辑
|
* 当前单元格是否允许编辑
|
||||||
* @param rowIndex ri
|
* @param rowIndex ri
|
||||||
@@ -570,16 +632,6 @@ const rowEventHandlers = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const headerContextmenuClick = (event: any, data: any) => {
|
|
||||||
event.preventDefault(); // 阻止默认的右击菜单行为
|
|
||||||
|
|
||||||
const { clientX, clientY } = event;
|
|
||||||
state.contextmenu.dropdown.x = clientX;
|
|
||||||
state.contextmenu.dropdown.y = clientY;
|
|
||||||
state.contextmenu.items = [cmHeaderAsc, cmHeaderDesc, cmHeaderFixed, cmHeaderCancelFixed];
|
|
||||||
contextmenuRef.value.openContextmenu(data);
|
|
||||||
};
|
|
||||||
|
|
||||||
const dataContextmenuClick = (event: any, rowIndex: number, column: any, data: any) => {
|
const dataContextmenuClick = (event: any, rowIndex: number, column: any, data: any) => {
|
||||||
event.preventDefault(); // 阻止默认的右击菜单行为
|
event.preventDefault(); // 阻止默认的右击菜单行为
|
||||||
|
|
||||||
@@ -851,6 +903,31 @@ defineExpose({
|
|||||||
top: 2px;
|
top: 2px;
|
||||||
right: 0;
|
right: 0;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-actions-trigger {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
border-radius: 50%;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: var(--el-fill-color-light);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-more-icon {
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-more-icon-visible {
|
||||||
|
opacity: 1 !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -497,8 +497,8 @@ export class DbInst {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取列名称的长度 加上排序图标长度、abc为字段类型简称占位符、排序图标等
|
// 获取列名称的长度 加上排序图标长度、abc为字段类型简称占位符、更多/排序图标等
|
||||||
const columnWidth: number = getTextWidth(prop + 'abc') + 10;
|
const columnWidth: number = getTextWidth(prop + 'abc') + 25;
|
||||||
// prop为该列的字段名(传字符串);tableData为该表格的数据源(传变量);
|
// prop为该列的字段名(传字符串);tableData为该表格的数据源(传变量);
|
||||||
if (!tableData || !tableData.length || tableData.length === 0 || tableData === undefined) {
|
if (!tableData || !tableData.length || tableData.length === 0 || tableData === undefined) {
|
||||||
return columnWidth;
|
return columnWidth;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
module mayfly-go
|
module mayfly-go
|
||||||
|
|
||||||
go 1.24
|
go 1.25
|
||||||
|
|
||||||
require (
|
require (
|
||||||
gitee.com/chunanyong/dm v1.8.20
|
gitee.com/chunanyong/dm v1.8.20
|
||||||
@@ -23,7 +23,7 @@ require (
|
|||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/pkg/sftp v1.13.9
|
github.com/pkg/sftp v1.13.9
|
||||||
github.com/pquerna/otp v1.5.0
|
github.com/pquerna/otp v1.5.0
|
||||||
github.com/redis/go-redis/v9 v9.11.0
|
github.com/redis/go-redis/v9 v9.12.1
|
||||||
github.com/robfig/cron/v3 v3.0.1 // 定时任务
|
github.com/robfig/cron/v3 v3.0.1 // 定时任务
|
||||||
github.com/sijms/go-ora/v2 v2.9.0
|
github.com/sijms/go-ora/v2 v2.9.0
|
||||||
github.com/spf13/cast v1.9.2
|
github.com/spf13/cast v1.9.2
|
||||||
@@ -31,7 +31,7 @@ require (
|
|||||||
github.com/tidwall/gjson v1.18.0
|
github.com/tidwall/gjson v1.18.0
|
||||||
github.com/veops/go-ansiterm v0.0.5
|
github.com/veops/go-ansiterm v0.0.5
|
||||||
go.mongodb.org/mongo-driver/v2 v2.2.2 // mongo
|
go.mongodb.org/mongo-driver/v2 v2.2.2 // mongo
|
||||||
golang.org/x/crypto v0.40.0 // ssh
|
golang.org/x/crypto v0.41.0 // ssh
|
||||||
golang.org/x/oauth2 v0.30.0
|
golang.org/x/oauth2 v0.30.0
|
||||||
golang.org/x/sync v0.16.0
|
golang.org/x/sync v0.16.0
|
||||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1
|
||||||
@@ -91,8 +91,8 @@ require (
|
|||||||
golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 // indirect
|
golang.org/x/exp v0.0.0-20250718183923-645b1fa84792 // indirect
|
||||||
golang.org/x/image v0.29.0 // indirect
|
golang.org/x/image v0.29.0 // indirect
|
||||||
golang.org/x/net v0.42.0 // indirect
|
golang.org/x/net v0.42.0 // indirect
|
||||||
golang.org/x/sys v0.34.0 // indirect
|
golang.org/x/sys v0.35.0 // indirect
|
||||||
golang.org/x/text v0.27.0 // indirect
|
golang.org/x/text v0.28.0 // indirect
|
||||||
google.golang.org/protobuf v1.36.6 // indirect
|
google.golang.org/protobuf v1.36.6 // indirect
|
||||||
modernc.org/libc v1.66.4 // indirect
|
modernc.org/libc v1.66.4 // indirect
|
||||||
modernc.org/mathutil v1.7.1 // indirect
|
modernc.org/mathutil v1.7.1 // indirect
|
||||||
|
|||||||
@@ -379,7 +379,7 @@ func (m *MachineFile) UploadFolder(rc *req.Ctx) {
|
|||||||
|
|
||||||
isSuccess := true
|
isSuccess := true
|
||||||
for _, chunk := range chunks {
|
for _, chunk := range chunks {
|
||||||
go func(files []FolderFile, wg *sync.WaitGroup) {
|
wg.Go(func() {
|
||||||
defer func() {
|
defer func() {
|
||||||
// 协程执行完成后调用Done方法
|
// 协程执行完成后调用Done方法
|
||||||
wg.Done()
|
wg.Done()
|
||||||
@@ -397,7 +397,7 @@ func (m *MachineFile) UploadFolder(rc *req.Ctx) {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
for _, file := range files {
|
for _, file := range chunk {
|
||||||
fileHeader := file.Fileheader
|
fileHeader := file.Fileheader
|
||||||
dir := file.Dir
|
dir := file.Dir
|
||||||
file, _ := fileHeader.Open()
|
file, _ := fileHeader.Open()
|
||||||
@@ -410,7 +410,7 @@ func (m *MachineFile) UploadFolder(rc *req.Ctx) {
|
|||||||
defer createfile.Close()
|
defer createfile.Close()
|
||||||
io.Copy(createfile, file)
|
io.Copy(createfile, file)
|
||||||
}
|
}
|
||||||
}(chunk, &wg)
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 等待所有协程执行完成
|
// 等待所有协程执行完成
|
||||||
|
|||||||
Reference in New Issue
Block a user