Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
R
risk-monitor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蔡建
risk-monitor
Commits
59089e47
提交
59089e47
authored
4月 22, 2026
作者:
朱政
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
feat:智库原文搜索高亮开发
上级
945bd0af
流水线
#593
已失败 于阶段
in 52 秒
变更
1
流水线
1
显示空白字符变更
内嵌
并排
正在显示
1 个修改的文件
包含
52 行增加
和
20 行删除
+52
-20
pdf.vue
src/views/thinkTank/reportOriginal/pdf.vue
+52
-20
没有找到文件。
src/views/thinkTank/reportOriginal/pdf.vue
浏览文件 @
59089e47
...
@@ -326,34 +326,39 @@ export default {
...
@@ -326,34 +326,39 @@ export default {
}
}
}
}
if
(
matchList
.
value
.
length
>
0
)
jumpTo
(
0
);
if
(
matchList
.
value
.
length
>
0
)
{
// 先把所有命中都标黄,再把“当前命中”改成蓝底
renderAllHighlights
();
jumpTo
(
0
);
}
};
};
// 跳转到第 N 个匹配项
const
setActiveHighlight
=
(
idx
)
=>
{
const
jumpTo
=
(
idx
)
=>
{
const
all
=
document
.
querySelectorAll
(
'.highlight-rect[data-match-idx]'
);
if
(
idx
<
0
||
idx
>=
matchList
.
value
.
length
)
return
;
all
.
forEach
((
el
)
=>
{
matchIdx
.
value
=
idx
;
const
isActive
=
Number
(
el
.
getAttribute
(
'data-match-idx'
))
===
Number
(
idx
);
const
m
=
matchList
.
value
[
idx
];
if
(
isActive
)
{
if
(
m
?.
fallback
)
{
el
.
classList
.
add
(
'highlight-rect--active'
);
// 兜底命中:只定位页码,不做高亮
}
else
{
goToPage
(
m
.
pageNum
);
el
.
classList
.
remove
(
'highlight-rect--active'
);
return
;
}
}
const
firstSeg
=
m
?.
segments
?.[
0
];
});
const
el
=
firstSeg
?.
el
;
};
if
(
!
el
)
return
;
const
renderAllHighlights
=
()
=>
{
clearHighlights
();
clearHighlights
();
const
list
=
Array
.
isArray
(
matchList
.
value
)
?
matchList
.
value
:
[];
list
.
forEach
((
m
,
idx
)
=>
{
if
(
!
m
||
m
.
fallback
)
return
;
const
layer
=
overlayMap
[
m
.
pageNum
];
const
layer
=
overlayMap
[
m
.
pageNum
];
if
(
!
layer
)
return
;
if
(
!
layer
)
return
;
const
pageWrap
=
layer
.
closest
(
'.page-wrap'
);
const
pageWrap
=
layer
.
closest
(
'.page-wrap'
);
const
container
=
(
pageWrap
||
layer
);
// 用 Range 精确计算“子串”在页面上的矩形位置,再画黄色块(支持跨 span)
const
containerRect
=
container
.
getBoundingClientRect
();
const
containerRect
=
(
pageWrap
||
layer
).
getBoundingClientRect
();
const
segs
=
Array
.
isArray
(
m
?.
segments
)
?
m
.
segments
:
[];
const
segs
=
Array
.
isArray
(
m
?.
segments
)
?
m
.
segments
:
[];
for
(
const
seg
of
segs
)
{
for
(
const
seg
of
segs
)
{
const
segEl
=
seg
?.
el
;
const
segEl
=
seg
?.
el
;
if
(
!
segEl
)
continue
;
if
(
!
segEl
)
continue
;
const
textNode
=
segEl
.
firstChild
;
const
textNode
=
segEl
.
firstChild
;
if
(
!
textNode
||
textNode
.
nodeType
!==
Node
.
TEXT_NODE
)
continue
;
if
(
!
textNode
||
textNode
.
nodeType
!==
Node
.
TEXT_NODE
)
continue
;
try
{
try
{
...
@@ -365,25 +370,26 @@ export default {
...
@@ -365,25 +370,26 @@ export default {
rectList
.
forEach
(
r
=>
{
rectList
.
forEach
(
r
=>
{
const
mark
=
document
.
createElement
(
'div'
);
const
mark
=
document
.
createElement
(
'div'
);
mark
.
className
=
'highlight-rect'
;
mark
.
className
=
'highlight-rect'
;
mark
.
setAttribute
(
'data-match-idx'
,
String
(
idx
));
mark
.
style
.
zIndex
=
'5'
;
mark
.
style
.
zIndex
=
'5'
;
mark
.
style
.
left
=
(
r
.
left
-
containerRect
.
left
)
+
'px'
;
mark
.
style
.
left
=
(
r
.
left
-
containerRect
.
left
)
+
'px'
;
mark
.
style
.
top
=
(
r
.
top
-
containerRect
.
top
)
+
'px'
;
mark
.
style
.
top
=
(
r
.
top
-
containerRect
.
top
)
+
'px'
;
mark
.
style
.
width
=
r
.
width
+
'px'
;
mark
.
style
.
width
=
r
.
width
+
'px'
;
mark
.
style
.
height
=
r
.
height
+
'px'
;
mark
.
style
.
height
=
r
.
height
+
'px'
;
(
pageWrap
||
layer
)
.
appendChild
(
mark
);
container
.
appendChild
(
mark
);
});
});
}
else
{
}
else
{
// Range 兜底为空时:用 span 自身的矩形画块(精度低,但尽量可见)
const
r
=
segEl
.
getBoundingClientRect
();
const
r
=
segEl
.
getBoundingClientRect
();
if
(
r
.
width
>
0
&&
r
.
height
>
0
)
{
if
(
r
.
width
>
0
&&
r
.
height
>
0
)
{
const
mark
=
document
.
createElement
(
'div'
);
const
mark
=
document
.
createElement
(
'div'
);
mark
.
className
=
'highlight-rect'
;
mark
.
className
=
'highlight-rect'
;
mark
.
setAttribute
(
'data-match-idx'
,
String
(
idx
));
mark
.
style
.
zIndex
=
'5'
;
mark
.
style
.
zIndex
=
'5'
;
mark
.
style
.
left
=
(
r
.
left
-
containerRect
.
left
)
+
'px'
;
mark
.
style
.
left
=
(
r
.
left
-
containerRect
.
left
)
+
'px'
;
mark
.
style
.
top
=
(
r
.
top
-
containerRect
.
top
)
+
'px'
;
mark
.
style
.
top
=
(
r
.
top
-
containerRect
.
top
)
+
'px'
;
mark
.
style
.
width
=
r
.
width
+
'px'
;
mark
.
style
.
width
=
r
.
width
+
'px'
;
mark
.
style
.
height
=
r
.
height
+
'px'
;
mark
.
style
.
height
=
r
.
height
+
'px'
;
(
pageWrap
||
layer
)
.
appendChild
(
mark
);
container
.
appendChild
(
mark
);
}
}
}
}
range
.
detach
?.();
range
.
detach
?.();
...
@@ -391,6 +397,24 @@ export default {
...
@@ -391,6 +397,24 @@ export default {
// ignore
// ignore
}
}
}
}
});
setActiveHighlight
(
matchIdx
.
value
);
};
// 跳转到第 N 个匹配项
const
jumpTo
=
(
idx
)
=>
{
if
(
idx
<
0
||
idx
>=
matchList
.
value
.
length
)
return
;
matchIdx
.
value
=
idx
;
const
m
=
matchList
.
value
[
idx
];
if
(
m
?.
fallback
)
{
// 兜底命中:只定位页码,不做高亮
goToPage
(
m
.
pageNum
);
return
;
}
const
firstSeg
=
m
?.
segments
?.[
0
];
const
el
=
firstSeg
?.
el
;
if
(
!
el
)
return
;
setActiveHighlight
(
idx
);
// 优先只滚动右侧 report-box,避免触发整页滚动导致 header 遮挡
// 优先只滚动右侧 report-box,避免触发整页滚动导致 header 遮挡
const
container
=
el
.
closest
(
'.report-box'
);
const
container
=
el
.
closest
(
'.report-box'
);
...
@@ -510,6 +534,10 @@ canvas {
...
@@ -510,6 +534,10 @@ canvas {
z-index
:
5
;
z-index
:
5
;
}
}
.textLayer
:deep
(
.highlight-rect--active
)
{
background
:
rgb
(
184
,
222
,
254
);
}
.page-wrap
:deep
(
.highlight-rect
)
{
.page-wrap
:deep
(
.highlight-rect
)
{
position
:
absolute
;
position
:
absolute
;
background
:
#ff0
;
background
:
#ff0
;
...
@@ -519,6 +547,10 @@ canvas {
...
@@ -519,6 +547,10 @@ canvas {
z-index
:
3
;
z-index
:
3
;
}
}
.page-wrap
:deep
(
.highlight-rect--active
)
{
background
:
rgb
(
184
,
222
,
254
);
}
.loading
{
.loading
{
position
:
absolute
;
position
:
absolute
;
top
:
50%
;
top
:
50%
;
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论