From f92707dac82843760f781e4dea485c94de83a4e8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E9=99=88=E5=AD=90=E9=BB=98?= <925456043@qq.com>
Date: Fri, 31 Jul 2026 14:38:05 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E7=9F=A5=E8=AF=86?=
=?UTF-8?q?=E5=BA=93=E5=88=86=E5=9D=97=E6=93=8D=E4=BD=9C=E5=8C=BA=E4=B8=8E?=
=?UTF-8?q?=E6=BB=9A=E5=8A=A8=E5=AF=BC=E8=88=AA?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- 将向量化操作上移到分块预览前的统一操作区
- 增加页顶页末双气泡并完善边界禁用状态
---
.../app/src/locales/langs/en-US/button.json | 2 +
.../app/src/locales/langs/zh-CN/button.json | 2 +
.../ai/documentCollection/SegmenterDoc.vue | 51 ++++++++-----------
.../packages/@core/base/icons/src/lucide.ts | 1 +
.../src/components/back-top/back-top.vue | 48 +++++++++++++----
.../src/components/back-top/backtop.ts | 23 +++++++++
.../src/components/back-top/use-backtop.ts | 39 ++++++++++++--
.../effects/layouts/src/basic/layout.vue | 6 ++-
8 files changed, 128 insertions(+), 44 deletions(-)
diff --git a/easyflow-ui-admin/app/src/locales/langs/en-US/button.json b/easyflow-ui-admin/app/src/locales/langs/en-US/button.json
index ebb6527f..e4a3440e 100644
--- a/easyflow-ui-admin/app/src/locales/langs/en-US/button.json
+++ b/easyflow-ui-admin/app/src/locales/langs/en-US/button.json
@@ -51,6 +51,8 @@
"submitPublishApproval": "Submit Publish Approval",
"viewSegmentation": "View Segments",
"continueProcess": "Continue",
+ "backToTop": "Back to top",
+ "goToBottom": "Go to bottom",
"startIndex": "Start Indexing",
"retryParse": "Retry Parse",
"retryIndex": "Retry Index"
diff --git a/easyflow-ui-admin/app/src/locales/langs/zh-CN/button.json b/easyflow-ui-admin/app/src/locales/langs/zh-CN/button.json
index 2b6bee1f..f10413ba 100644
--- a/easyflow-ui-admin/app/src/locales/langs/zh-CN/button.json
+++ b/easyflow-ui-admin/app/src/locales/langs/zh-CN/button.json
@@ -51,6 +51,8 @@
"submitPublishApproval": "提交发布审批",
"viewSegmentation": "查看分段",
"continueProcess": "继续处理",
+ "backToTop": "回到页顶",
+ "goToBottom": "到达页末",
"startIndex": "开始向量化",
"retryParse": "重试解析",
"retryIndex": "重试向量化"
diff --git a/easyflow-ui-admin/app/src/views/ai/documentCollection/SegmenterDoc.vue b/easyflow-ui-admin/app/src/views/ai/documentCollection/SegmenterDoc.vue
index 3b1bf2bc..eee08992 100644
--- a/easyflow-ui-admin/app/src/views/ai/documentCollection/SegmenterDoc.vue
+++ b/easyflow-ui-admin/app/src/views/ai/documentCollection/SegmenterDoc.vue
@@ -432,19 +432,7 @@ watch(
-
-
-
- {{ previewError }}
-
-
-
@@ -484,6 +484,15 @@ watch(
grid-column: 1 / -1;
}
+.workbench__actions {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 8px;
+ justify-content: flex-end;
+ padding-bottom: 16px;
+ border-bottom: 1px solid var(--el-border-color-lighter);
+}
+
.workbench__content {
min-height: 620px;
}
@@ -500,22 +509,6 @@ watch(
border-radius: 16px;
}
-.workbench__footer {
- position: sticky;
- bottom: 0;
- display: flex;
- justify-content: flex-end;
- gap: 12px;
- padding: 16px 0 8px;
- margin-top: auto;
- background: linear-gradient(
- 180deg,
- rgb(246 248 251 / 0%) 0%,
- rgb(246 248 251 / 82%) 30%,
- rgb(246 248 251 / 100%) 100%
- );
-}
-
:deep(.el-form-item__label) {
padding-bottom: 6px;
font-size: 13px;
diff --git a/easyflow-ui-admin/packages/@core/base/icons/src/lucide.ts b/easyflow-ui-admin/packages/@core/base/icons/src/lucide.ts
index 0a79f773..c0ea9cd5 100644
--- a/easyflow-ui-admin/packages/@core/base/icons/src/lucide.ts
+++ b/easyflow-ui-admin/packages/@core/base/icons/src/lucide.ts
@@ -1,5 +1,6 @@
export {
ArrowDown,
+ ArrowDownToLine,
ArrowLeft,
ArrowLeftToLine,
ArrowRightLeft,
diff --git a/easyflow-ui-admin/packages/@core/ui-kit/shadcn-ui/src/components/back-top/back-top.vue b/easyflow-ui-admin/packages/@core/ui-kit/shadcn-ui/src/components/back-top/back-top.vue
index 2838d090..8ce3fe97 100644
--- a/easyflow-ui-admin/packages/@core/ui-kit/shadcn-ui/src/components/back-top/back-top.vue
+++ b/easyflow-ui-admin/packages/@core/ui-kit/shadcn-ui/src/components/back-top/back-top.vue
@@ -3,7 +3,7 @@ import type { BacktopProps } from './backtop';
import { computed } from 'vue';
-import { ArrowUpToLine } from '@easyflow-core/icons';
+import { ArrowDownToLine, ArrowUpToLine } from '@easyflow-core/icons';
import { EasyFlowButton } from '../button';
import { useBackTop } from './use-backtop';
@@ -14,9 +14,11 @@ defineOptions({ name: 'BackTop' });
const props = withDefaults(defineProps(), {
bottom: 20,
+ bottomLabel: 'Scroll to bottom',
isGroup: false,
right: 24,
target: '',
+ topLabel: 'Back to top',
visibilityHeight: 200,
});
@@ -25,19 +27,45 @@ const backTopStyle = computed(() => ({
right: `${props.right}px`,
}));
-const { handleClick, visible } = useBackTop(props);
+const {
+ canScrollDown,
+ canScrollUp,
+ handleBottomClick,
+ handleClick,
+ scrollable,
+ visible,
+} = useBackTop(props);
-
-
-
+
+
+
+
+
+
+
diff --git a/easyflow-ui-admin/packages/@core/ui-kit/shadcn-ui/src/components/back-top/backtop.ts b/easyflow-ui-admin/packages/@core/ui-kit/shadcn-ui/src/components/back-top/backtop.ts
index de422c0c..74a53366 100644
--- a/easyflow-ui-admin/packages/@core/ui-kit/shadcn-ui/src/components/back-top/backtop.ts
+++ b/easyflow-ui-admin/packages/@core/ui-kit/shadcn-ui/src/components/back-top/backtop.ts
@@ -6,6 +6,20 @@ export const backtopProps = {
default: 40,
type: Number,
},
+ /**
+ * @zh_CN scroll-to-bottom button label.
+ */
+ bottomLabel: {
+ default: 'Scroll to bottom',
+ type: String,
+ },
+ /**
+ * @zh_CN whether to show top and bottom controls as a group.
+ */
+ isGroup: {
+ default: false,
+ type: Boolean,
+ },
/**
* @zh_CN right distance.
*/
@@ -20,6 +34,13 @@ export const backtopProps = {
default: '',
type: String,
},
+ /**
+ * @zh_CN back-to-top button label.
+ */
+ topLabel: {
+ default: 'Back to top',
+ type: String,
+ },
/**
* @zh_CN the button will not show until the scroll height reaches this value.
*/
@@ -31,8 +52,10 @@ export const backtopProps = {
export interface BacktopProps {
bottom?: number;
+ bottomLabel?: string;
isGroup?: boolean;
right?: number;
target?: string;
+ topLabel?: string;
visibilityHeight?: number;
}
diff --git a/easyflow-ui-admin/packages/@core/ui-kit/shadcn-ui/src/components/back-top/use-backtop.ts b/easyflow-ui-admin/packages/@core/ui-kit/shadcn-ui/src/components/back-top/use-backtop.ts
index 6a51a95a..a64278a9 100644
--- a/easyflow-ui-admin/packages/@core/ui-kit/shadcn-ui/src/components/back-top/use-backtop.ts
+++ b/easyflow-ui-admin/packages/@core/ui-kit/shadcn-ui/src/components/back-top/use-backtop.ts
@@ -1,16 +1,31 @@
import type { BacktopProps } from './backtop';
-import { onMounted, ref, shallowRef } from 'vue';
+import { nextTick, onMounted, ref, shallowRef } from 'vue';
-import { useEventListener, useThrottleFn } from '@vueuse/core';
+import {
+ useEventListener,
+ useResizeObserver,
+ useThrottleFn,
+} from '@vueuse/core';
export const useBackTop = (props: BacktopProps) => {
const el = shallowRef();
const container = shallowRef();
+ const resizeTarget = shallowRef();
+ const canScrollDown = ref(false);
+ const canScrollUp = ref(false);
+ const scrollable = ref(false);
const visible = ref(false);
const handleScroll = () => {
if (el.value) {
+ const maxScrollTop = Math.max(
+ el.value.scrollHeight - el.value.clientHeight,
+ 0,
+ );
+ scrollable.value = maxScrollTop > 1;
+ canScrollUp.value = el.value.scrollTop > 1;
+ canScrollDown.value = el.value.scrollTop < maxScrollTop - 1;
visible.value = el.value.scrollTop >= (props?.visibilityHeight ?? 0);
}
};
@@ -19,12 +34,24 @@ export const useBackTop = (props: BacktopProps) => {
el.value?.scrollTo({ behavior: 'smooth', top: 0 });
};
+ const handleBottomClick = () => {
+ if (!el.value) {
+ return;
+ }
+ el.value.scrollTo({
+ behavior: 'smooth',
+ top: Math.max(el.value.scrollHeight - el.value.clientHeight, 0),
+ });
+ };
+
const handleScrollThrottled = useThrottleFn(handleScroll, 300, true);
useEventListener(container, 'scroll', handleScrollThrottled);
+ useResizeObserver(resizeTarget, handleScrollThrottled);
onMounted(() => {
container.value = document;
el.value = document.documentElement;
+ resizeTarget.value = document.body;
if (props.target) {
el.value = document.querySelector(props.target) ?? undefined;
@@ -33,13 +60,17 @@ export const useBackTop = (props: BacktopProps) => {
throw new Error(`target does not exist: ${props.target}`);
}
container.value = el.value;
+ resizeTarget.value = el.value;
}
- // Give visible an initial value, fix #13066
- handleScroll();
+ void nextTick(handleScroll);
});
return {
+ canScrollDown,
+ canScrollUp,
+ handleBottomClick,
handleClick,
+ scrollable,
visible,
};
};
diff --git a/easyflow-ui-admin/packages/effects/layouts/src/basic/layout.vue b/easyflow-ui-admin/packages/effects/layouts/src/basic/layout.vue
index 21822f91..9d072c01 100644
--- a/easyflow-ui-admin/packages/effects/layouts/src/basic/layout.vue
+++ b/easyflow-ui-admin/packages/effects/layouts/src/basic/layout.vue
@@ -425,7 +425,11 @@ const headerSlots = computed(() => {
@clear-preferences-and-logout="clearPreferencesAndLogout"
/>
-
+