修复提示框文字换行问题
This commit is contained in:
@@ -255,54 +255,17 @@ export async function getReviewPoints(fileId: string) {
|
||||
// console.log('result-------', result.evaluated_results?.result);
|
||||
// console.log('datacontent-------', data);
|
||||
if (data && typeof data === 'object') {
|
||||
// try {
|
||||
// const dataObj = data as Record<string, string>;
|
||||
// // 检查是否是预期的格式 {'立案报告表-完整性检查':'缺失部分内容'}
|
||||
// for (const key in dataObj) {
|
||||
// if (Object.prototype.hasOwnProperty.call(dataObj, key)) {
|
||||
// // 使用'-'分割获取前缀(如'立案报告表')
|
||||
// const prefix = key.split('-')[0];
|
||||
// // console.log('prefix-------', prefix);
|
||||
// // 检查document.data中的ocrResult是否存在这个key
|
||||
// if (documentData.data?.ocrResult &&
|
||||
// typeof documentData.data.ocrResult === 'object') {
|
||||
|
||||
// // ocrResult可能有嵌套的ocr_result属性
|
||||
// let ocrData: OcrData = documentData.data.ocrResult as OcrData;
|
||||
|
||||
// // 检查是否有嵌套的ocr_result对象
|
||||
// if ('ocr_result' in ocrData &&
|
||||
// ocrData.ocr_result &&
|
||||
// typeof ocrData.ocr_result === 'object') {
|
||||
// ocrData = ocrData.ocr_result as OcrData;
|
||||
// }
|
||||
|
||||
// for (const ocrKey in ocrData) {
|
||||
// // 如果找到匹配的key
|
||||
// if (ocrKey === prefix &&
|
||||
// ocrData[ocrKey] &&
|
||||
// typeof ocrData[ocrKey] === 'object' &&
|
||||
// 'pages' in ocrData[ocrKey]) {
|
||||
|
||||
// // 获取pages数组
|
||||
// const pages = ocrData[ocrKey].pages;
|
||||
// if (Array.isArray(pages)) {
|
||||
// // 存储每个key对应的页码数组
|
||||
// contentPage[key] = pages;
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// 4-22 更改数据结构:通过拿到的data数据(每一个key对应一个object),将object中的page提取出来
|
||||
try{
|
||||
const dataObj = data as Record<string, {page: number | string,value: string}>;
|
||||
for (const key in dataObj) {
|
||||
if (Object.prototype.hasOwnProperty.call(dataObj, key)) {
|
||||
contentPage[key] = dataObj[key].page.toString();
|
||||
let newPage = dataObj[key].page.toString();
|
||||
// 如果newPage里面有文本,则把文本去掉
|
||||
if(newPage.match(/\d+/g)){
|
||||
newPage = newPage.match(/\d+/g)?.map(Number).join('') || '';
|
||||
}
|
||||
contentPage[key] = newPage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ export function AIAnalysis({ analysisData, score, onConfirmResults }: AIAnalysis
|
||||
</div>
|
||||
|
||||
{/* 操作按钮 */}
|
||||
<div className="mt-4 flex space-x-4">
|
||||
{/* <div className="mt-4 flex space-x-4">
|
||||
<button
|
||||
className="ant-btn ant-btn-default flex items-center"
|
||||
onClick={handleExportReport}
|
||||
@@ -124,7 +124,7 @@ export function AIAnalysis({ analysisData, score, onConfirmResults }: AIAnalysis
|
||||
>
|
||||
<i className="ri-check-double-line mr-1"></i> 确认评查结果
|
||||
</button>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -175,17 +175,20 @@ export function FilePreview({ fileContent, reviewPoints, activeReviewPointResult
|
||||
// 如果有目标页码,并且与上次不同或activeReviewPointId变化了,则执行跳转
|
||||
if (targetPage && numPages && targetPage <= numPages && (targetPage !== prevTargetPageRef.current || activeReviewPointResultId)) {
|
||||
prevTargetPageRef.current = targetPage;
|
||||
let newTargetPage = targetPage;
|
||||
try {
|
||||
// 安全地访问ocrResult
|
||||
if (fileContent.ocrResult && fileContent.ocrResult.__meta && fileContent.ocrResult.__meta.page_offset) {
|
||||
// 可以根据需要使用page_offset调整目标页面
|
||||
newTargetPage = targetPage + fileContent.ocrResult.__meta.page_offset;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("访问ocrResult时出错:", error);
|
||||
toastService.error("访问ocrResult时出错:" + (error instanceof Error ? error.message : '未知错误'));
|
||||
}
|
||||
const newTargetPage = targetPage;
|
||||
// let newTargetPage = targetPage;
|
||||
// console.log("targetPage:", targetPage);
|
||||
// console.log("fileContent:", fileContent);
|
||||
// try {
|
||||
// // 安全地访问ocrResult
|
||||
// if (fileContent.ocrResult && fileContent.ocrResult.__meta && fileContent.ocrResult.__meta.page_offset) {
|
||||
// // 可以根据需要使用page_offset调整目标页面
|
||||
// newTargetPage = targetPage + fileContent.ocrResult.__meta.page_offset;
|
||||
// }
|
||||
// } catch (error) {
|
||||
// console.error("访问ocrResult时出错:", error);
|
||||
// toastService.error("访问ocrResult时出错:" + (error instanceof Error ? error.message : '未知错误'));
|
||||
// }
|
||||
|
||||
const pageElement = document.getElementById(`page-${newTargetPage}`);
|
||||
if (pageElement) {
|
||||
|
||||
@@ -73,8 +73,14 @@ export function Toast({
|
||||
// 计算消息行数(用于可能的额外样式调整)
|
||||
useEffect(() => {
|
||||
if (message) {
|
||||
// 简单估算行数: 假设每行平均40个字符,+1确保有足够空间
|
||||
const estimatedLines = Math.ceil(message.length / 40) + 1;
|
||||
// 更好地估算中文文本行数:假设每行平均25个中文字符(或50个英文字符)
|
||||
const estimatedChars = message.split('').reduce((count, char) => {
|
||||
// 判断是否为中文字符(粗略判断)
|
||||
const isChinese = /[\u4e00-\u9fa5]/.test(char);
|
||||
return count + (isChinese ? 2 : 1); // 中文字符算2个宽度单位
|
||||
}, 0);
|
||||
|
||||
const estimatedLines = Math.ceil(estimatedChars / 50);
|
||||
setMessageLines(Math.max(1, Math.min(estimatedLines, 10))); // 最小1行,最大10行
|
||||
}
|
||||
}, [message]);
|
||||
@@ -91,15 +97,20 @@ export function Toast({
|
||||
// 自动关闭
|
||||
useEffect(() => {
|
||||
if (isOpen && autoClose && !isHovered) {
|
||||
// 根据消息长度调整显示时间,长消息显示更长时间
|
||||
// 根据消息长度调整显示时间,较长消息显示更长时间
|
||||
const messageLength = message.length;
|
||||
const baseDelay = autoCloseDelay || DEFAULT_AUTO_CLOSE_DELAY;
|
||||
|
||||
// 按照文本长度比例延长显示时间
|
||||
const adjustedDelay = Math.min(
|
||||
autoCloseDelay + (message.length > 100 ? 2000 : 0),
|
||||
10000 // 最长不超过10秒
|
||||
baseDelay + (messageLength > 20 ? messageLength * 30 : 0),
|
||||
15000 // 最长不超过15秒
|
||||
);
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
handleClose();
|
||||
}, adjustedDelay);
|
||||
|
||||
return () => clearTimeout(timer);
|
||||
}
|
||||
}, [isOpen, autoClose, autoCloseDelay, handleClose, message, isHovered]);
|
||||
@@ -139,6 +150,42 @@ export function Toast({
|
||||
}
|
||||
}, [handleClose]);
|
||||
|
||||
// 处理长文本
|
||||
const formatMessage = (text: string) => {
|
||||
// 清理文本中的多余空白,但保留换行符
|
||||
const cleanedText = text.replace(/[ \t]+/g, ' ');
|
||||
|
||||
// 处理中文文本最后两个字符换行问题
|
||||
const fixChineseWrapping = (content: string) => {
|
||||
// 如果内容长度小于3,或已有换行符,直接返回
|
||||
if (content.length < 3 || content.includes('\n')) {
|
||||
return content;
|
||||
}
|
||||
|
||||
// 检测是否是中文文本
|
||||
const isChinese = /[\u4e00-\u9fa5]/.test(content);
|
||||
if (!isChinese) {
|
||||
return content;
|
||||
}
|
||||
|
||||
// 在中文文本中,添加零宽空格避免最后两个字符换行
|
||||
// 在文本末尾前两个字符之间添加零宽不换行空格,防止它们被分开
|
||||
return content.slice(0, -2) + '\u2060' + content.slice(-2);
|
||||
};
|
||||
|
||||
// 如果文本包含换行符,按换行符分割
|
||||
if (cleanedText.includes('\n')) {
|
||||
return cleanedText.split('\n').map((line, index) => (
|
||||
<div key={index} className="toast-message-line">
|
||||
{fixChineseWrapping(line)}
|
||||
</div>
|
||||
));
|
||||
}
|
||||
|
||||
// 如果没有换行符,直接返回整个文本,应用修复
|
||||
return fixChineseWrapping(cleanedText);
|
||||
};
|
||||
|
||||
// 如果通知未打开,不渲染
|
||||
if (!isOpen || !portalElement) {
|
||||
return null;
|
||||
@@ -147,7 +194,7 @@ export function Toast({
|
||||
// 使用 Portal 渲染通知
|
||||
return createPortal(
|
||||
<div
|
||||
className={`toast toast-${type} ${isClosing ? 'closing' : ''} ${className} ${messageLines > 3 ? 'toast-multiline' : ''}`}
|
||||
className={`toast toast-${type} ${isClosing ? 'closing' : ''} ${className} ${messageLines > 1 ? 'toast-multiline' : ''}`}
|
||||
role="status"
|
||||
aria-live="polite"
|
||||
onMouseEnter={handleMouseEnter}
|
||||
@@ -158,7 +205,7 @@ export function Toast({
|
||||
{renderIcon()}
|
||||
</div>
|
||||
<div className="toast-message">
|
||||
{message}
|
||||
{formatMessage(message)}
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
|
||||
@@ -27,17 +27,17 @@
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
padding: 12px 16px;
|
||||
display: flex;
|
||||
align-items: flex-start; /* 改为flex-start让图标和文本从顶部对齐,更好地支持多行文本 */
|
||||
align-items: flex-start;
|
||||
justify-content: space-between;
|
||||
width: fit-content; /* 更好地适应内容宽度 */
|
||||
min-width: 300px; /* 最小宽度 */
|
||||
max-width: 100%; /* 相对于容器的最大宽度 */
|
||||
width: max-content;
|
||||
min-width: 300px;
|
||||
max-width: 450px;
|
||||
animation: slideInDown 0.3s ease forwards;
|
||||
overflow: hidden;
|
||||
overflow: visible;
|
||||
pointer-events: auto;
|
||||
border-left: 4px solid #1890ff;
|
||||
margin: 0 auto; /* 水平居中 */
|
||||
transition: width 0.2s ease-out; /* 添加平滑的宽度过渡效果 */
|
||||
margin: 0 auto;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* 多行文本的Toast样式调整 */
|
||||
@@ -52,25 +52,25 @@
|
||||
|
||||
.toast-content {
|
||||
display: flex;
|
||||
/* align-items: flex-start; 改为flex-start让图标和文本从顶部对齐 */
|
||||
align-items: center;
|
||||
align-items: flex-start;
|
||||
flex: 1;
|
||||
min-width: 0; /* 确保flex子项不会溢出父容器 */
|
||||
margin-right: 8px; /* 给关闭按钮留出空间 */
|
||||
min-width: 0;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
/* 图标容器 */
|
||||
.toast-icon-wrapper {
|
||||
margin-right: 12px;
|
||||
flex-shrink: 0;
|
||||
margin-top: 2px; /* 微调图标位置,与文本第一行更好地对齐 */
|
||||
margin-top: 2px;
|
||||
width: 24px;
|
||||
}
|
||||
|
||||
/* 通知图标 */
|
||||
.toast-icon {
|
||||
font-size: 20px;
|
||||
height: 24px;
|
||||
width: 24px;
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@@ -113,16 +113,39 @@
|
||||
/* 消息样式 */
|
||||
.toast-message {
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
word-break: break-word; /* 允许在任何字符处换行 */
|
||||
word-wrap: break-word; /* 长词自动换行 */
|
||||
white-space: pre-wrap; /* 保留空格和换行,但允许文本换行 */
|
||||
overflow-wrap: break-word; /* 确保长单词也能换行 */
|
||||
flex: 1;
|
||||
min-width: 0; /* 确保flex子项不会溢出父容器 */
|
||||
max-height: none; /* 移除最大高度限制,让内容自然增长 */
|
||||
max-width: calc(100% - 60px); /* 确保有足够空间给图标和关闭按钮 */
|
||||
min-width: 0;
|
||||
text-align: left;
|
||||
padding: 1px 0;
|
||||
|
||||
/* 简化文本样式 */
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
/* 消息行样式 */
|
||||
.toast-message-line {
|
||||
display: block;
|
||||
margin-bottom: 3px;
|
||||
}
|
||||
|
||||
.toast-message-line:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* 对于中文文本特别处理 */
|
||||
:lang(zh) .toast-message,
|
||||
:lang(zh-CN) .toast-message,
|
||||
:lang(zh-TW) .toast-message {
|
||||
/* 中文特殊处理 */
|
||||
text-indent: 0; /* 确保没有首行缩进 */
|
||||
text-align-last: left; /* 确保最后一行也左对齐 */
|
||||
}
|
||||
|
||||
/* 对于英文文本,特别处理 */
|
||||
.toast-message:lang(en) {
|
||||
word-break: normal;
|
||||
}
|
||||
|
||||
/* 关闭按钮 */
|
||||
@@ -141,8 +164,8 @@
|
||||
margin-left: 8px;
|
||||
flex-shrink: 0;
|
||||
padding: 0;
|
||||
align-self: flex-start; /* 按钮始终位于顶部 */
|
||||
margin-top: 2px; /* 微调按钮位置 */
|
||||
align-self: flex-start;
|
||||
margin-top: 2px;
|
||||
}
|
||||
|
||||
.toast-close:hover {
|
||||
@@ -204,7 +227,8 @@
|
||||
|
||||
.toast {
|
||||
min-width: 250px;
|
||||
width: auto; /* 在平板上自动调整宽度 */
|
||||
max-width: 400px;
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,8 +242,9 @@
|
||||
|
||||
.toast {
|
||||
padding: 10px 12px;
|
||||
min-width: 0; /* 移动设备上取消最小宽度限制 */
|
||||
width: 100%; /* 在移动设备上占满容器宽度 */
|
||||
min-width: 0;
|
||||
max-width: 330px;
|
||||
width: calc(100% - 20px);
|
||||
}
|
||||
|
||||
.toast-icon {
|
||||
@@ -230,7 +255,7 @@
|
||||
|
||||
.toast-message {
|
||||
font-size: 13px;
|
||||
max-width: calc(100% - 50px); /* 移动设备上调整最大宽度 */
|
||||
max-width: calc(100% - 50px);
|
||||
}
|
||||
|
||||
.toast-close {
|
||||
|
||||
Reference in New Issue
Block a user