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/"
|
||||
},
|
||||
"dependencies": {
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
"@logicflow/core": "^2.0.16",
|
||||
"@logicflow/extension": "^2.0.21",
|
||||
"@element-plus/icons-vue": "^2.3.2",
|
||||
"@logicflow/core": "^2.1.1",
|
||||
"@logicflow/extension": "^2.1.2",
|
||||
"@vueuse/core": "^13.6.0",
|
||||
"@xterm/addon-fit": "^0.10.0",
|
||||
"@xterm/addon-search": "^0.15.0",
|
||||
@@ -24,7 +24,7 @@
|
||||
"crypto-js": "^4.2.0",
|
||||
"dayjs": "^1.11.13",
|
||||
"echarts": "^6.0.0",
|
||||
"element-plus": "^2.10.5",
|
||||
"element-plus": "^2.10.7",
|
||||
"js-base64": "^3.7.7",
|
||||
"jsencrypt": "^3.3.2",
|
||||
"monaco-editor": "^0.52.2",
|
||||
@@ -59,7 +59,7 @@
|
||||
"eslint-plugin-vue": "^10.4.0",
|
||||
"postcss": "^8.5.6",
|
||||
"prettier": "^3.6.1",
|
||||
"sass": "^1.89.2",
|
||||
"sass": "^1.90.0",
|
||||
"tailwindcss": "^4.1.11",
|
||||
"typescript": "^5.9.2",
|
||||
"vite": "npm:rolldown-vite@latest",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<el-main class="layout-main !h-full">
|
||||
<el-scrollbar ref="layoutScrollbarRef" view-class="!h-full">
|
||||
<el-main class="layout-main h-full">
|
||||
<el-scrollbar ref="layoutScrollbarRef" view-class="h-full">
|
||||
<LayoutParentView />
|
||||
</el-scrollbar>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
</template>
|
||||
|
||||
<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 { storeToRefs } from 'pinia';
|
||||
import { useThemeConfig } from '@/store/themeConfig';
|
||||
@@ -21,22 +21,33 @@ import { useThemeConfig } from '@/store/themeConfig';
|
||||
const LayoutParentView = defineAsyncComponent(() => import('@/layout/routerView/parent.vue'));
|
||||
const Footer = defineAsyncComponent(() => import('@/layout/footer/index.vue'));
|
||||
|
||||
const { proxy } = getCurrentInstance() as any;
|
||||
const layoutScrollbarRef = useTemplateRef('layoutScrollbarRef');
|
||||
const { themeConfig } = storeToRefs(useThemeConfig());
|
||||
const route = useRoute();
|
||||
|
||||
// 监听 themeConfig 配置文件的变化,更新菜单 el-scrollbar 的高度
|
||||
watch(themeConfig.value, (val) => {
|
||||
if (val.isFixedHeaderChange !== val.isFixedHeader) {
|
||||
if (!proxy.$refs.layoutScrollbarRef) return false;
|
||||
proxy.$refs.layoutScrollbarRef.update();
|
||||
if (!layoutScrollbarRef.value) {
|
||||
return;
|
||||
}
|
||||
layoutScrollbarRef.value.update();
|
||||
}
|
||||
});
|
||||
|
||||
// 监听路由的变化
|
||||
watch(
|
||||
() => route.path,
|
||||
() => {
|
||||
proxy.$refs.layoutScrollbarRef.wrapRef.scrollTop = 0;
|
||||
nextTick(() => {
|
||||
if (!layoutScrollbarRef.value) {
|
||||
return;
|
||||
}
|
||||
setTimeout(() => {
|
||||
layoutScrollbarRef.value.update();
|
||||
}, 500);
|
||||
layoutScrollbarRef.value.setScrollTop();
|
||||
});
|
||||
}
|
||||
);
|
||||
</script>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<el-container class="layout-container flex-center layout-backtop">
|
||||
<el-container class="layout-container layout-backtop !flex-col">
|
||||
<Header />
|
||||
<Main />
|
||||
</el-container>
|
||||
|
||||
@@ -34,13 +34,12 @@
|
||||
</template>
|
||||
|
||||
<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 SubItem from '@/layout/navMenu/subItem.vue';
|
||||
import { useRoutesList } from '@/store/routesList';
|
||||
import { useThemeConfig } from '@/store/themeConfig';
|
||||
|
||||
const SubItem = defineAsyncComponent(() => import('@/layout/navMenu/subItem.vue'));
|
||||
|
||||
// 定义父组件传过来的值
|
||||
const props = defineProps({
|
||||
// 菜单列表
|
||||
@@ -117,42 +116,29 @@ onBeforeRouteUpdate((to) => {
|
||||
overflow: hidden;
|
||||
margin-right: 30px;
|
||||
|
||||
.horizontal-menu {
|
||||
border: none !important;
|
||||
::v-deep(.el-scrollbar__bar.is-vertical) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
::v-deep(a) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.el-menu.el-menu--horizontal {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
::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;
|
||||
border-bottom: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
::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>
|
||||
|
||||
@@ -131,35 +131,10 @@ $spacing: 8px;
|
||||
|
||||
// 横向菜单
|
||||
.el-menu--horizontal {
|
||||
background: var(--bg-topBar);
|
||||
|
||||
.el-menu-item,
|
||||
.el-sub-menu {
|
||||
height: $menuHeight;
|
||||
line-height: $menuHeight;
|
||||
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-sub-menu__title {
|
||||
height: $menuHeight;
|
||||
line-height: $menuHeight;
|
||||
color: var(--bg-topBarColor);
|
||||
border-radius: $radius;
|
||||
transition: all 0.2s ease;
|
||||
padding: 0 10px !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__title {
|
||||
padding-right: 20px !important; // 调整箭头图标空间
|
||||
padding-right: 22px !important; // 调整箭头图标空间
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ import { useI18nCreateTitle, useI18nDeleteConfirm, useI18nDeleteSuccessMsg, useI
|
||||
import { tmplApi } from '../api';
|
||||
import { TmplStatusEnum, TmplTypeEnum, ChannelTypeEnum } from '../enums';
|
||||
import TmplEdit from './TmplEdit.vue';
|
||||
import EnumValue from '../../../common/Enum';
|
||||
import EnumValue from '@/common/Enum';
|
||||
import AccountSelectFormItem from '@/views/system/account/components/AccountSelectFormItem.vue';
|
||||
|
||||
const perms = {
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
<template>
|
||||
<el-card class="h-full flex" body-class="!p-1 flex flex-col w-full">
|
||||
<el-input v-model="filterText" :placeholder="$t('tag.tagFilterPlaceholder')" clearable size="small" class="!mb-1 w-full" />
|
||||
<el-card class="h-full flex tag-tree-card" body-class="!p-0 flex flex-col 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-tree
|
||||
class="min-w-full inline-block"
|
||||
@@ -30,7 +36,7 @@
|
||||
|
||||
<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="disabledLabel" :data="data" v-else>
|
||||
@@ -40,7 +46,7 @@
|
||||
</slot>
|
||||
</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>
|
||||
</span>
|
||||
</div>
|
||||
@@ -59,6 +65,7 @@ import TagInfo from './TagInfo.vue';
|
||||
import { Contextmenu } from '@/components/contextmenu';
|
||||
import { tagApi } from '../tag/api';
|
||||
import { isPrefixSubsequence } from '@/common/utils/string';
|
||||
import SvgIcon from '@/components/svgIcon/index.vue';
|
||||
|
||||
const props = defineProps({
|
||||
resourceType: {
|
||||
@@ -248,4 +255,22 @@ defineExpose({
|
||||
});
|
||||
</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 v-else @contextmenu="headerContextmenuClick($event, column)" style="position: relative">
|
||||
<div v-else style="position: relative" @mouseenter="showColumnAction(column)" @mouseleave="hideColumnAction">
|
||||
<!-- 字段列的数据类型 -->
|
||||
<div class="column-type">
|
||||
<span v-if="column.dataTypeSubscript === 'icon-clock'">
|
||||
@@ -65,9 +65,56 @@
|
||||
|
||||
<!-- 字段列右部分内容 -->
|
||||
<div class="column-right">
|
||||
<span v-if="column.title == nowSortColumn?.columnName">
|
||||
<SvgIcon color="var(--el-color-primary)" :name="nowSortColumn?.order == 'asc' ? 'top' : 'bottom'"></SvgIcon>
|
||||
<el-dropdown
|
||||
@command="handleColumnCommand(column, $event)"
|
||||
@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>
|
||||
@@ -214,43 +261,9 @@ const props = defineProps({
|
||||
const contextmenuRef = ref();
|
||||
const tableRef = ref();
|
||||
|
||||
/** 表头 menu items **/
|
||||
|
||||
const cmHeaderAsc = new ContextmenuItem('asc', 'db.asc')
|
||||
.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);
|
||||
// 用于控制列操作按钮的显示
|
||||
const showColumnActions = ref({} as any);
|
||||
const columnActionVisible = ref({} as any);
|
||||
|
||||
/** 表数据 contextmenu items **/
|
||||
|
||||
@@ -508,6 +521,55 @@ const cancelLoading = async () => {
|
||||
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
|
||||
@@ -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) => {
|
||||
event.preventDefault(); // 阻止默认的右击菜单行为
|
||||
|
||||
@@ -851,6 +903,31 @@ defineExpose({
|
||||
top: 2px;
|
||||
right: 0;
|
||||
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>
|
||||
|
||||
@@ -497,8 +497,8 @@ export class DbInst {
|
||||
return;
|
||||
}
|
||||
|
||||
// 获取列名称的长度 加上排序图标长度、abc为字段类型简称占位符、排序图标等
|
||||
const columnWidth: number = getTextWidth(prop + 'abc') + 10;
|
||||
// 获取列名称的长度 加上排序图标长度、abc为字段类型简称占位符、更多/排序图标等
|
||||
const columnWidth: number = getTextWidth(prop + 'abc') + 25;
|
||||
// prop为该列的字段名(传字符串);tableData为该表格的数据源(传变量);
|
||||
if (!tableData || !tableData.length || tableData.length === 0 || tableData === undefined) {
|
||||
return columnWidth;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
module mayfly-go
|
||||
|
||||
go 1.24
|
||||
go 1.25
|
||||
|
||||
require (
|
||||
gitee.com/chunanyong/dm v1.8.20
|
||||
@@ -23,7 +23,7 @@ require (
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/pkg/sftp v1.13.9
|
||||
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/sijms/go-ora/v2 v2.9.0
|
||||
github.com/spf13/cast v1.9.2
|
||||
@@ -31,7 +31,7 @@ require (
|
||||
github.com/tidwall/gjson v1.18.0
|
||||
github.com/veops/go-ansiterm v0.0.5
|
||||
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/sync v0.16.0
|
||||
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/image v0.29.0 // indirect
|
||||
golang.org/x/net v0.42.0 // indirect
|
||||
golang.org/x/sys v0.34.0 // indirect
|
||||
golang.org/x/text v0.27.0 // indirect
|
||||
golang.org/x/sys v0.35.0 // indirect
|
||||
golang.org/x/text v0.28.0 // indirect
|
||||
google.golang.org/protobuf v1.36.6 // indirect
|
||||
modernc.org/libc v1.66.4 // indirect
|
||||
modernc.org/mathutil v1.7.1 // indirect
|
||||
|
||||
@@ -379,7 +379,7 @@ func (m *MachineFile) UploadFolder(rc *req.Ctx) {
|
||||
|
||||
isSuccess := true
|
||||
for _, chunk := range chunks {
|
||||
go func(files []FolderFile, wg *sync.WaitGroup) {
|
||||
wg.Go(func() {
|
||||
defer func() {
|
||||
// 协程执行完成后调用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
|
||||
dir := file.Dir
|
||||
file, _ := fileHeader.Open()
|
||||
@@ -410,7 +410,7 @@ func (m *MachineFile) UploadFolder(rc *req.Ctx) {
|
||||
defer createfile.Close()
|
||||
io.Copy(createfile, file)
|
||||
}
|
||||
}(chunk, &wg)
|
||||
})
|
||||
}
|
||||
|
||||
// 等待所有协程执行完成
|
||||
|
||||
Reference in New Issue
Block a user