Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
R
risk-monitor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
1
合并请求
1
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蔡建
risk-monitor
Commits
79410949
提交
79410949
authored
4月 09, 2026
作者:
张伊明
浏览文件
操作
浏览文件
下载
差异文件
合并分支 'zym-dev' 到 'pre'
Zym dev 查看合并请求
!326
上级
1e3e0df3
769dfe68
流水线
#393
已通过 于阶段
in 3 分 47 秒
变更
7
流水线
1
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
129 行增加
和
35 行删除
+129
-35
billHome.js
src/api/bill/billHome.js
+1
-1
IntelligentEntityText.vue
src/components/base/texts/IntelligentEntityText.vue
+58
-10
ResourceLibrarySection.vue
src/views/bill/billHome/ResourceLibrarySection.vue
+1
-3
index.vue
src/views/bill/billHome/index.vue
+37
-20
index.vue
src/views/bill/deepDig/processAnalysis/index.vue
+7
-0
index.vue
src/views/bill/template/index.vue
+25
-1
出口管制接口-4.md
出口管制接口-4.md
+0
-0
没有找到文件。
src/api/bill/billHome.js
浏览文件 @
79410949
...
...
@@ -16,7 +16,7 @@ export function getBillIndustry(params) {
return
request
({
method
:
'GET'
,
url
:
`/api/BillOverview/billIndustry/
${
params
.
year
}
`
,
params
:
{
sta
tus
:
params
.
status
}
params
:
{
sta
geName
:
params
.
stageName
}
})
}
...
...
src/components/base/texts/IntelligentEntityText.vue
浏览文件 @
79410949
<
template
>
<p
class=
"p-regular-rereg"
>
<span
class=
"text-regular"
v-for=
"(segment, index) in processedText"
:key=
"index"
>
<span
v-if=
"segment.isEntity"
@
click=
"$emit('onEntityClick', segment.entity)"
class=
"entity-link"
>
<span
v-if=
"segment.isEntity"
@
click=
"$emit('onEntityClick', segment.entity)"
:class=
"['entity-link',
{ 'keyword-highlight': segment.isKeywordHit }]"
>
{{
segment
.
entity
?.
text_span
}}
<img
:src=
"SearchIcon"
:width=
"10"
:height=
"10"
alt=
"search"
/>
</span>
<span
v-else
>
{{
segment
.
text
}}
<span
:class=
"
{ 'keyword-highlight': segment.isKeywordHit }">
{{
segment
.
text
}}
</span>
</span>
</span>
</p>
...
...
@@ -20,6 +24,7 @@ export interface ProcessedTextSegment {
text
:
string
;
isEntity
:
boolean
;
entity
?:
TextEntity
;
isKeywordHit
?:
boolean
;
}
const
props
=
defineProps
({
text
:
{
...
...
@@ -29,15 +34,42 @@ const props = defineProps({
entities
:
{
type
:
Array
<
TextEntity
>
,
default
:
()
=>
[]
},
highlight
:
{
type
:
String
,
default
:
""
}
});
const
emit
=
defineEmits
([
"onEntityClick"
]);
// 处理后的文本段
const
processedText
=
ref
<
ProcessedTextSegment
[]
>
([]);
const
normalizeKeyword
=
(
value
:
unknown
)
=>
String
(
value
??
""
).
trim
();
const
getKeywordMatches
=
(
text
:
string
,
keyword
:
string
)
=>
{
if
(
!
keyword
)
return
[{
text
,
isKeywordHit
:
false
}];
const
lowerText
=
text
.
toLowerCase
();
const
lowerKeyword
=
keyword
.
toLowerCase
();
if
(
!
lowerKeyword
)
return
[{
text
,
isKeywordHit
:
false
}];
const
parts
:
Array
<
{
text
:
string
;
isKeywordHit
:
boolean
}
>
=
[];
let
start
=
0
;
while
(
start
<
text
.
length
)
{
const
index
=
lowerText
.
indexOf
(
lowerKeyword
,
start
);
if
(
index
===
-
1
)
{
parts
.
push
({
text
:
text
.
slice
(
start
),
isKeywordHit
:
false
});
break
;
}
if
(
index
>
start
)
{
parts
.
push
({
text
:
text
.
slice
(
start
,
index
),
isKeywordHit
:
false
});
}
parts
.
push
({
text
:
text
.
slice
(
index
,
index
+
keyword
.
length
),
isKeywordHit
:
true
});
start
=
index
+
keyword
.
length
;
}
return
parts
.
filter
(
part
=>
part
.
text
);
};
// 处理文本,识别并替换实体
const
processText
=
()
=>
{
console
.
log
(
"props.entities.length"
,
props
.
entities
.
length
);
if
(
!
props
.
text
||
!
props
.
entities
)
{
// console.log('props.text', props.entities.length)
processedText
.
value
=
[{
text
:
""
,
isEntity
:
false
}];
...
...
@@ -46,6 +78,7 @@ const processText = () => {
const
result
=
[];
let
currentPosition
=
0
;
const
keyword
=
normalizeKeyword
(
props
.
highlight
);
// 按实体文本长度排序,优先匹配长文本
const
sortedEntities
=
[...
props
.
entities
].
sort
((
a
,
b
)
=>
b
.
text_span
.
length
-
a
.
text_span
.
length
);
...
...
@@ -61,7 +94,8 @@ const processText = () => {
// 如果当前位置是实体,添加到结果
result
.
push
({
isEntity
:
true
,
entity
:
{
...
entity
}
entity
:
{
...
entity
},
isKeywordHit
:
keyword
?
entityText
.
toLowerCase
().
includes
(
keyword
.
toLowerCase
())
:
false
});
currentPosition
=
endPosition
;
matched
=
true
;
...
...
@@ -82,18 +116,26 @@ const processText = () => {
if
(
nextEntityStart
>
currentPosition
)
{
const
plainText
=
props
.
text
.
substring
(
currentPosition
,
nextEntityStart
);
result
.
push
({
text
:
plainText
,
isEntity
:
false
const
parts
=
getKeywordMatches
(
plainText
,
keyword
);
parts
.
forEach
(
part
=>
{
result
.
push
({
text
:
part
.
text
,
isEntity
:
false
,
isKeywordHit
:
part
.
isKeywordHit
});
});
currentPosition
=
nextEntityStart
;
}
else
{
// 没有更多实体,添加剩余文本
const
remainingText
=
props
.
text
.
substring
(
currentPosition
);
if
(
remainingText
)
{
result
.
push
({
text
:
remainingText
,
isEntity
:
false
const
parts
=
getKeywordMatches
(
remainingText
,
keyword
);
parts
.
forEach
(
part
=>
{
result
.
push
({
text
:
part
.
text
,
isEntity
:
false
,
isKeywordHit
:
part
.
isKeywordHit
});
});
}
currentPosition
=
props
.
text
.
length
;
...
...
@@ -106,6 +148,7 @@ const processText = () => {
// 监听文本和实体变化
watch
(()
=>
props
.
text
,
processText
);
watch
(()
=>
props
.
entities
,
processText
,
{
deep
:
true
});
watch
(()
=>
props
.
highlight
,
processText
);
// 初始化处理
onMounted
(
processText
);
...
...
@@ -113,6 +156,11 @@ onMounted(processText);
<
style
lang=
"scss"
scoped
>
@use
"@/styles/common.scss"
;
.keyword-highlight
{
background
:
rgba
(
255
,
199
,
0
,
0
.35
);
border-radius
:
2px
;
}
.entity-link
{
color
:
var
(
--
color-primary-100
);
&
:hover
{
...
...
src/views/bill/billHome/ResourceLibrarySection.vue
浏览文件 @
79410949
...
...
@@ -93,7 +93,7 @@
<div
class=
"item"
>
<div
class=
"item-left"
>
法案进展:
</div>
<div
class=
"item-right2"
>
<div
class=
"tag"
v-for=
"(val, idx) in
getReversedProgress(item.progress)
"
:key=
"`$
{item.billId}-${val}-${idx}`" :style="{ zIndex: item.progress.length - idx }">
{{
val
}}
</div>
<div
class=
"tag"
v-for=
"(val, idx) in
item.progress
"
:key=
"`$
{item.billId}-${val}-${idx}`" :style="{ zIndex: item.progress.length - idx }">
{{
val
}}
</div>
</div>
</div>
</div>
...
...
@@ -458,8 +458,6 @@ const handleClickAvatar = async member => {
}
catch
(
error
)
{
}
}
;
const
getReversedProgress
=
progress
=>
(
Array
.
isArray
(
progress
)
?
[...
progress
].
reverse
()
:
[]);
const
handleClickCommitteeBill
=
bill
=>
{
if
(
!
bill
?.
billId
)
return
;
props
.
onClickToDetail
({
...
...
src/views/bill/billHome/index.vue
浏览文件 @
79410949
...
...
@@ -373,7 +373,8 @@ const committeeTimeRange = ref("近一月");
const
committeeTimeOptions
=
[
{
label
:
"近一周"
,
value
:
"近一周"
},
{
label
:
"近一月"
,
value
:
"近一月"
},
{
label
:
"近一年"
,
value
:
"近一年"
}
{
label
:
"近一年"
,
value
:
"近一年"
},
{
label
:
"全部时间"
,
value
:
"全部时间"
}
];
const
committeeCardList
=
ref
([]);
...
...
@@ -1029,14 +1030,15 @@ const handleBox6 = async () => {
// 涉华领域分布
const
box9ChartData
=
ref
([]);
const
box9selectetedTime
=
ref
(
"2025"
);
// 立法状态下拉:提出法案、众议院通过、参议院通过、解决分歧、完成立法
// v-model 存储的是接口需要的 status 值
const
box9LegislativeStatus
=
ref
(
"提案"
);
// 立法状态下拉:提出法案、众议院通过、参议院通过、解决分歧、
呈交总统、
完成立法
// v-model 存储的是接口需要的 status 值
(直接作为接口参数)
const
box9LegislativeStatus
=
ref
(
"提
出法
案"
);
const
box9LegislativeStatusList
=
ref
([
{
label
:
"提出法案"
,
value
:
"提案"
},
{
label
:
"提出法案"
,
value
:
"提
出法
案"
},
{
label
:
"众议院通过"
,
value
:
"众议院通过"
},
{
label
:
"参议院通过"
,
value
:
"参议院通过"
},
{
label
:
"解决分歧"
,
value
:
"分歧已解决"
},
{
label
:
"解决分歧"
,
value
:
"解决分歧"
},
{
label
:
"呈交总统"
,
value
:
"呈交总统"
},
{
label
:
"完成立法"
,
value
:
"完成立法"
}
]);
const
box9YearList
=
ref
([
...
...
@@ -1063,18 +1065,39 @@ const box9YearList = ref([
]);
const
box9HasData
=
ref
(
true
);
let
box9ChartInstance
=
null
;
const
BOX9_MAX_DOMAIN_COUNT
=
7
;
const
BOX9_OTHER_DOMAIN_NAME
=
"其他"
;
const
formatBox9DomainData
=
(
list
=
[])
=>
{
if
(
!
Array
.
isArray
(
list
)
||
list
.
length
<=
BOX9_MAX_DOMAIN_COUNT
)
{
return
list
;
}
const
topDomainList
=
list
.
slice
(
0
,
BOX9_MAX_DOMAIN_COUNT
);
const
otherDomainCount
=
list
.
slice
(
BOX9_MAX_DOMAIN_COUNT
).
reduce
((
sum
,
item
)
=>
{
return
sum
+
Number
(
item
?.
countBill
||
0
);
},
0
);
if
(
!
otherDomainCount
)
{
return
topDomainList
;
}
return
[
...
topDomainList
,
{
industryName
:
BOX9_OTHER_DOMAIN_NAME
,
countBill
:
otherDomainCount
}
];
};
const
getBox9Data
=
async
()
=>
{
chartLoading
.
value
=
{
...
chartLoading
.
value
,
box6
:
true
};
const
params
=
{
year
:
box9selectetedTime
.
value
,
sta
tus
:
box9LegislativeStatus
.
value
sta
geName
:
box9LegislativeStatus
.
value
};
try
{
const
res
=
await
getBillIndustry
(
params
);
console
.
log
(
"box9-涉华法案领域分布"
,
res
.
data
);
if
(
res
.
code
===
200
&&
res
.
data
&&
res
.
data
.
length
>
0
)
{
box9HasData
.
value
=
true
;
box9ChartData
.
value
=
res
.
data
;
box9ChartData
.
value
=
formatBox9DomainData
(
res
.
data
)
;
}
else
{
box9HasData
.
value
=
false
;
box9ChartData
.
value
=
[];
...
...
@@ -1104,16 +1127,9 @@ const handleBox9Data = async () => {
const
selectedIndex
=
box9LegislativeStatusList
.
value
.
findIndex
(
item
=>
item
.
value
===
box9LegislativeStatus
.
value
);
const
arr
=
[
{
label
:
"提出法案"
,
value
:
"提案"
},
{
label
:
"众议院通过"
,
value
:
"众议院通过"
},
{
label
:
"参议院通过"
,
value
:
"参议院通过"
},
{
label
:
"解决分歧"
,
value
:
"分歧已解决"
},
{
label
:
"完成立法"
,
value
:
"完成立法"
}
]
const
status
=
arr
.
filter
(
item
=>
{
return
item
.
value
===
box9LegislativeStatus
.
value
})[
0
].
label
// 当前选中的立法状态中文名(直接等于接口传参值)
const
statusItem
=
box9LegislativeStatusList
.
value
[
selectedIndex
];
const
status
=
statusItem
?
statusItem
.
label
:
""
;
const
selectParam
=
{
moduleType
:
'国会法案'
,
key
:
2
,
...
...
@@ -1272,13 +1288,14 @@ const getBox8ChartOption = stageList => {
const
handleBox8Data
=
async
()
=>
{
chartLoading
.
value
=
{
...
chartLoading
.
value
,
box8
:
true
};
// 进展分布显示顺序:提出法案(对应进度“提案”)、众议院通过、参议院通过、
分歧已解决(解决分歧)
、完成立法
const
stageOrder
=
[
"提案"
,
"众议院通过"
,
"参议院通过"
,
"分歧已解决"
,
"完成立法"
];
// 进展分布显示顺序:提出法案(对应进度“提案”)、众议院通过、参议院通过、
解决分歧(对应进度“分歧已解决”)、呈交总统
、完成立法
const
stageOrder
=
[
"提案"
,
"众议院通过"
,
"参议院通过"
,
"分歧已解决"
,
"
呈交总统"
,
"
完成立法"
];
const
stageNameMap
=
{
提案
:
"提出法案"
,
众议院通过
:
"众议院通过"
,
参议院通过
:
"参议院通过"
,
分歧已解决
:
"解决分歧"
,
呈交总统
:
"呈交总统"
,
完成立法
:
"完成立法"
};
...
...
src/views/bill/deepDig/processAnalysis/index.vue
浏览文件 @
79410949
...
...
@@ -1169,6 +1169,10 @@ onMounted(async () => {
<
style
lang
=
"scss"
scoped
>
.
wrap
{
display
:
flex
;
flex
-
direction
:
row
;
flex
-
wrap
:
nowrap
;
direction
:
ltr
;
justify
-
content
:
flex
-
start
;
margin
-
bottom
:
30
px
;
...
...
@@ -1254,6 +1258,8 @@ onMounted(async () => {
.
left
{
margin
-
top
:
16
px
;
width
:
792
px
;
flex
:
0
0
792
px
;
.
box1
{
width
:
792
px
;
...
...
@@ -1651,6 +1657,7 @@ onMounted(async () => {
margin
-
left
:
16
px
;
margin
-
top
:
16
px
;
width
:
792
px
;
flex
:
0
0
792
px
;
height
:
847
px
;
.
box3
{
...
...
src/views/bill/template/index.vue
浏览文件 @
79410949
...
...
@@ -131,6 +131,7 @@
<IntelligentEntityText
:text=
"term?.fynr || ''"
:entities=
"termsHighlight ? getTermEntities(term, 'cn') : []"
:highlight=
"searchKeyword"
@
on-entity-click=
"e => gotoSearchResults(e.text_span, '')"
/>
</div>
...
...
@@ -141,6 +142,7 @@
<IntelligentEntityText
:text=
"term?.ywnr || ''"
:entities=
"termsHighlight ? getTermEntities(term, 'en') : []"
:highlight=
"searchKeyword"
@
on-entity-click=
"e => gotoSearchResults(e.text_span, '')"
/>
</div>
...
...
@@ -343,6 +345,27 @@ const chart1ColorList = ref([...MUTICHARTCOLORS]);
const
chart2ColorList
=
ref
([...
MUTICHARTCOLORS
]);
const
chart2Data
=
ref
([]);
const
DOMAIN_MAX_DISPLAY_COUNT
=
7
;
const
DOMAIN_OTHER_NAME
=
"其他"
;
const
formatDomainChartData
=
(
list
=
[])
=>
{
if
(
!
Array
.
isArray
(
list
)
||
list
.
length
<=
DOMAIN_MAX_DISPLAY_COUNT
)
{
return
list
;
}
const
topDomainList
=
list
.
slice
(
0
,
DOMAIN_MAX_DISPLAY_COUNT
);
const
otherCount
=
list
.
slice
(
DOMAIN_MAX_DISPLAY_COUNT
).
reduce
((
sum
,
item
)
=>
{
return
sum
+
Number
(
item
?.
value
||
0
);
}
,
0
);
if
(
!
otherCount
)
{
return
topDomainList
;
}
return
[
...
topDomainList
,
{
name
:
DOMAIN_OTHER_NAME
,
value
:
otherCount
}
];
}
;
const
aiPaneVisible
=
ref
({
domain
:
false
,
...
...
@@ -737,12 +760,13 @@ const handleGetBillHyly = async () => {
.
map
(
name
=>
{
return
{
label
:
name
,
value
:
name
}
;
}
);
c
hart2Data
.
value
=
res
.
data
.
map
(
item
=>
{
c
onst
domainChartData
=
res
.
data
.
map
(
item
=>
{
return
{
name
:
item
.
hylymc
,
value
:
item
.
countTk
}
;
}
);
chart2Data
.
value
=
formatDomainChartData
(
domainChartData
);
aiPaneFetched
.
value
=
{
...
aiPaneFetched
.
value
,
domain
:
false
}
;
let
chart2
=
getPieChart
(
chart2Data
.
value
,
chart2ColorList
.
value
);
...
...
出口管制接口-4.md
浏览文件 @
79410949
差异被折叠。
点击展开。
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论