fix(login): correct password validation message path

refactor(iframe-bridge): update route prefix from '/ragflow' to '/route-ragflow'
This commit is contained in:
2025-11-17 10:42:42 +08:00
parent 32c77d9f8e
commit 3118fa4f1b
4 changed files with 102 additions and 62 deletions

View File

@@ -50,11 +50,11 @@ export function isEmbedded(): boolean {
/**
* 将子端路由转换为宿主路由(添加宿主前缀)。
* 默认会为路径添加 '/ragflow' 前缀。
* 默认会为路径添加 '/route-ragflow' 前缀。
*/
export function toHostPath(to: string): string {
const normalized = to.startsWith('/') ? to : `/${to}`;
const target = normalized.startsWith('/route-ragflow') ? normalized : `/ragflow${normalized}`;
const target = normalized.startsWith('/route-ragflow') ? normalized : `/route-ragflow${normalized}`;
log('toHostPath()', { input: to, normalized, target });
return target;
}

View File

@@ -370,7 +370,7 @@ export const useLoginForm = () => {
required: t('login.passwordPlaceholder'),
minLength: {
value: 6,
message: t('login.passwordMinLength')
message: t('setting.passwordMinLength')
}
}
},
@@ -393,7 +393,7 @@ export const useLoginForm = () => {
required: t('login.passwordPlaceholder'),
minLength: {
value: 8,
message: t('login.passwordMinLength')
message: t('setting.passwordMinLength')
}
}
}

View File

