统一结果图标悬停时都会展示对应的规则类型显示

This commit is contained in:
2025-05-30 23:12:52 +08:00
parent e9c1db64d2
commit 3e47f4752a
2 changed files with 133 additions and 30 deletions
+129 -26
View File
@@ -44,6 +44,28 @@ const getCompareMethodText = (method?: string): string => {
return typeof text === 'string' ? text : String(text); return typeof text === 'string' ? text : String(text);
}; };
/**
* 规则类型映射
* 将后端返回的规则类型英文值映射为友好的中文显示
*/
const ruleTypeMap: Record<string, string> = {
'exists': '有无判断',
'format': '格式判断',
'logic': '逻辑判断',
'regex': '正则表达式',
// 可以根据需要添加更多映射
};
/**
* 获取规则类型的中文显示
* @param type 规则类型的原始值
* @returns 映射后的中文显示文本
*/
const getRuleTypeText = (type?: string): string => {
if (!type) return '';
return ruleTypeMap[type] || type;
};
/** /**
* 评查点类型定义 * 评查点类型定义
* 用于展示单个评查结果 * 用于展示单个评查结果
@@ -200,13 +222,13 @@ export function ReviewPointsList({
} }
// 将参数输出到控制台 // 将参数输出到控制台
console.log('评查点审核操作', { // console.log('评查点审核操作', {
id: reviewPointResultId, // id: reviewPointResultId,
editAuditStatusId: editAuditStatusId, // editAuditStatusId: editAuditStatusId,
action: action, // action: action,
content: message, // content: message,
status: action === 'approve' ? 'true' : (action === 'reject' ? 'false' : 'review') // status: action === 'approve' ? 'true' : (action === 'reject' ? 'false' : 'review')
}); // });
// 清除编辑状态 // 清除编辑状态
setEditingReviewPoint(null); setEditingReviewPoint(null);
@@ -460,7 +482,7 @@ export function ReviewPointsList({
const renderHumanReviewBadge = (reviewPoint: ReviewPoint) => { const renderHumanReviewBadge = (reviewPoint: ReviewPoint) => {
if (reviewPoint.postAction === 'manual') { if (reviewPoint.postAction === 'manual') {
return ( return (
<span className="status-badge status-waiting ml-2 mt-1 text-xs"> <span className="status-badge status-waiting mt-1 text-xs">
<i className="ri-user-line mr-1"></i> <i className="ri-user-line mr-1"></i>
</span> </span>
); );
@@ -498,23 +520,28 @@ export function ReviewPointsList({
const renderContent = (reviewPoint: ReviewPoint, otherRules: Array<Record<string, unknown>>) => { const renderContent = (reviewPoint: ReviewPoint, otherRules: Array<Record<string, unknown>>) => {
return ( return (
<> <>
{/* 渲染其他规则分组 */} {/* 渲染其他规则分组 */}
{otherRules.map((rule, index) => { {otherRules.map((rule, index) => {
return <div key={`other-rule-${index}`}>{renderOtherRule(rule, reviewPoint)}</div>; return <div key={`other-rule-${index}`}>{renderOtherRule(rule, reviewPoint)}</div>;
})} })}
<div key="line" className=" bg-gray-50 rounded border border-gray-200 text-xs mb-3"></div> {/* <div key="line" className=" bg-gray-50 rounded border border-gray-200 text-xs mb-3"></div> */}
{/* 渲染各个一致性的规则分组 */} {/* 渲染各个一致性的规则分组 */}
{reviewPoint.evaluatedPointResultsLog?.rules?.map((rule, index) => { {reviewPoint.evaluatedPointResultsLog?.rules?.map((rule, index) => {
// console.log('rule-------', rule); // console.log('rule-------', rule);
if (rule.type === 'consistency') { if (rule.type === 'consistency') {
// console.log('rule-------', rule); // console.log('rule-------', rule);
return <div key={`rule-${index}`}>{renderConsistencyRule(rule, reviewPoint)}</div>; return <div key={`rule-${index}`}>
<div key="line" className=" bg-gray-50 rounded border border-gray-200 text-xs mb-3"></div>
{renderConsistencyRule(rule, reviewPoint)}
</div>;
} }
if (rule.type === 'ai') { if (rule.type === 'ai') {
return <div key={`rule-${index}`}>{renderModelRule(rule, reviewPoint)}</div>; return <div key={`rule-${index}`}>
<div key="line" className=" bg-gray-50 rounded border border-gray-200 text-xs mb-3"></div>
{renderModelRule(rule, reviewPoint)}
</div>;
} }
@@ -858,6 +885,7 @@ export function ReviewPointsList({
? "comparison-item match" ? "comparison-item match"
: "comparison-item mismatch"; : "comparison-item mismatch";
// console.log('currentchain-------', chain);
// 如果是长链(3个或以上元素) // 如果是长链(3个或以上元素)
if (isLongChain) { if (isLongChain) {
// console.log('currentlongchain-------', chain); // console.log('currentlongchain-------', chain);
@@ -947,12 +975,38 @@ export function ReviewPointsList({
))} ))}
</div> </div>
</div> </div>
<div className="status-indicator w-8 flex items-center justify-center" > <div className="status-indicator w-8 flex items-center justify-center group relative" >
{res ? ( {res ? (
<i className="ri-check-line text-success text-base" ></i> <i className="ri-check-line text-success text-base" ></i>
) : ( ) : (
<i className="ri-alert-line text-warning text-base" ></i> <i className="ri-alert-line text-warning text-base" ></i>
)} )}
{/* 悬停提示框 - 横向布局 */}
<div className="w-auto absolute hidden group-hover:block right-full top-1/2 transform -translate-y-1/2 mr-2 z-100">
<div className="bg-white shadow-md rounded-md p-1 border border-gray-200">
{/* <div className="text-xs font-medium text-gray-700 w-auto">规则检查结果</div> */}
<div className="flex flex-row gap-2 overflow-x-auto">
{chain.map((item, idx) =>
idx >= 1 ? (
<div key={idx} className={`rounded-md flex flex-row items-center
${
res ? 'bg-green-100 text-green-600': 'bg-yellow-100 text-yellow-600'
}`}>
<div className="text-xs text-gray-600 whitespace-nowrap pl-2">
{typeof item.compareMethod === 'object'
? ''
: getCompareMethodText(item.compareMethod)}
</div>
<div className={`p-1 text-xs font-medium rounded-full min-w-[50px] text-center`}>
{res ? '通过' : '不通过'}
</div>
</div>
) : null
)}
</div>
</div>
<div className="absolute top-1/2 right-0 transform translate-x-1/2 -translate-y-1/2 rotate-45 w-2 h-2 bg-white border-t border-r border-gray-200"></div>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -960,7 +1014,7 @@ export function ReviewPointsList({
} }
// 如果是标准的成对比较(2个元素) // 如果是标准的成对比较(2个元素)
// console.log('currentpairchain-------', chain);
return ( return (
<div <div
key={`pair_${chainIndex}`} key={`pair_${chainIndex}`}
@@ -1019,12 +1073,34 @@ export function ReviewPointsList({
hover:z-10 hover:overflow-auto rounded transition-all duration-300 ease-in-out cursor-text max-h-96">{chain[1].data.value?.toString() || ''}</div> hover:z-10 hover:overflow-auto rounded transition-all duration-300 ease-in-out cursor-text max-h-96">{chain[1].data.value?.toString() || ''}</div>
</button> </button>
</div> </div>
<div className="status-indicator tooltip w-8 flex items-center justify-center"> <div className="status-indicator tooltip w-8 flex items-center justify-center group relative">
{res ? ( {res ? (
<i className="ri-check-line text-success text-base"></i> <i className="ri-check-line text-success text-base"></i>
) : ( ) : (
<i className="ri-alert-line text-warning text-base"></i> <i className="ri-alert-line text-warning text-base"></i>
)} )}
{/* 悬停提示框 - 横向布局 */}
<div className="w-auto absolute hidden group-hover:block right-full top-1/2 transform -translate-y-1/2 mr-2 z-100">
<div className="bg-white shadow-md rounded-md p-1 border border-gray-200">
<div className="flex flex-row gap-2 overflow-x-auto">
<div key={chain[1].compareMethod} className={`rounded-md flex flex-row items-center ${
res
? 'bg-green-100 text-green-600'
: 'bg-yellow-100 text-yellow-600'
}`}>
<div className="text-xs text-gray-600 whitespace-nowrap pl-1">
{typeof chain[1].compareMethod === 'object'
? ''
: getCompareMethodText(chain[1].compareMethod)}
</div>
<div className={`p-1 text-xs font-medium rounded-full min-w-[50px] text-center`}>
{res ? '通过' : '不通过'}
</div>
</div>
</div>
</div>
<div className="absolute top-1/2 right-0 transform translate-x-1/2 -translate-y-1/2 rotate-45 w-2 h-2 bg-white border-t border-r border-gray-200"></div>
</div>
</div> </div>
</div> </div>
); );
@@ -1165,7 +1241,7 @@ export function ReviewPointsList({
? 'bg-green-100 text-green-600' ? 'bg-green-100 text-green-600'
: 'bg-yellow-100 text-yellow-600' : 'bg-yellow-100 text-yellow-600'
}`}> }`}>
<div className="text-xs text-gray-600 min-w-[50px] text-center">{typeKey}</div> <div className="text-xs text-gray-600 pl-1 whitespace-nowrap">{getRuleTypeText(typeKey)}</div>
<div className={`p-1 text-xs font-medium rounded-full min-w-[50px] text-center`}> <div className={`p-1 text-xs font-medium rounded-full min-w-[50px] text-center`}>
{typeValue.res ? '通过' : '不通过'} {typeValue.res ? '通过' : '不通过'}
</div> </div>
@@ -1206,9 +1282,9 @@ export function ReviewPointsList({
const fieldElements: JSX.Element[] = []; const fieldElements: JSX.Element[] = [];
// 先存放一条粗的横线 // 先存放一条粗的横线
fieldElements.push( // fieldElements.push(
<div key="line" className=" bg-gray-50 rounded border border-gray-200 text-xs mb-3"></div> // <div key="line" className=" bg-gray-50 rounded border border-gray-200 text-xs mb-3"></div>
); // );
// 遍历fields,获取每个字段的值并生成对应的JSX元素 // 遍历fields,获取每个字段的值并生成对应的JSX元素
if (config.fields) { if (config.fields) {
@@ -1224,6 +1300,8 @@ export function ReviewPointsList({
if (value.page && typeof onReviewPointSelect === 'function') { if (value.page && typeof onReviewPointSelect === 'function') {
e.stopPropagation(); e.stopPropagation();
onReviewPointSelect(reviewPoint.id, Number(value.page)); onReviewPointSelect(reviewPoint.id, Number(value.page));
}else{
toastService.error(`没有找到${key}对应的索引内容`);
} }
}} }}
onKeyDown={(e) => { onKeyDown={(e) => {
@@ -1232,6 +1310,8 @@ export function ReviewPointsList({
if (value.page && typeof onReviewPointSelect === 'function') { if (value.page && typeof onReviewPointSelect === 'function') {
e.preventDefault(); e.preventDefault();
onReviewPointSelect(reviewPoint.id, Number(value.page)); onReviewPointSelect(reviewPoint.id, Number(value.page));
}else{
toastService.error(`没有找到${key}对应的索引内容`);
} }
} }
}} }}
@@ -1242,6 +1322,10 @@ export function ReviewPointsList({
{/* 字段名称 */} {/* 字段名称 */}
<div className="text-xs text-left text-gray-500 mb-1"> <div className="text-xs text-left text-gray-500 mb-1">
{key} {key}
{/* 没有抽取到目录内容,page和value都为空 */}
{!value.page && !value.value && (
<i className="ri-information-line text-red-500 text-xs ml-1"></i>
)}
{/* 缺失显示 */} {/* 缺失显示 */}
{!res && ( {!res && (
<span className="ml-2 text-xs text-yellow-500"> <span className="ml-2 text-xs text-yellow-500">
@@ -1273,6 +1357,25 @@ export function ReviewPointsList({
) : ( ) : (
<i className="ri-alert-line text-warning text-base hover:text-yellow-800" ></i> <i className="ri-alert-line text-warning text-base hover:text-yellow-800" ></i>
)} )}
{/* 悬停提示框 - 横向布局 */}
<div className="w-auto absolute hidden group-hover:block right-full top-1/2 transform -translate-y-1/2 mr-2 z-100">
<div className="bg-white shadow-md rounded-md p-1 border border-gray-200">
{/* <div className="text-xs font-medium text-gray-700 w-auto">规则检查结果</div> */}
<div className="flex flex-row gap-2 overflow-x-auto">
<div className={`rounded-md flex flex-row items-center ${
res
? 'bg-green-100 text-green-600'
: 'bg-yellow-100 text-yellow-600'
}`}>
<div className="text-xs text-gray-600 pl-1 whitespace-nowrap"></div>
<div className={`p-1 text-xs font-medium rounded-full min-w-[50px] text-center`}>
{res ? '通过' : '不通过'}
</div>
</div>
</div>
</div>
<div className="absolute top-1/2 right-0 transform translate-x-1/2 -translate-y-1/2 rotate-45 w-2 h-2 bg-white border-t border-r border-gray-200"></div>
</div>
</div> </div>
</button> </button>
); );
@@ -1565,7 +1668,7 @@ export function ReviewPointsList({
return ( return (
<> <>
{checkContentPage(reviewPoint).pageIndex === 0 && ( {checkContentPage(reviewPoint).pageIndex === 0 && (
<p className="text-xs text-red-500 select-text text-left"></p> <p className="text-xs text-red-500 select-text text-left mb-1"></p>
)} )}
<div className="mt-2"> <div className="mt-2">
{/* {reviewPoint.suggestion && ( {/* {reviewPoint.suggestion && (
@@ -1632,7 +1735,7 @@ export function ReviewPointsList({
return ( return (
<> <>
{checkContentPage(reviewPoint).pageIndex === 0 && ( {checkContentPage(reviewPoint).pageIndex === 0 && (
<p className="text-xs text-red-500 select-text text-left"></p> <p className="text-xs text-red-500 select-text text-left mb-1"></p>
)} )}
{/* 评查点内容显示区域 */} {/* 评查点内容显示区域 */}
{reviewPoint.content && Object.entries(reviewPoint.content).length > 0 && ( {reviewPoint.content && Object.entries(reviewPoint.content).length > 0 && (
@@ -1646,11 +1749,11 @@ export function ReviewPointsList({
} }
return ( return (
<div className="mt-2"> <div>
{/* 没有索引内容提示 */} {/* 没有索引内容提示 */}
{checkContentPage(reviewPoint).pageIndex === 0 && ( {checkContentPage(reviewPoint).pageIndex === 0 && (
<p className="text-xs text-red-500 select-text text-left"></p> <p className="text-xs text-red-500 select-text text-left mb-1"></p>
)} )}
{/* 建议内容显示区域 */} {/* 建议内容显示区域 */}
@@ -1886,12 +1989,12 @@ export function ReviewPointsList({
key={reviewPoint.id} key={reviewPoint.id}
className={`rounded-md review-point-item ${activeReviewPointResultId === reviewPoint.id ? 'active border-l-4 border-l-[#00684a] shadow-md' : 'border-l-4 border-l-transparent'} className={`rounded-md review-point-item ${activeReviewPointResultId === reviewPoint.id ? 'active border-l-4 border-l-[#00684a] shadow-md' : 'border-l-4 border-l-transparent'}
transition-all duration-300 ease-in-out transition-all duration-300 ease-in-out
hover:shadow-lg hover:-translate-x-0.5 hover:bg-[rgba(0,0,0,0.02)]`} hover:shadow-lg hover:-translate-x-0.5 hover:bg-[rgba(0,0,0,0.02)] my-2`}
role="button" role="button"
tabIndex={0} tabIndex={0}
style={{ userSelect: 'text' }} style={{ userSelect: 'text' }}
onClick={() => { onClick={() => {
console.log('reviewPoint', reviewPoint); // console.log('reviewPoint', reviewPoint);
handleReviewPointClick(reviewPoint.id); handleReviewPointClick(reviewPoint.id);
}} }}
onKeyDown={(e) => { onKeyDown={(e) => {
@@ -1902,7 +2005,7 @@ export function ReviewPointsList({
> >
{/* 评查点标题和状态 */} {/* 评查点标题和状态 */}
{/* 评查点名称 pointName*/} {/* 评查点名称 pointName*/}
<div className="flex justify-between items-center"> <div className="flex justify-between items-center mb-2">
<div className='flex flex-col'> <div className='flex flex-col'>
<div className="review-point-title flex-1 text-left text-blue-500">{reviewPoint.pointName}</div> <div className="review-point-title flex-1 text-left text-blue-500">{reviewPoint.pointName}</div>
<div className="review-point-header flex justify-between items-start"> <div className="review-point-header flex justify-between items-start">
+2 -2
View File
@@ -215,7 +215,7 @@
.review-point-item { .review-point-item {
/* box-sizing: border-box; */ /* box-sizing: border-box; */
/* margin: 10px; */ /* margin: 10px; */
padding: 10px; padding: 5px 10px 10px 10px;
/* border-bottom: 1px solid var(--border-color); */ /* border-bottom: 1px solid var(--border-color); */
cursor: pointer; cursor: pointer;
width: 100%; width: 100%;
@@ -225,7 +225,7 @@
.review-point-item:hover { .review-point-item:hover {
/* background-color: #f5f5f5; */ /* background-color: #f5f5f5; */
/* box-shadow: 10px 10px 10px 3px rgba(250, 173, 20, 0.6); */ /* box-shadow: 10px 10px 10px 3px rgba(250, 173, 20, 0.6); */
transform: translateX(-1px); transform: translateX(-2px);
box-shadow: 1px 4px 10px rgba(0, 0, 0, 0.08); box-shadow: 1px 4px 10px rgba(0, 0, 0, 0.08);
} }