feat: 接入pdf文件的显示高亮效果

This commit is contained in:
2025-11-25 18:23:35 +08:00
parent 87a6cae1d5
commit f76b3a8a92
3 changed files with 145 additions and 346 deletions
+71 -49
View File
@@ -68,6 +68,16 @@ const getRuleTypeText = (type?: string): string => {
return ruleTypeMap[type] || type;
};
/**
* 字符位置类型定义
* 用于定位文档中具体的文字位置
*/
export interface CharPosition {
box: number[][]; // 字符边界框坐标
char: string; // 字符内容
score: number; // OCR识别置信度
}
/**
* 评查点类型定义
* 用于展示单个评查结果
@@ -136,7 +146,7 @@ interface ReviewPointsListProps {
reviewPoints: ReviewPoint[];
statistics: Statistics;
activeReviewPointResultId: string | null;
onReviewPointSelect: (id: string, page?: number) => void;
onReviewPointSelect: (id: string, page?: number, charPositions?: CharPosition[]) => void;
onStatusChange: (id: string, editAuditStatusId: string | number, status: string, message: string) => void;
}
@@ -816,15 +826,15 @@ export function ReviewPointsList({
// console.log('singleReviewPoint-------', singleReviewPoint);
// 检查是否存在配置和pairs数组
const config = singleReviewPoint.config as {
logic?: string;
pairs?: Array<{
sourceField: Record<string, { page: number; value: string }>;
targetField: Record<string, { page: number; value: string }>;
const config = singleReviewPoint.config as {
logic?: string;
pairs?: Array<{
sourceField: Record<string, { page: number; value: string; char_positions?: CharPosition[] }>;
targetField: Record<string, { page: number; value: string; char_positions?: CharPosition[] }>;
res: boolean;
compareMethod?: string;
}>;
selectedFields?: string[]
}>;
selectedFields?: string[]
} | undefined;
if (!config || !config.pairs || !Array.isArray(config.pairs) || config.pairs.length === 0) {
@@ -865,27 +875,28 @@ export function ReviewPointsList({
// 查找链条关系
const findChains = () => {
type ChainItem = {
field: string;
data: {
key: string;
page: number;
value: string
};
type ChainItem = {
field: string;
data: {
key: string;
page: number;
value: string;
char_positions?: CharPosition[];
};
res: boolean;
compareMethod?: string;
compareMethod?: string;
};
const chains: Array<Array<ChainItem>> = [];
const visited = new Set<string>();
// 构建字段映射关系
const fieldMap = new Map<string, Array<{
targetField: string;
const fieldMap = new Map<string, Array<{
targetField: string;
data: {
source: { key: string; page: number; value: string };
target: { key: string; page: number; value: string };
};
source: { key: string; page: number; value: string; char_positions?: CharPosition[] };
target: { key: string; page: number; value: string; char_positions?: CharPosition[] };
};
res: boolean;
compareMethod?: string;
}>>();
@@ -1102,7 +1113,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));
onReviewPointSelect(reviewPoint.id, Number(item.data.page), item.data.char_positions);
break;
}
}
@@ -1116,7 +1127,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));
onReviewPointSelect(reviewPoint.id, Number(item.data.page), item.data.char_positions);
break;
}
}
@@ -1152,11 +1163,11 @@ export function ReviewPointsList({
onClick={(e) => {
e.stopPropagation();
if (item.data.page) {
// console.log('currentitem-------', reviewPoint);
console.log('点击了长链条评查点', item.data.char_positions);
// 假设onReviewPointSelect在作用域内可用
const reviewPointId = reviewPoint.id as string;
if (reviewPointId && typeof onReviewPointSelect === 'function') {
onReviewPointSelect(reviewPointId, Number(item.data.page));
onReviewPointSelect(reviewPointId, Number(item.data.page), item.data.char_positions);
}
}
else if(reviewPoint.contentPage && reviewPoint.contentPage[item.field]){
@@ -1237,9 +1248,10 @@ export function ReviewPointsList({
onClick={(e) => {
e.stopPropagation();
if (chain[0].data.page) {
console.log('点击了短链1左', chain[0].data.char_positions)
const reviewPointId = reviewPoint.id as string;
if (reviewPointId && typeof onReviewPointSelect === 'function') {
onReviewPointSelect(reviewPointId, chain[0].data.page);
onReviewPointSelect(reviewPointId, chain[0].data.page, chain[0].data.char_positions);
}
}
else if(reviewPoint.contentPage && reviewPoint.contentPage[chain[0].field]){
@@ -1263,9 +1275,10 @@ export function ReviewPointsList({
onClick={(e) => {
e.stopPropagation();
if (chain[1].data.page) {
console.log('点击了短链2右', chain[1].data.char_positions)
const reviewPointId = reviewPoint.id as string;
if (reviewPointId && typeof onReviewPointSelect === 'function') {
onReviewPointSelect(reviewPointId, chain[1].data.page);
onReviewPointSelect(reviewPointId, chain[1].data.page, chain[1].data.char_positions);
}
}
else if(reviewPoint.contentPage && reviewPoint.contentPage[chain[1].field]){
@@ -1338,12 +1351,13 @@ export function ReviewPointsList({
*/
const renderOtherRule = (otherRule: Record<string, unknown>, reviewPoint: ReviewPoint) => {
const fieldKey = otherRule.fieldKey as string;
const fieldValue = otherRule.fieldValue as {
type: Record<string, {
const fieldValue = otherRule.fieldValue as {
type: Record<string, {
res: boolean;
page?: number | string;
value?: string;
}>;
char_positions?: CharPosition[];
}>;
};
// 获取res的综合结果
@@ -1404,7 +1418,8 @@ export function ReviewPointsList({
onClick={(e) => {
e.stopPropagation();
if (mainTypeValue.page && typeof onReviewPointSelect === 'function') {
onReviewPointSelect(reviewPoint.id, Number(mainTypeValue.page));
console.log("点击了其他评查点", mainTypeValue)
onReviewPointSelect(reviewPoint.id, Number(mainTypeValue.page), mainTypeValue.char_positions);
}else if(reviewPoint.contentPage && reviewPoint.contentPage[fieldKey]){
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[fieldKey]));
}else{
@@ -1415,7 +1430,7 @@ export function ReviewPointsList({
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
if (mainTypeValue.page && typeof onReviewPointSelect === 'function') {
onReviewPointSelect(reviewPoint.id, Number(mainTypeValue.page));
onReviewPointSelect(reviewPoint.id, Number(mainTypeValue.page), mainTypeValue.char_positions);
}else{
toastService.error(`没有找到${fieldKey}对应的索引内容`);
}
@@ -1478,12 +1493,13 @@ export function ReviewPointsList({
const renderModelRule = (aiRule: Record<string, unknown>, reviewPoint: ReviewPoint) => {
// 从aiRule中提取配置信息
const config = aiRule.config as {
model?: string;
fields?: Record<string, {
const config = aiRule.config as {
model?: string;
fields?: Record<string, {
page: number | string;
value: string;
}>;
char_positions?: CharPosition[];
}>;
message?: string;
res?: boolean;
} | undefined;
@@ -1525,7 +1541,8 @@ export function ReviewPointsList({
onClick={(e) => {
e.stopPropagation();
if (value.page && typeof onReviewPointSelect === 'function') {
onReviewPointSelect(reviewPoint.id, Number(value.page));
console.log("点击了大模型的评查点", value.char_positions)
onReviewPointSelect(reviewPoint.id, Number(value.page), value.char_positions);
}else if(reviewPoint.contentPage && reviewPoint.contentPage[key]){
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[key]));
}else{
@@ -1537,7 +1554,7 @@ export function ReviewPointsList({
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
if (value.page && typeof onReviewPointSelect === 'function') {
onReviewPointSelect(reviewPoint.id, Number(value.page));
onReviewPointSelect(reviewPoint.id, Number(value.page), value.char_positions);
}else if(reviewPoint.contentPage && reviewPoint.contentPage[key]){
onReviewPointSelect(reviewPoint.id, Number(reviewPoint.contentPage[key]));
}else{
@@ -1652,6 +1669,7 @@ export function ReviewPointsList({
interface RuleFieldValue {
page?: number | string;
value?: string;
char_positions?: CharPosition[];
type: Record<string, boolean>;
}
@@ -1670,7 +1688,7 @@ export function ReviewPointsList({
// 使用类型断言获取config对象的具体结构
const config = rule.config as {
res: boolean;
fields: Record<string, { page: number; value: string }>;
fields: Record<string, { page: number; value: string; char_positions?: CharPosition[] }>;
logic?: string;
};
@@ -1717,7 +1735,7 @@ export function ReviewPointsList({
// 使用类型断言获取config对象的具体结构
const config = rule.config as {
res: boolean;
field: Record<string, { page: string | number; value: string }>;
field: Record<string, { page: string | number; value: string; char_positions?: CharPosition[] }>;
formatType?: string;
parameters?: string;
};
@@ -1751,7 +1769,7 @@ export function ReviewPointsList({
logic: string;
res: boolean;
conditions: Array<{
field: Record<string, { page: number | string; value: string }>;
field: Record<string, { page: number | string; value: string; char_positions?: CharPosition[] }>;
value: string;
operator: string;
res: boolean;
@@ -1786,7 +1804,7 @@ export function ReviewPointsList({
// 使用类型断言获取config对象的具体结构
const config = rule.config as {
res: boolean;
field: Record<string, { page: number | string; value: string }>;
field: Record<string, { page: number | string; value: string; char_positions?: CharPosition[] }>;
pattern?: string;
matchType?: string;
selectedFields?: string[];
@@ -1821,10 +1839,11 @@ export function ReviewPointsList({
res: boolean;
page?: number | string;
value?: string;
char_positions?: CharPosition[];
}>;
};
}> = [];
// 使用对象存储相同fieldKey的项,便于快速查找和合并
const fieldKeyMap: Record<string, {
fieldKey: string;
@@ -1833,6 +1852,7 @@ export function ReviewPointsList({
res: boolean;
page?: number | string;
value?: string;
char_positions?: CharPosition[];
}>;
};
}> = {};
@@ -1843,11 +1863,12 @@ export function ReviewPointsList({
const fieldValue = item.fieldValue;
const typeKey = Object.keys(fieldValue.type)[0]; // 获取类型名称(exists/logic/regex/format
const typeValue = fieldValue.type[typeKey]; // 获取类型值(true/false
// 提取页码和值
// 提取页码、值和字符位置
const page = fieldValue.page;
const value = fieldValue.value;
const char_positions = fieldValue.char_positions;
// 如果是第一次遇到这个fieldKey,创建新条目
if (!fieldKeyMap[fieldKey]) {
// 创建新的结构
@@ -1858,12 +1879,13 @@ export function ReviewPointsList({
}
};
}
// 将类型信息添加到type对象中,允许一个字段有多种规则类型的结果
fieldKeyMap[fieldKey].fieldValue.type[typeKey] = {
res: typeValue,
page,
value
value,
char_positions
};
});
@@ -2270,7 +2292,7 @@ export function ReviewPointsList({
tabIndex={0}
style={{ userSelect: 'text' }}
onClick={() => {
// console.log('reviewPoint', reviewPoint);
console.log('reviewPoint', reviewPoint);
handleReviewPointClick(reviewPoint.id);
}}
onKeyDown={(e) => {