revert: reset to 32bee87 for clean text_bbox baseline
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -93,32 +93,6 @@ export interface CharPosition {
|
||||
score: number; // OCR识别置信度
|
||||
}
|
||||
|
||||
/**
|
||||
* text_bbox -> CharPosition[] 转换
|
||||
* GraphRAG 抽取结果只有 text_bbox (段落级坐标), 没有 char_positions (字符级坐标)。
|
||||
* 将 text_bbox 转为单个 CharPosition 矩形框, 让 PdfPreview 的高亮逻辑复用。
|
||||
*/
|
||||
function resolveCharPositions(data: any): CharPosition[] | undefined {
|
||||
// 优先用 char_positions
|
||||
if (data?.char_positions && data.char_positions.length > 0) {
|
||||
return data.char_positions;
|
||||
}
|
||||
// fallback: text_bbox -> CharPosition[]
|
||||
if (data?.text_bbox) {
|
||||
const b = data.text_bbox;
|
||||
if (b.x_min != null && b.y_min != null && b.x_max != null && b.y_max != null
|
||||
&& (b.x_max - b.x_min) > 0 && (b.y_max - b.y_min) > 0) {
|
||||
return [{
|
||||
box: [[b.x_min, b.y_min], [b.x_max, b.y_min], [b.x_max, b.y_max], [b.x_min, b.y_max]],
|
||||
char: '',
|
||||
score: 1
|
||||
}];
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 评查点类型定义
|
||||
* 用于展示单个评查结果
|
||||
@@ -1538,7 +1512,7 @@ export function ReviewPointsList({
|
||||
for (const item of chain) {
|
||||
if (item.data.page && typeof onReviewPointSelect === 'function') {
|
||||
hasPage = true;
|
||||
onReviewPointSelect(reviewPoint.id, Number(item.data.page), resolveCharPositions(item.data), item.data.value);
|
||||
onReviewPointSelect(reviewPoint.id, Number(item.data.page), item.data.char_positions, item.data.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1552,7 +1526,7 @@ export function ReviewPointsList({
|
||||
// 遍历chain找到第一个有效的page
|
||||
for (const item of chain) {
|
||||
if (item.data.page && typeof onReviewPointSelect === 'function') {
|
||||
onReviewPointSelect(reviewPoint.id, Number(item.data.page), resolveCharPositions(item.data), item.data.value);
|
||||
onReviewPointSelect(reviewPoint.id, Number(item.data.page), item.data.char_positions, item.data.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1592,11 +1566,11 @@ export function ReviewPointsList({
|
||||
// 假设onReviewPointSelect在作用域内可用
|
||||
const reviewPointId = reviewPoint.id as string;
|
||||
if (reviewPointId && typeof onReviewPointSelect === 'function') {
|
||||
onReviewPointSelect(reviewPointId, Number(item.data.page), resolveCharPositions(item.data), item.data.value);
|
||||
onReviewPointSelect(reviewPointId, Number(item.data.page), item.data.char_positions, item.data.value);
|
||||
}
|
||||
}
|
||||
else if(reviewPoint.contentPage && reviewPoint.contentPage[item.field]){
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[item.field]), resolveCharPositions(item.data), item.data.value);
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[item.field]), item.data.char_positions, item.data.value);
|
||||
}
|
||||
else{
|
||||
toastService.error(`没有找到${item.field}对应的索引内容`);
|
||||
@@ -1675,11 +1649,11 @@ export function ReviewPointsList({
|
||||
if (chain[0].data.page) {
|
||||
const reviewPointId = reviewPoint.id as string;
|
||||
if (reviewPointId && typeof onReviewPointSelect === 'function') {
|
||||
onReviewPointSelect(reviewPointId, chain[0].data.page, resolveCharPositions(chain[0].data), chain[0].data.value);
|
||||
onReviewPointSelect(reviewPointId, chain[0].data.page, chain[0].data.char_positions, chain[0].data.value);
|
||||
}
|
||||
}
|
||||
else if(reviewPoint.contentPage && reviewPoint.contentPage[chain[0].field]){
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[chain[0].field]), resolveCharPositions(chain[0].data), chain[0].data.value);
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[chain[0].field]), chain[0].data.char_positions, chain[0].data.value);
|
||||
}
|
||||
else{
|
||||
toastService.error(`没有找到${chain[0].field}对应的索引内容`);
|
||||
@@ -1701,11 +1675,11 @@ export function ReviewPointsList({
|
||||
if (chain[1].data.page) {
|
||||
const reviewPointId = reviewPoint.id as string;
|
||||
if (reviewPointId && typeof onReviewPointSelect === 'function') {
|
||||
onReviewPointSelect(reviewPointId, chain[1].data.page, resolveCharPositions(chain[1].data), chain[1].data.value);
|
||||
onReviewPointSelect(reviewPointId, chain[1].data.page, chain[1].data.char_positions, chain[1].data.value);
|
||||
}
|
||||
}
|
||||
else if(reviewPoint.contentPage && reviewPoint.contentPage[chain[1].field]){
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[chain[1].field]), resolveCharPositions(chain[1].data), chain[1].data.value);
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[chain[1].field]), chain[1].data.char_positions, chain[1].data.value);
|
||||
}
|
||||
else{
|
||||
toastService.error(`没有找到${chain[1].field}对应的索引内容`);
|
||||
@@ -1841,9 +1815,9 @@ export function ReviewPointsList({
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (mainTypeValue.page && typeof onReviewPointSelect === 'function') {
|
||||
onReviewPointSelect(reviewPoint.id, Number(mainTypeValue.page), resolveCharPositions(mainTypeValue), mainTypeValue.value);
|
||||
onReviewPointSelect(reviewPoint.id, Number(mainTypeValue.page), mainTypeValue.char_positions, mainTypeValue.value);
|
||||
}else if(reviewPoint.contentPage && reviewPoint.contentPage[fieldKey]){
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[fieldKey]), resolveCharPositions(mainTypeValue), mainTypeValue.value);
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[fieldKey]), mainTypeValue.char_positions, mainTypeValue.value);
|
||||
}else{
|
||||
toastService.error(`没有找到${fieldKey}对应的索引内容`);
|
||||
}
|
||||
@@ -1852,9 +1826,9 @@ export function ReviewPointsList({
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
if (mainTypeValue.page && typeof onReviewPointSelect === 'function') {
|
||||
onReviewPointSelect(reviewPoint.id, Number(mainTypeValue.page), resolveCharPositions(mainTypeValue), mainTypeValue.value);
|
||||
onReviewPointSelect(reviewPoint.id, Number(mainTypeValue.page), mainTypeValue.char_positions, mainTypeValue.value);
|
||||
}else if(reviewPoint.contentPage && reviewPoint.contentPage[fieldKey]){
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[fieldKey]), resolveCharPositions(mainTypeValue), mainTypeValue.value);
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[fieldKey]), mainTypeValue.char_positions, mainTypeValue.value);
|
||||
}else{
|
||||
toastService.error(`没有找到${fieldKey}对应的索引内容`);
|
||||
}
|
||||
@@ -1922,7 +1896,6 @@ export function ReviewPointsList({
|
||||
fields?: Record<string, {
|
||||
page: number | string;
|
||||
value: string;
|
||||
res: boolean;
|
||||
char_positions?: CharPosition[];
|
||||
}>;
|
||||
ai_suggestion?: {
|
||||
@@ -1981,14 +1954,14 @@ export function ReviewPointsList({
|
||||
<button
|
||||
key={`field-${index}`}
|
||||
className={`border border-gray w-full
|
||||
rounded-md overflow-hidden mb-2 ${value.res ? 'bg-[rgba(246,255,237,1)]' : 'bg-[rgba(255,251,230,1)]'} flex
|
||||
hover:shadow-[0_0_10px_rgba(0,0,0,0.1)] ${value.res ? 'hover:bg-[rgba(0,128,0,0.1)]' : 'hover:bg-[rgba(255,255,0,0.1)]'}`}
|
||||
rounded-md overflow-hidden mb-2 ${res ? 'bg-[rgba(246,255,237,1)]' : 'bg-[rgba(255,251,230,1)]'} flex
|
||||
hover:shadow-[0_0_10px_rgba(0,0,0,0.1)] ${res ? 'hover:bg-[rgba(0,128,0,0.1)]' : 'hover:bg-[rgba(255,255,0,0.1)]'}`}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
if (value.page && typeof onReviewPointSelect === 'function') {
|
||||
onReviewPointSelect(reviewPoint.id, Number(value.page), resolveCharPositions(value), value.value);
|
||||
onReviewPointSelect(reviewPoint.id, Number(value.page), value.char_positions, value.value);
|
||||
}else if(reviewPoint.contentPage && reviewPoint.contentPage[key]){
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[key]), resolveCharPositions(value), value.value);
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[key]), value.char_positions, value.value);
|
||||
}else{
|
||||
toastService.error(`没有找到${key}对应的索引内容`);
|
||||
}
|
||||
@@ -1998,9 +1971,9 @@ export function ReviewPointsList({
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
if (value.page && typeof onReviewPointSelect === 'function') {
|
||||
onReviewPointSelect(reviewPoint.id, Number(value.page), resolveCharPositions(value), value.value);
|
||||
onReviewPointSelect(reviewPoint.id, Number(value.page), value.char_positions, value.value);
|
||||
}else if(reviewPoint.contentPage && reviewPoint.contentPage[key]){
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[key]), resolveCharPositions(value), value.value);
|
||||
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[key]), value.char_positions, value.value);
|
||||
}else{
|
||||
toastService.error(`没有找到${key}对应的索引内容`);
|
||||
}
|
||||
@@ -2031,7 +2004,7 @@ export function ReviewPointsList({
|
||||
)}
|
||||
</div>
|
||||
<div className={`w-8 flex items-center justify-center rounded-r-md group relative`}>
|
||||
{value.res ? (
|
||||
{res ? (
|
||||
<i className="ri-check-line text-success text-base hover:text-green-800" ></i>
|
||||
) : (
|
||||
<i className="ri-alert-line text-warning text-base hover:text-yellow-800" ></i>
|
||||
@@ -2048,7 +2021,7 @@ export function ReviewPointsList({
|
||||
<div className={`rounded-md flex flex-row items-center`}>
|
||||
<div className="text-xs text-gray-600 pl-1 whitespace-nowrap">大模型判断:</div>
|
||||
<div className={`p-1 text-xs rounded-full min-w-[50px] text-center`}>
|
||||
{ value.res ? '通过' : '不通过'}
|
||||
{res ? '通过' : '不通过'}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -2717,10 +2690,7 @@ export function ReviewPointsList({
|
||||
{/* <div className='flex flex-col'> */}
|
||||
<div className="flex items-center gap-2 max-w-[75%]">
|
||||
<div className="review-point-title text-left text-blue-500 break-all">{reviewPoint.pointName}</div>
|
||||
{ reviewPoint.pointName === '签署乙方详细信息校验' && (() => {
|
||||
const firstContentKey = reviewPoint.content ? Object.keys(reviewPoint.content)[0] : undefined;
|
||||
const firstContentValue = firstContentKey ? reviewPoint.content![firstContentKey]?.value : undefined;
|
||||
return (
|
||||
{ reviewPoint.pointName === '签署乙方详细信息校验' && (
|
||||
<button
|
||||
className="enterprise-info-btn"
|
||||
style={{
|
||||
@@ -2733,25 +2703,27 @@ export function ReviewPointsList({
|
||||
flexShrink: 0,
|
||||
transition: 'all 0.2s',
|
||||
border: 'none',
|
||||
cursor: firstContentValue ? 'pointer' : 'not-allowed',
|
||||
backgroundColor: firstContentValue ? '#00684a' : '#e5e7eb',
|
||||
color: firstContentValue ? '#ffffff' : '#9ca3af',
|
||||
cursor: reviewPoint.content?.['合同主体信息-乙方名称']?.value ? 'pointer' : 'not-allowed',
|
||||
backgroundColor: reviewPoint.content?.['合同主体信息-乙方名称']?.value ? '#00684a' : '#e5e7eb',
|
||||
color: reviewPoint.content?.['合同主体信息-乙方名称']?.value ? '#ffffff' : '#9ca3af',
|
||||
}}
|
||||
disabled={!firstContentValue}
|
||||
disabled={!reviewPoint.content?.['合同主体信息-乙方名称']?.value}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
const companyName = typeof firstContentValue === 'string' ? firstContentValue : String(firstContentValue || '');
|
||||
const companyNameValue = reviewPoint.content?.['合同主体信息-乙方名称']?.value;
|
||||
// console.log('companyNameValue', companyNameValue);
|
||||
const companyName = typeof companyNameValue === 'string' ? companyNameValue : String(companyNameValue || '');
|
||||
if (companyName) {
|
||||
handleCorporateInfoClick(companyName);
|
||||
}
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
if (firstContentValue) {
|
||||
if (reviewPoint.content?.['合同主体信息-乙方名称']?.value) {
|
||||
e.currentTarget.style.backgroundColor = '#005a3f';
|
||||
}
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
if (firstContentValue) {
|
||||
if (reviewPoint.content?.['合同主体信息-乙方名称']?.value) {
|
||||
e.currentTarget.style.backgroundColor = '#00684a';
|
||||
}
|
||||
}}
|
||||
@@ -2759,12 +2731,8 @@ export function ReviewPointsList({
|
||||
<i className="ri-eye-line"></i>
|
||||
乙方企业信息
|
||||
</button>
|
||||
);
|
||||
})()}
|
||||
{ reviewPoint.pointName === '签署甲方详细信息校验' && (() => {
|
||||
const firstContentKey = reviewPoint.content ? Object.keys(reviewPoint.content)[0] : undefined;
|
||||
const firstContentValue = firstContentKey ? reviewPoint.content![firstContentKey]?.value : undefined;
|
||||
return (
|
||||
)}
|
||||
{ reviewPoint.pointName === '签署甲方详细信息校验' && (
|
||||
<button
|
||||
className="enterprise-info-btn"
|
||||
style={{
|
||||
@@ -2777,25 +2745,26 @@ export function ReviewPointsList({
|
||||
flexShrink: 0,
|
||||
transition: 'all 0.2s',
|
||||
border: 'none',
|
||||
cursor: firstContentValue ? 'pointer' : 'not-allowed',
|
||||
backgroundColor: firstContentValue ? '#00684a' : '#e5e7eb',
|
||||
color: firstContentValue ? '#ffffff' : '#9ca3af',
|
||||
cursor: reviewPoint.content?.['合同主体信息-甲方名称']?.value ? 'pointer' : 'not-allowed',
|
||||
backgroundColor: reviewPoint.content?.['合同主体信息-甲方名称']?.value ? '#00684a' : '#e5e7eb',
|
||||
color: reviewPoint.content?.['合同主体信息-甲方名称']?.value ? '#ffffff' : '#9ca3af',
|
||||
}}
|
||||
disabled={!firstContentValue}
|
||||
disabled={!reviewPoint.content?.['合同主体信息-甲方名称']?.value}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
const companyName = typeof firstContentValue === 'string' ? firstContentValue : String(firstContentValue || '');
|
||||
const companyNameValue = reviewPoint.content?.['合同主体信息-甲方名称']?.value;
|
||||
const companyName = typeof companyNameValue === 'string' ? companyNameValue : String(companyNameValue || '');
|
||||
if (companyName) {
|
||||
handleCorporateInfoClick(companyName);
|
||||
}
|
||||
}}
|
||||
onMouseEnter={(e) => {
|
||||
if (firstContentValue) {
|
||||
if (reviewPoint.content?.['合同主体信息-甲方名称']?.value) {
|
||||
e.currentTarget.style.backgroundColor = '#005a3f';
|
||||
}
|
||||
}}
|
||||
onMouseLeave={(e) => {
|
||||
if (firstContentValue) {
|
||||
if (reviewPoint.content?.['合同主体信息-甲方名称']?.value) {
|
||||
e.currentTarget.style.backgroundColor = '#00684a';
|
||||
}
|
||||
}}
|
||||
@@ -2803,8 +2772,7 @@ export function ReviewPointsList({
|
||||
<i className="ri-eye-line"></i>
|
||||
甲方企业信息
|
||||
</button>
|
||||
);
|
||||
})()}
|
||||
)}
|
||||
</div>
|
||||
{/* <div className="review-point-header flex justify-between items-start">
|
||||
<div className="flex-1 text-left min-w-[25%] font-medium text-[13px]">{reviewPoint.title}</div>
|
||||
|
||||
Reference in New Issue
Block a user