@@ -24,6 +24,7 @@ import { useSnackbar } from '@/hooks/useSnackbar';
import { AgentCategory } from '@/constants/agent';
import { IAgentCreateRequestBody } from '@/interfaces/request/agent';
import { useAgentOperations } from '@/hooks/agent-hooks';
import { Position } from '@xyflow/react';
interface CreateAgentDialogProps {
open: boolean;
@@ -129,12 +130,36 @@ const CreateAgentDialog: React.FC<CreateAgentDialogProps> = ({ open, onClose, on
const body: IAgentCreateRequestBody = {
title: lang === 'zh' ? '空白智能体' : 'Blank Agent',
dsl: {
components: {},
history: [],
globals: {},
graph: {
nodes: [
{
id: 'begin',
type: 'beginNode',
position: { x: 50, y: 200 },
data: { label: 'Begin', name: 'begin' },
sourcePosition: Position.Left,
targetPosition: Position.Right,
},
],
edges: [],
},
components: {
begin: {
obj: { component_name: 'Begin', params: {} },
downstream: [],
upstream: [],
},
},
retrieval: [],
graph: { nodes: [], edges: [] },
history: [],
path: [],
messages: [],
globals: {
'sys.query': '',
'sys.user_id': '',
'sys.conversation_turns': 0,
'sys.files': [],
},
},
canvas_category: AgentCategory.AgentCanvas,
};

View File

@@ -29,6 +29,7 @@ import ChunkListResult from './components/ChunkListResult';
import knowledgeService from '@/services/knowledge_service';
import type { IKnowledge, IKnowledgeFile, IChunk } from '@/interfaces/database/knowledge';
import KnowledgeBreadcrumbs from '@/pages/knowledge/components/KnowledgeBreadcrumbs';
import logger from '@/utils/logger';
function ChunkParsedResult() {
const { t } = useTranslation();
@@ -109,22 +110,20 @@ function ChunkParsedResult() {
if (!doc_id || fileLoading) return;
try {
setFileLoading(true);
// 取消之前的请求
if (abortControllerRef.current) {
// abortControllerRef.current.abort();
abortControllerRef.current.abort();
}
setFileLoading(true);
// 创建新的AbortController
abortControllerRef.current = new AbortController();
const fileResponse = await knowledgeService.getDocumentFile({
const fileResponse: { data: Blob } = await knowledgeService.getDocumentFile({
doc_id
}, {
signal: abortControllerRef.current.signal
});
setFileLoading(false);
if (fileResponse.data instanceof Blob) {
setDocumentFile(fileResponse.data);
const url = URL.createObjectURL(fileResponse.data);
@@ -132,10 +131,11 @@ function ChunkParsedResult() {
}
} catch (err: any) {
if (err?.name !== 'AbortError' && err?.name !== 'CanceledError') {
console.error('获取文档文件失败:', err);
logger.error('获取文档文件失败:', err);
setFileLoading(false);
} else {
logger.info('请求被取消:', err);
}
} finally {
setFileLoading(false);
}
};
@@ -161,62 +161,77 @@ function ChunkParsedResult() {
}
try {
const arrayBuffer = await documentFile.arrayBuffer();
// 使用模块 Worker 的端口,避免设置 workerSrc 导致的路径/MIME 问题
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const task = pdfjsLib.getDocument({ data: arrayBuffer });
const pdfDoc = await task.promise;
const container = pdfContainerRef.current;
if (!container) return;
container.innerHTML = '';
// 根据容器宽度自适应缩放
const containerRect = container.getBoundingClientRect();
const containerWidth = Math.max(1, Math.floor(containerRect.width || container.clientWidth || 800));
for (let pageNum = 1; pageNum <= pdfDoc.numPages; pageNum++) {
const renderWithDoc = async (disableWorker: boolean) => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const page = await pdfDoc.getPage(pageNum);
const viewport = page.getViewport({ scale: 1 });
const scale = containerWidth / viewport.width;
const scaledViewport = page.getViewport({ scale });
const dpr = Math.max(1, window.devicePixelRatio || 1);
const task = pdfjsLib.getDocument({ data: arrayBuffer, disableWorker });
const pdfDoc = await task.promise;
const canvas = window.document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.style.display = 'block';
canvas.style.marginBottom = '12px';
canvas.style.width = `${Math.floor(scaledViewport.width)}px`;
canvas.style.height = `${Math.floor(scaledViewport.height)}px`;
canvas.width = Math.floor(scaledViewport.width * dpr);
canvas.height = Math.floor(scaledViewport.height * dpr);
const container = pdfContainerRef.current;
if (!container) return;
container.innerHTML = '';
if (ctx) {
// 提升清晰度:将绘制与 CSS 尺寸解耦并使用设备像素比
// 根据容器宽度自适应缩放
const containerRect = container.getBoundingClientRect();
const containerWidth = Math.max(1, Math.floor(containerRect.width || container.clientWidth || 800));
for (let pageNum = 1; pageNum <= pdfDoc.numPages; pageNum++) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
ctx.imageSmoothingEnabled = true;
const page = await pdfDoc.getPage(pageNum);
const viewport = page.getViewport({ scale: 1 });
const scale = containerWidth / viewport.width;
const scaledViewport = page.getViewport({ scale });
const dpr = Math.max(1, window.devicePixelRatio || 1);
const canvas = window.document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.style.display = 'block';
canvas.style.marginBottom = '12px';
canvas.style.width = `${Math.floor(scaledViewport.width)}px`;
canvas.style.height = `${Math.floor(scaledViewport.height)}px`;
canvas.width = Math.floor(scaledViewport.width * dpr);
canvas.height = Math.floor(scaledViewport.height * dpr);
if (ctx) {
// 提升清晰度:将绘制与 CSS 尺寸解耦并使用设备像素比
// @ts-ignore
ctx.imageSmoothingEnabled = true;
// @ts-ignore
ctx.imageSmoothingQuality = 'high';
}
// @ts-ignore
ctx.imageSmoothingQuality = 'high';
await page.render({
canvasContext: ctx as CanvasRenderingContext2D,
viewport: scaledViewport,
transform: dpr !== 1 ? [dpr, 0, 0, dpr, 0, 0] : undefined,
}).promise;
const pageWrapper = window.document.createElement('div');
pageWrapper.setAttribute('data-page-index', String(pageNum));
pageWrapper.appendChild(canvas);
container.appendChild(pageWrapper);
}
// @ts-ignore
await page.render({
canvasContext: ctx as CanvasRenderingContext2D,
viewport: scaledViewport,
transform: dpr !== 1 ? [dpr, 0, 0, dpr, 0, 0] : undefined,
}).promise;
};
const pageWrapper = window.document.createElement('div');
pageWrapper.setAttribute('data-page-index', String(pageNum));
pageWrapper.appendChild(canvas);
container.appendChild(pageWrapper);
try {
// 优先使用 Worker 渲染
await renderWithDoc(false);
setPdfRendered(true);
} catch (err1) {
console.error('PDF.js Worker 渲染失败,降级为主线程渲染。错误: ', err1);
try {
// Worker 不可用时,禁用 Worker 在主线程渲染
await renderWithDoc(true);
setPdfRendered(true);
} catch (err2) {
console.error('PDF.js 主线程渲染失败: ', err2);
setPdfRendered(false);
}
}
setPdfRendered(true);
} catch (err) {
console.error('渲染 PDF 过程中发生错误: ', err);
console.error('读取 PDF 文件数据失败: ', err);
setPdfRendered(false);
}
};