Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
R
risk-monitor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蔡建
risk-monitor
Commits
ab4c3907
提交
ab4c3907
authored
3月 27, 2026
作者:
coderBryanFu
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'pre' of
http://8.140.26.4:10003/caijian/risk-monitor
into fk-dev
上级
4cd32036
1b498149
流水线
#127
已失败 于阶段
in 27 秒
变更
14
流水线
1
显示空白字符变更
内嵌
并排
正在显示
14 个修改的文件
包含
213 行增加
和
199 行删除
+213
-199
billHome.js
src/api/bill/billHome.js
+46
-66
FilterSection.vue
...l/influence/ProgressForecast/components/FilterSection.vue
+8
-10
PredictionPhaseCard.vue
...uence/ProgressForecast/components/PredictionPhaseCard.vue
+32
-14
Step2FilterBills.vue
...nfluence/ProgressForecast/components/Step2FilterBills.vue
+4
-3
index.vue
src/views/bill/influence/ProgressForecast/index.vue
+7
-5
index.vue
src/views/thinkTank/MultiThinkTankViewAnalysis/index.vue
+10
-9
index.vue
src/views/thinkTank/ReportDetail/policyTracking/index.vue
+22
-6
index.vue
src/views/thinkTank/ReportDetail/reportAnalysis/index.vue
+44
-44
index.vue
src/views/thinkTank/ThinkTankDetail/PolicyTracking/index.vue
+4
-4
index.vue
src/views/thinkTank/ThinkTankDetail/thinkInfo/index.vue
+6
-25
ThinkTankPolicyAdviceOverview.vue
...ws/thinkTank/components/ThinkTankPolicyAdviceOverview.vue
+12
-1
index.vue
src/views/thinkTank/index.vue
+1
-1
index.vue
src/views/thinkTank/reportOriginal/index.vue
+15
-9
pdf.vue
src/views/thinkTank/reportOriginal/pdf.vue
+2
-2
没有找到文件。
src/api/bill/billHome.js
浏览文件 @
ab4c3907
...
@@ -335,99 +335,79 @@ export function getProgressPrediction(billId) {
...
@@ -335,99 +335,79 @@ export function getProgressPrediction(billId) {
* @returns {Promise<Object>} 相似法案列表
* @returns {Promise<Object>} 相似法案列表
*/
*/
export
function
getSimiBills
(
params
=
{})
{
export
function
getSimiBills
(
params
=
{})
{
// domains 如果是数组则用逗号拼接
const
domains
=
Array
.
isArray
(
params
.
domains
)
?
params
.
domains
.
join
(
','
)
:
params
.
domains
return
request
(
'/api/BillProgressPrediction/simiBills'
,
{
return
request
(
'/api/BillProgressPrediction/simiBills'
,
{
method
:
'GET'
,
method
:
'GET'
,
params
:
{
params
:
{
billIds
:
params
.
billIds
,
billIds
:
params
.
billIds
,
domains
:
params
.
domains
,
domains
:
domains
,
patternType
:
params
.
patternType
,
patternType
:
params
.
patternType
,
proposalType
:
params
.
proposalType
,
proposalType
:
params
.
proposalType
...
params
}
}
})
})
}
}
/**
* 格式化日期 YYYY-MM-DD -> YYYY年M月D日
* @param {string} dateStr - 日期字符串
* @returns {string} 格式化后的日期
*/
function
formatDate
(
dateStr
)
{
if
(
!
dateStr
)
return
''
const
match
=
dateStr
.
match
(
/
(\d{4})
-
(\d{2})
-
(\d{2})
/
)
if
(
match
)
{
return
`
${
match
[
1
]}
年
${
parseInt
(
match
[
2
])}
月
${
parseInt
(
match
[
3
])}
日`
}
return
dateStr
}
/**
/**
* 转换相似法案 API 返回的数据为组件所需格式
* 转换相似法案 API 返回的数据为组件所需格式
* @param {Object} apiData - API 返回的原始数据
* @param {Object} apiData - API 返回的原始数据
* @returns {Object} 转换后的统计数据和法案列表
* @returns {Object} 转换后的统计数据和法案列表
*/
*/
export
function
transformSimiBillsData
(
apiData
)
{
export
function
transformSimiBillsData
(
apiData
)
{
if
(
!
apiData
||
!
apiData
.
data
||
!
Array
.
isArray
(
apiData
.
data
)
)
{
if
(
!
apiData
||
!
apiData
.
data
)
{
return
{
stats
:
null
,
bills
:
[]
}
return
{
stats
:
null
,
bills
:
[]
}
}
}
const
bills
=
apiData
.
data
const
data
=
apiData
.
data
const
simiBills
=
data
.
simi_bills
||
[]
// 计算统计数据
let
becameLaw
=
0
let
notPassedOrShelved
=
0
let
totalDays
=
0
let
completedBills
=
0
bills
.
forEach
(
bill
=>
{
const
actions
=
bill
.
bill_actions
||
[]
const
hasBecameLaw
=
actions
.
some
(
a
=>
a
.
action_type
===
'BecameLaw'
||
a
.
action_type
===
'President'
&&
a
.
action_desc
?.
includes
(
'签署'
)
)
if
(
hasBecameLaw
)
{
becameLaw
++
// 计算耗时
if
(
actions
.
length
>=
2
)
{
const
firstDate
=
new
Date
(
actions
[
0
].
action_date
)
const
lastDate
=
new
Date
(
actions
[
actions
.
length
-
1
].
action_date
)
const
days
=
Math
.
ceil
((
lastDate
-
firstDate
)
/
(
1000
*
60
*
60
*
24
))
if
(
days
>
0
)
{
totalDays
+=
days
completedBills
++
}
}
}
else
{
notPassedOrShelved
++
}
})
const
medianDays
=
completedBills
>
0
?
Math
.
round
(
totalDays
/
completedBills
)
:
223
const
passRate
=
bills
.
length
>
0
?
((
becameLaw
/
bills
.
length
)
*
100
).
toFixed
(
1
)
:
'0'
// 直接使用 API 返回的统计数据
const
stats
=
{
const
stats
=
{
totalBills
:
b
ills
.
length
,
totalBills
:
data
.
count
||
simiB
ills
.
length
,
becameLaw
,
becameLaw
:
data
.
become_law
||
0
,
notPassedOrShelved
,
notPassedOrShelved
:
(
data
.
count
||
simiBills
.
length
)
-
(
data
.
become_law
||
0
)
,
medianDays
,
medianDays
:
data
.
become_law_avg_days
||
0
,
passRate
passRate
:
data
.
become_law_prop
?
(
data
.
become_law_prop
*
100
).
toFixed
(
1
)
:
'0'
}
}
// 转换法案列表格式
// 转换法案列表格式
const
transformedBills
=
b
ills
.
map
(
bill
=>
({
const
transformedBills
=
simiB
ills
.
map
(
bill
=>
({
id
:
bill
.
bill_id
,
id
:
bill
.
bill_id
,
title
:
bill
.
bill_name
||
bill
.
bill_id
,
title
:
bill
.
bill_name
||
bill
.
bill_id
,
proposalDate
:
extractProposalDate
(
bill
.
poli_pattern_desc
),
proposalDate
:
bill
.
proposed_date
?
formatDate
(
bill
.
proposed_date
)
:
''
,
areas
:
bill
.
domain_name
?
(
Array
.
isArray
(
bill
.
domain_name
)
?
bill
.
domain_name
:
[
bill
.
domain_name
])
:
[],
areas
:
bill
.
bill_domain
?
(
Array
.
isArray
(
bill
.
bill_domain
)
?
bill
.
bill_domain
:
[
bill
.
bill_domain
])
:
[],
proposer
:
extractProposer
(
bill
.
bill_sponsors
),
proposer
:
bill
.
key_sponsor_name
||
extractProposer
(
bill
.
bill_sponsors
),
coProposers
:
bill
.
bill_proposal_desc
||
''
,
proposerParty
:
bill
.
key_sponsor_party
||
''
,
coProposers
:
bill
.
co_sponsor_desc
||
bill
.
bill_proposal_desc
||
''
,
proposalType
:
bill
.
bill_proposal_type
||
''
,
governmentType
:
formatGovernmentType
(
bill
.
poli_pattern_type
,
bill
.
poli_pattern_desc
),
governmentType
:
formatGovernmentType
(
bill
.
poli_pattern_type
,
bill
.
poli_pattern_desc
),
passDays
:
calculateTotalDays
(
bill
.
bill_actions
),
patternType
:
bill
.
poli_pattern_type
||
''
,
billStatus
:
bill
.
bill_status
||
''
,
passDays
:
bill
.
bill_action_days
||
calculateTotalDays
(
bill
.
bill_actions
),
yearsDifference
:
bill
.
years_difference
||
0
,
billActions
:
bill
.
bill_actions
||
[],
billSponsors
:
bill
.
bill_sponsors
||
[],
selected
:
true
// 默认全选
selected
:
true
// 默认全选
}))
}))
return
{
stats
,
bills
:
transformedBills
}
return
{
stats
,
bills
:
transformedBills
}
}
}
/**
* 从政治格局描述中提取提案时间
* @param {string} desc - 政治格局描述
* @returns {string} 提案时间
*/
function
extractProposalDate
(
desc
)
{
if
(
!
desc
)
return
''
const
match
=
desc
.
match
(
/
(\d{4})
-
(\d{2})
-
(\d{2})
/
)
if
(
match
)
{
return
`
${
match
[
1
]}
年
${
parseInt
(
match
[
2
])}
月
${
parseInt
(
match
[
3
])}
日`
}
return
''
}
/**
/**
* 从提案人列表中提取主提案人
* 从提案人列表中提取主提案人
* @param {Array} sponsors - 提案人列表
* @param {Array} sponsors - 提案人列表
...
@@ -504,9 +484,9 @@ export function transformProposalInfo(apiData) {
...
@@ -504,9 +484,9 @@ export function transformProposalInfo(apiData) {
return
{
return
{
// 提案标题
// 提案标题
title
:
data
.
bill_
title
||
'H.R.1-大而美法案'
,
title
:
data
.
bill_
name_zh
,
// 提案时间 - 从政治格局描述中提取
// 提案时间 - 从政治格局描述中提取
date
:
extractDateFromDesc
(
data
.
poli_pattern_desc
)
||
'2025年5月20日'
,
date
:
extractDateFromDesc
(
data
.
poli_pattern_desc
)
,
// 涉及领域 TAG - 使用 domain_name
// 涉及领域 TAG - 使用 domain_name
areas
:
Array
.
isArray
(
data
.
domain_name
)
?
data
.
domain_name
:
(
data
.
domain_name
?
[
data
.
domain_name
]
:
[]),
areas
:
Array
.
isArray
(
data
.
domain_name
)
?
data
.
domain_name
:
(
data
.
domain_name
?
[
data
.
domain_name
]
:
[]),
// 政策领域完整选项列表 - 使用 bill_domain(用于筛选下拉框)
// 政策领域完整选项列表 - 使用 bill_domain(用于筛选下拉框)
...
...
src/views/bill/influence/ProgressForecast/components/FilterSection.vue
浏览文件 @
ab4c3907
...
@@ -62,7 +62,6 @@
...
@@ -62,7 +62,6 @@
<div
class=
"field-content"
>
<div
class=
"field-content"
>
<el-select
<el-select
v-model=
"localValues.oppositionProposer"
v-model=
"localValues.oppositionProposer"
multiple
placeholder=
"请选择"
placeholder=
"请选择"
style=
"width: 420px"
style=
"width: 420px"
@
change=
"handleChange"
@
change=
"handleChange"
...
@@ -83,7 +82,6 @@
...
@@ -83,7 +82,6 @@
<div
class=
"field-content"
>
<div
class=
"field-content"
>
<el-select
<el-select
v-model=
"localValues.proposalTime"
v-model=
"localValues.proposalTime"
multiple
placeholder=
"请选择"
placeholder=
"请选择"
style=
"width: 420px"
style=
"width: 420px"
@
change=
"handleChange"
@
change=
"handleChange"
...
@@ -115,18 +113,18 @@ const props = defineProps<{
...
@@ -115,18 +113,18 @@ const props = defineProps<{
const
localValues
=
ref
({
const
localValues
=
ref
({
policyArea
:
[]
as
string
[],
policyArea
:
[]
as
string
[],
governmentType
:
[]
as
string
[],
governmentType
:
[]
as
string
[],
oppositionProposer
:
[]
as
string
[]
,
oppositionProposer
:
''
as
string
,
proposalTime
:
[]
as
string
[]
,
proposalTime
:
''
as
string
,
})
})
// 根据 proposalInfo 计算初始筛选值(即"设置为当前提案"的目标状态)
// 根据 proposalInfo 计算初始筛选值(即"设置为当前提案"的目标状态)
function
buildInitialValues
(
info
?:
ProposalInfo
|
null
):
Record
<
string
,
string
[]
>
{
function
buildInitialValues
(
info
?:
ProposalInfo
|
null
):
Record
<
string
,
string
[]
|
string
>
{
if
(
!
info
)
return
{
policyArea
:
[],
governmentType
:
[],
oppositionProposer
:
[],
proposalTime
:
[]
}
if
(
!
info
)
return
{
policyArea
:
[],
governmentType
:
[],
oppositionProposer
:
''
,
proposalTime
:
''
}
return
{
return
{
policyArea
:
info
.
defaultDomains
?.
length
?
[...
info
.
defaultDomains
]
:
[...(
info
.
areas
||
[])],
policyArea
:
info
.
defaultDomains
?.
length
?
[...
info
.
defaultDomains
]
:
[...(
info
.
areas
||
[])],
governmentType
:
info
.
patternType
?
[
info
.
patternType
]
:
[],
governmentType
:
info
.
patternType
?
[
info
.
patternType
]
:
[],
oppositionProposer
:
[]
,
oppositionProposer
:
''
,
proposalTime
:
[]
,
proposalTime
:
''
,
}
}
}
}
...
@@ -144,8 +142,8 @@ function reset() {
...
@@ -144,8 +142,8 @@ function reset() {
localValues
.
value
=
{
localValues
.
value
=
{
policyArea
:
[],
policyArea
:
[],
governmentType
:
[],
governmentType
:
[],
oppositionProposer
:
[]
,
oppositionProposer
:
''
,
proposalTime
:
[]
,
proposalTime
:
''
,
}
}
}
}
...
...
src/views/bill/influence/ProgressForecast/components/PredictionPhaseCard.vue
浏览文件 @
ab4c3907
...
@@ -2,8 +2,8 @@
...
@@ -2,8 +2,8 @@
<div
v-if=
"phase"
class=
"phase-card"
:class=
"borderColorClass"
>
<div
v-if=
"phase"
class=
"phase-card"
:class=
"borderColorClass"
>
<div
class=
"phase-header flex-display-start"
>
<div
class=
"phase-header flex-display-start"
>
<div>
<div>
<
h3
class=
"phase-title main-color text-title-2-bold"
>
{{
phase
.
title
}}
</h3
>
<
div
class=
"phase-title main-color text-title-2-bold"
>
{{
phase
.
title
}}
</div
>
<
p
class=
"text-tip-2 text-primary-50-clor"
>
{{
phase
.
description
}}
</p
>
<
div
class=
"text-tip-2 text-primary-50-clor"
>
{{
phase
.
description
}}
</div
>
</div>
</div>
<div
class=
"phase-status"
>
<div
class=
"phase-status"
>
<span
class=
"risk-badge"
:class=
"riskColorClass"
>
{{
riskLabel
}}
</span>
<span
class=
"risk-badge"
:class=
"riskColorClass"
>
{{
riskLabel
}}
</span>
...
@@ -18,32 +18,41 @@
...
@@ -18,32 +18,41 @@
<p
v-if=
"phase.riskLevel !== 'passed'"
class=
"text-tip-2 text-primary-50-clor"
>
{{
phase
.
estimatedDays
}}
</p>
<p
v-if=
"phase.riskLevel !== 'passed'"
class=
"text-tip-2 text-primary-50-clor"
>
{{
phase
.
estimatedDays
}}
</p>
</div>
</div>
</div>
</div>
<div
style=
"display: flex;"
>
<div
class=
"box-title-row"
><img
src=
"../assets/input.svg"
/>
<span
class=
"text-compact-bold text-primary-80-clor"
style=
"margin-left: 8px;"
>
预测模型数据输入
</span></div>
<div
class=
"box-hint flex-display-center text-tip-2 text-primary-50-clor"
style=
"margin-left: auto;"
>
<img
src=
"../assets/importent.svg"
/>
<span>
此阶段预测基于以下多维特征
</span>
</div>
</div>
<div
class=
"model-inputs-box"
>
<div
class=
"model-inputs-box"
>
<div
class=
"box-header flex-display-start"
>
<div
class=
"box-header flex-display-start"
>
<div
class=
"box-title-row flex-display-center"
>
<div
class=
"box-title-row flex-display-center"
>
<img
src=
"../assets/input.svg"
/>
<span
class=
"text-compact-bold"
>
预测模型数据输入
</span>
</div>
<div
class=
"box-hint flex-display-center text-tip-2 text-primary-50-clor"
>
<img
src=
"../assets/importent.svg"
/>
<span>
此阶段预测基于以下多维特征
</span>
</div>
</div>
</div>
</div>
<div
class=
"model-inputs"
>
<div
class=
"model-inputs"
>
<
p
<
div
v-for=
"(input, index) in phase.modelInputs"
v-for=
"(input, index) in phase.modelInputs"
:key=
"index"
:key=
"index"
class=
"text-tip-2 text-primary-65-clor"
class=
"text-tip-2 text-primary-65-clor"
>
>
{{
input
}}
{{
input
}}
</
p
>
</
div
>
</div>
</div>
</div>
</div>
<div
v-if=
"phase.predictionBasis"
class=
"facts-section"
>
<div
v-if=
"phase.predictionBasis"
class=
"facts-section"
>
<div
class=
"box-header flex-display-start"
>
<div
class=
"box-header flex-display-start"
>
<div
class=
"box-title-row flex-display-center"
>
<div
class=
"box-title-row flex-display-center"
>
<img
src=
"../assets/icon1.svg"
/>
<img
src=
"../assets/icon1.svg"
/>
<span
class=
"text-compact-bold"
>
通过性预测依据
</span>
<span
class=
"text-compact-bold
text-primary-80-clor
"
>
通过性预测依据
</span>
</div>
</div>
<div
class=
"box-hint flex-display-center text-tip-2 text-primary-50-clor"
>
<div
class=
"box-hint flex-display-center text-tip-2 text-primary-50-clor"
>
<img
src=
"../assets/importent.svg"
/>
<img
src=
"../assets/importent.svg"
/>
...
@@ -51,9 +60,11 @@
...
@@ -51,9 +60,11 @@
</div>
</div>
</div>
</div>
<div
class=
"prediction-basis-content"
>
<div
class=
"prediction-basis-content"
>
<
p
class=
"text-tip-2 text-primary-65-clor"
>
{{
phase
.
predictionBasis
}}
</p
>
<
div
class=
"text-tip-2 text-primary-65-clor"
>
{{
phase
.
predictionBasis
}}
</div
>
</div>
</div>
</div>
</div>
<!-- 底部虚线分隔 -->
<div
class=
"phase-divider"
></div>
</div>
</div>
</
template
>
</
template
>
...
@@ -144,7 +155,8 @@ const riskLabel = computed(() => {
...
@@ -144,7 +155,8 @@ const riskLabel = computed(() => {
<
style
scoped
>
<
style
scoped
>
.phase-card
{
.phase-card
{
padding-left
:
24px
;
padding-left
:
24px
;
padding-bottom
:
32px
;
/* padding-bottom: 16px; */
/* padding-top: 16px; */
}
}
.border-primary
{
.border-primary
{
...
@@ -166,7 +178,7 @@ const riskLabel = computed(() => {
...
@@ -166,7 +178,7 @@ const riskLabel = computed(() => {
.phase-header
{
.phase-header
{
justify-content
:
space-between
;
justify-content
:
space-between
;
align-items
:
flex-start
;
align-items
:
flex-start
;
margin-bottom
:
16px
;
/* margin-bottom: 16px; */
}
}
.phase-header
>
div
:first-child
{
.phase-header
>
div
:first-child
{
...
@@ -288,4 +300,10 @@ const riskLabel = computed(() => {
...
@@ -288,4 +300,10 @@ const riskLabel = computed(() => {
height
:
16px
;
height
:
16px
;
color
:
var
(
--text-primary-65-color
);
color
:
var
(
--text-primary-65-color
);
}
}
/* 底部虚线分隔 */
.phase-divider
{
margin-top
:
16px
;
border-bottom
:
1px
solid
var
(
--bg-black-10
,
#e5e5e5
);
}
</
style
>
</
style
>
src/views/bill/influence/ProgressForecast/components/Step2FilterBills.vue
浏览文件 @
ab4c3907
...
@@ -125,7 +125,7 @@ async function loadData() {
...
@@ -125,7 +125,7 @@ async function loadData() {
// 使用真实 API,传入 billIds、domains、patternType、proposalType
// 使用真实 API,传入 billIds、domains、patternType、proposalType
const
params
=
{
const
params
=
{
billIds
:
filterParams
?.
value
.
billIds
,
billIds
:
filterParams
?.
value
.
billIds
,
domains
:
JSON
.
stringify
(
filterParams
?.
value
.
domains
)
||
[],
domains
:
filterParams
?.
value
.
domains
||
[],
patternType
:
filterParams
?.
value
.
patternType
||
'统一政府'
,
patternType
:
filterParams
?.
value
.
patternType
||
'统一政府'
,
proposalType
:
filterParams
?.
value
.
proposalType
||
'两党共同提案'
proposalType
:
filterParams
?.
value
.
proposalType
||
'两党共同提案'
}
}
...
@@ -133,14 +133,15 @@ async function loadData() {
...
@@ -133,14 +133,15 @@ async function loadData() {
const
response
=
await
getSimiBills
(
params
)
const
response
=
await
getSimiBills
(
params
)
if
(
response
&&
response
.
data
)
{
if
(
response
&&
response
.
data
)
{
// 保存原始数据
// 保存原始数据
(新 API 返回结构中 simi_bills 是法案数组)
rawBillsData
.
value
=
response
.
data
rawBillsData
.
value
=
response
.
data
.
simi_bills
||
[]
const
{
stats
:
apiStats
,
bills
:
apiBills
}
=
transformSimiBillsData
(
response
)
const
{
stats
:
apiStats
,
bills
:
apiBills
}
=
transformSimiBillsData
(
response
)
stats
.
value
=
apiStats
stats
.
value
=
apiStats
bills
.
value
=
apiBills
bills
.
value
=
apiBills
}
else
{
}
else
{
stats
.
value
=
null
stats
.
value
=
null
bills
.
value
=
[]
bills
.
value
=
[]
rawBillsData
.
value
=
[]
}
}
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
error
(
'获取相似法案失败:'
,
error
)
console
.
error
(
'获取相似法案失败:'
,
error
)
...
...
src/views/bill/influence/ProgressForecast/index.vue
浏览文件 @
ab4c3907
...
@@ -90,7 +90,7 @@ onMounted(async () => {
...
@@ -90,7 +90,7 @@ onMounted(async () => {
// 获取提案信息
// 获取提案信息
const
predictionData
=
await
getProgressPrediction
(
billId
.
value
).
catch
(
err
=>
{
const
predictionData
=
await
getProgressPrediction
(
billId
.
value
).
catch
(
err
=>
{
console
.
error
(
'
[v0]
获取预测数据失败:'
,
err
)
console
.
error
(
' 获取预测数据失败:'
,
err
)
return
null
return
null
})
})
...
@@ -341,7 +341,7 @@ async function handleStep2Next(selectedBills: any[]) {
...
@@ -341,7 +341,7 @@ async function handleStep2Next(selectedBills: any[]) {
predictionResult
.
value
=
transformPredictionResult
(
response
.
data
)
predictionResult
.
value
=
transformPredictionResult
(
response
.
data
)
}
}
}
catch
(
error
)
{
}
catch
(
error
)
{
console
.
error
(
'
[v0]
获取预测分析失败:'
,
error
)
console
.
error
(
' 获取预测分析失败:'
,
error
)
}
finally
{
}
finally
{
predictionLoading
.
value
=
false
predictionLoading
.
value
=
false
}
}
...
@@ -370,9 +370,11 @@ function transformPredictionResult(data: any) {
...
@@ -370,9 +370,11 @@ function transformPredictionResult(data: any) {
const
factors
=
data
?.
factor_analysis
||
[]
const
factors
=
data
?.
factor_analysis
||
[]
// 转换阶段分析
// 转换阶段分析
const
phases
=
stages
.
map
((
stage
:
any
,
index
:
number
)
=>
({
const
chineseNum
=
[
'一'
,
'二'
,
'三'
,
'四'
,
'五'
,
'六'
,
'七'
,
'八'
,
'九'
,
'十'
]
const
phases
=
stages
.
map
((
stage
:
any
,
index
:
number
)
=>
({
id
:
index
+
1
,
id
:
index
+
1
,
title
:
`阶段
${
index
+
1
}
:
${
stage
.
stage
}
`
,
title
:
`阶段
${
chineseNum
[
index
]
||
index
+
1
}
:
${
stage
.
stage
}
`
,
description
:
stage
.
stage
,
description
:
stage
.
stage
,
riskLevel
:
probabilityToRisk
(
stage
.
predicted_pass_probability
),
riskLevel
:
probabilityToRisk
(
stage
.
predicted_pass_probability
),
progressLevel
:
probabilityToProgressLevel
(
stage
.
predicted_pass_probability
),
progressLevel
:
probabilityToProgressLevel
(
stage
.
predicted_pass_probability
),
...
@@ -387,7 +389,7 @@ function transformPredictionResult(data: any) {
...
@@ -387,7 +389,7 @@ function transformPredictionResult(data: any) {
]
]
},
},
predictionBasis
:
stage
.
prediction_basis
predictionBasis
:
stage
.
prediction_basis
}))
}))
return
{
return
{
title
:
'立法进展阶段预测分析'
,
title
:
'立法进展阶段预测分析'
,
...
...
src/views/thinkTank/MultiThinkTankViewAnalysis/index.vue
浏览文件 @
ab4c3907
...
@@ -228,11 +228,9 @@
...
@@ -228,11 +228,9 @@
<
div
v
-
for
=
"(sv, svIdx) in item.sourceViewDetails"
:
key
=
"`${sv.report_id
}
-${sv.view_id
}
-${svIdx
}
`"
<
div
v
-
for
=
"(sv, svIdx) in item.sourceViewDetails"
:
key
=
"`${sv.report_id
}
-${sv.view_id
}
-${svIdx
}
`"
class
=
"source-view-detail"
>
class
=
"source-view-detail"
>
<
div
class
=
"source-view-detail-title"
>
<
div
class
=
"source-view-detail-title"
>
<
span
<
span
class
=
"source-view-detail-title-text"
class
=
"source-view-detail-title-text"
:
class
=
"{ 'is-clickable-report': hasReportLinkForSourceView(sv)
}
"
:
class
=
"{ 'is-clickable-report': hasReportLinkForSourceView(sv)
}
"
@
click
.
stop
=
"handleOpenReportOriginalFromSource(sv)"
@
click
.
stop
=
"handleOpenReportOriginalFromSource(sv)"
>
{{
getSourceViewDisplayTitle
(
sv
)
}}
<
/span
>
>
{{
getSourceViewDisplayTitle
(
sv
)
}}
<
/span
>
<
span
class
=
"source-view-detail-org"
v
-
if
=
"sv.thinktankName || sv.thinktankLogoUrl"
>
<
span
class
=
"source-view-detail-org"
v
-
if
=
"sv.thinktankName || sv.thinktankLogoUrl"
>
<
img
v
-
if
=
"sv.thinktankLogoUrl"
:
src
=
"sv.thinktankLogoUrl"
alt
=
""
/>
<
img
v
-
if
=
"sv.thinktankLogoUrl"
:
src
=
"sv.thinktankLogoUrl"
alt
=
""
/>
<
span
class
=
"source-view-detail-org-text"
>
{{
sv
.
thinktankName
}}
<
/span
>
<
span
class
=
"source-view-detail-org-text"
>
{{
sv
.
thinktankName
}}
<
/span
>
...
@@ -278,11 +276,10 @@
...
@@ -278,11 +276,10 @@
<
div
v
-
for
=
"(sv, svIdx) in item.sourceViewDetails"
<
div
v
-
for
=
"(sv, svIdx) in item.sourceViewDetails"
:
key
=
"`${sv.report_id
}
-${sv.view_id
}
-${svIdx
}
`"
class
=
"source-view-detail"
>
:
key
=
"`${sv.report_id
}
-${sv.view_id
}
-${svIdx
}
`"
class
=
"source-view-detail"
>
<
div
class
=
"source-view-detail-title"
>
<
div
class
=
"source-view-detail-title"
>
<
span
<
span
class
=
"source-view-detail-title-text"
class
=
"source-view-detail-title-text"
:
class
=
"{ 'is-clickable-report': hasReportLinkForSourceView(sv)
}
"
:
class
=
"{ 'is-clickable-report': hasReportLinkForSourceView(sv)
}
"
@
click
.
stop
=
"handleOpenReportOriginalFromSource(sv)"
@
click
.
stop
=
"handleOpenReportOriginalFromSource(sv)"
>
{{
getSourceViewDisplayTitle
(
sv
)
>
{{
getSourceViewDisplayTitle
(
sv
)
}}
<
/span
>
}}
<
/span
>
<
span
class
=
"source-view-detail-org"
v
-
if
=
"sv.thinktankName || sv.thinktankLogoUrl"
>
<
span
class
=
"source-view-detail-org"
v
-
if
=
"sv.thinktankName || sv.thinktankLogoUrl"
>
<
img
v
-
if
=
"sv.thinktankLogoUrl"
:
src
=
"sv.thinktankLogoUrl"
alt
=
""
/>
<
img
v
-
if
=
"sv.thinktankLogoUrl"
:
src
=
"sv.thinktankLogoUrl"
alt
=
""
/>
<
span
class
=
"source-view-detail-org-text"
>
{{
sv
.
thinktankName
}}
<
/span
>
<
span
class
=
"source-view-detail-org-text"
>
{{
sv
.
thinktankName
}}
<
/span
>
...
@@ -1007,6 +1004,8 @@ onMounted(async () => {
...
@@ -1007,6 +1004,8 @@ onMounted(async () => {
flex
-
direction
:
column
;
flex
-
direction
:
column
;
align
-
items
:
center
;
align
-
items
:
center
;
overflow
-
y
:
auto
;
height
:
100
vh
;
.
header
{
.
header
{
...
@@ -1197,7 +1196,9 @@ onMounted(async () => {
...
@@ -1197,7 +1196,9 @@ onMounted(async () => {
margin
-
top
:
16
px
;
margin
-
top
:
16
px
;
width
:
1600
px
;
width
:
1600
px
;
height
:
1094
px
;
height
:
950
px
;
margin
-
bottom
:
100
px
;
.
box1
{
.
box1
{
width
:
480
px
;
width
:
480
px
;
...
...
src/views/thinkTank/ReportDetail/policyTracking/index.vue
浏览文件 @
ab4c3907
...
@@ -39,10 +39,10 @@
...
@@ -39,10 +39,10 @@
</div>
</div>
</div>
</div>
<div
class=
"box4-main-footer"
>
<div
class=
"box4-main-footer"
>
<div
class=
"info"
>
共
{{
opinionsTotal
}}
条
核心论点
</div>
<div
class=
"info"
>
共
{{
opinionsTotal
}}
条
政策建议
</div>
<div
class=
"page-box"
>
<div
class=
"page-box"
>
<el-pagination
:page
-size=
"pageSize"
background
layout=
"prev, pager, next"
:total=
"opinionsTotal
"
<el-pagination
:page
r-count=
"4"
:page-size=
"pageSize"
background
layout=
"prev, pager, next
"
@
current-change=
"handleCurrentChange"
:current-page=
"currentPage"
/>
:total=
"opinionsTotal"
@
current-change=
"handleCurrentChange"
:current-page=
"currentPage"
/>
</div>
</div>
</div>
</div>
</div>
</div>
...
@@ -368,7 +368,7 @@ onMounted(async () => {
...
@@ -368,7 +368,7 @@ onMounted(async () => {
.left
{
.left
{
width
:
506px
;
width
:
506px
;
gap
:
12
px
;
gap
:
8
px
;
display
:
flex
;
display
:
flex
;
flex-direction
:
column
;
flex-direction
:
column
;
...
@@ -406,19 +406,32 @@ onMounted(async () => {
...
@@ -406,19 +406,32 @@ onMounted(async () => {
width
:
506px
;
width
:
506px
;
gap
:
8px
;
gap
:
8px
;
display
:
flex
;
display
:
flex
;
height
:
28px
;
align-items
:
flex-start
;
margin-top
:
4px
;
padding-bottom
:
0
;
box-sizing
:
border-box
;
overflow-x
:
auto
;
overflow-y
:
hidden
;
scrollbar-gutter
:
stable
;
.tag
{
.tag
{
height
:
28px
;
height
:
28px
;
margin-bottom
:
4px
;
border
:
1px
solid
rgb
(
230
,
231
,
232
);
border
:
1px
solid
rgb
(
230
,
231
,
232
);
border-radius
:
4px
;
border-radius
:
4px
;
width
:
auto
!
important
;
flex-shrink
:
0
;
/* 不被压缩 */
padding
:
0px
8px
;
padding
:
0px
8px
;
display
:
flex
;
display
:
flex
;
cursor
:
pointer
;
cursor
:
pointer
;
white-space
:
nowrap
;
/* 强制不换行 */
&
.tag-active
{
&
.tag-active
{
border-color
:
rgb
(
5
,
95
,
194
);
border-color
:
rgb
(
5
,
95
,
194
);
...
@@ -426,6 +439,7 @@ onMounted(async () => {
...
@@ -426,6 +439,7 @@ onMounted(async () => {
.tag-text
{
.tag-text
{
color
:
rgb
(
5
,
95
,
194
);
color
:
rgb
(
5
,
95
,
194
);
}
}
}
}
...
@@ -515,6 +529,8 @@ onMounted(async () => {
...
@@ -515,6 +529,8 @@ onMounted(async () => {
.box4-main-footer
{
.box4-main-footer
{
display
:
flex
;
display
:
flex
;
justify-content
:
space-between
;
justify-content
:
space-between
;
/* empty */
}
}
}
}
...
...
src/views/thinkTank/ReportDetail/reportAnalysis/index.vue
浏览文件 @
ab4c3907
...
@@ -73,8 +73,13 @@
...
@@ -73,8 +73,13 @@
<
template
v-else
>
<
template
v-else
>
<div
class=
"box5Chart"
>
<div
class=
"box5Chart"
>
<!-- 有数据后再挂载子组件:子组件仅在 onMounted 初始化,异步数据到达后需 v-if + key 强制重新挂载 -->
<!-- 有数据后再挂载子组件:子组件仅在 onMounted 初始化,异步数据到达后需 v-if + key 强制重新挂载 -->
<WordCloudChart
v-if=
"box5Data.length"
:key=
"box5WordCloudKey"
:data=
"box5Data"
width=
"100%"
<WordCloudChart
height=
"100%"
/>
v-if=
"box5Data.length"
:key=
"box5WordCloudKey"
:data=
"box5Data"
width=
"432px"
height=
"272px"
/>
</div>
</div>
<div
class=
"box5-footer"
>
<div
class=
"box5-footer"
>
<TipTab
:text=
"REPORT_ANALYSIS_TIP_BOX5"
/>
<TipTab
:text=
"REPORT_ANALYSIS_TIP_BOX5"
/>
...
@@ -356,54 +361,21 @@ const handleClickReportAuthor = async (author) => {
...
@@ -356,54 +361,21 @@ const handleClickReportAuthor = async (author) => {
const
personId
=
author
?.
id
;
const
personId
=
author
?.
id
;
if
(
!
personId
)
return
;
if
(
!
personId
)
return
;
let
personTypeList
=
[];
try
{
personTypeList
=
JSON
.
parse
(
window
.
sessionStorage
.
getItem
(
"personTypeList"
)
||
"[]"
);
}
catch
(
e
)
{
personTypeList
=
[];
}
const
params
=
{
personId
};
const
params
=
{
personId
};
try
{
const
res
=
await
getPersonSummaryInfo
(
params
);
const
res
=
await
getPersonSummaryInfo
(
params
);
if
(
res
.
code
!==
200
||
!
res
.
data
)
return
;
if
(
res
.
code
!==
200
||
!
res
.
data
)
return
;
const
arr
=
personTypeList
.
filter
((
t
)
=>
{
const
typeIdNum
=
Number
(
t
.
typeId
);
const
personTypeNum
=
Number
(
res
.
data
.
personType
);
return
!
Number
.
isNaN
(
typeIdNum
)
&&
!
Number
.
isNaN
(
personTypeNum
)
&&
typeIdNum
===
personTypeNum
;
});
if
(
!
arr
.
length
)
{
ElMessage
.
warning
(
"找不到当前人员的类型值!"
);
return
;
}
const
personTypeName
=
arr
[
0
]?.
typeName
||
""
;
let
type
=
0
;
if
(
personTypeName
===
"科技企业领袖"
)
{
type
=
1
;
}
else
if
(
personTypeName
===
"国会议员"
)
{
type
=
2
;
}
else
if
(
personTypeName
===
"智库研究人员"
)
{
type
=
3
;
}
else
{
ElMessage
.
warning
(
"找不到当前人员的类型值!"
);
return
;
}
window
.
sessionStorage
.
setItem
(
"curTabName"
,
author
?.
name
||
""
);
window
.
sessionStorage
.
setItem
(
"curTabName"
,
author
?.
name
||
""
);
const
route
=
router
.
resolve
({
const
route
=
router
.
resolve
({
path
:
"/characterPage"
,
path
:
"/characterPage"
,
query
:
{
query
:
{
type
,
personId
personId
}
}
});
});
window
.
open
(
route
.
href
,
"_blank"
);
window
.
open
(
route
.
href
,
"_blank"
);
}
catch
(
error
)
{
console
.
error
(
"点击报告作者头像跳转失败"
,
error
);
}
};
};
const
riskSignal
=
computed
(()
=>
{
const
riskSignal
=
computed
(()
=>
{
const
info
=
props
.
thinkInfo
||
{};
const
info
=
props
.
thinkInfo
||
{};
...
@@ -921,10 +893,7 @@ onMounted(() => {
...
@@ -921,10 +893,7 @@ onMounted(() => {
.box5-main
{
.box5-main
{
width
:
480px
;
width
:
480px
;
height
:
361px
;
height
:
361px
;
padding-left
:
31px
;
padding
:
24px
24px
65px
24px
;
padding-right
:
32px
;
padding-top
:
26px
;
padding-bottom
:
43px
;
display
:
flex
;
display
:
flex
;
flex-direction
:
column
;
flex-direction
:
column
;
box-sizing
:
border-box
;
box-sizing
:
border-box
;
...
@@ -932,8 +901,8 @@ onMounted(() => {
...
@@ -932,8 +901,8 @@ onMounted(() => {
position
:
relative
;
position
:
relative
;
.box5Chart
{
.box5Chart
{
width
:
418px
;
width
:
100%
;
height
:
292px
;
height
:
100%
;
margin
:
0
auto
;
margin
:
0
auto
;
overflow
:
hidden
;
overflow
:
hidden
;
}
}
...
@@ -1023,6 +992,15 @@ onMounted(() => {
...
@@ -1023,6 +992,15 @@ onMounted(() => {
line-height
:
24px
;
line-height
:
24px
;
letter-spacing
:
0
;
letter-spacing
:
0
;
text-align
:
left
;
text-align
:
left
;
/* 👇 下面是 两行文本超出省略 核心代码 */
display
:
-
webkit-box
;
-webkit-line-clamp
:
2
;
/* 限制显示 2 行 */
-webkit-box-orient
:
vertical
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
word-break
:
break-all
;
}
}
.report-footer
{
.report-footer
{
...
@@ -1385,9 +1363,14 @@ onMounted(() => {
...
@@ -1385,9 +1363,14 @@ onMounted(() => {
height
:
80px
;
height
:
80px
;
display
:
flex
;
display
:
flex
;
justify-content
:
space-between
;
justify-content
:
space-between
;
align-items
:
center
;
padding
:
30px
5px
;
padding
:
30px
5px
;
box-sizing
:
border-box
;
overflow
:
hidden
;
.info
{
.info
{
flex
:
1
1
auto
;
min-width
:
0
;
color
:
rgba
(
132
,
136
,
142
,
1
);
color
:
rgba
(
132
,
136
,
142
,
1
);
font-family
:
Microsoft
YaHei
;
font-family
:
Microsoft
YaHei
;
font-size
:
14px
;
font-size
:
14px
;
...
@@ -1396,6 +1379,23 @@ onMounted(() => {
...
@@ -1396,6 +1379,23 @@ onMounted(() => {
letter-spacing
:
0px
;
letter-spacing
:
0px
;
text-align
:
left
;
text-align
:
left
;
}
}
.page-box
{
/* 最大 300px:允许变小,但绝不变大 */
flex
:
0
1
300px
;
width
:
100%
;
max-width
:
300px
;
min-width
:
0
;
display
:
flex
;
justify-content
:
flex-end
;
overflow
:
hidden
;
}
.page-box
:deep
(
.el-pagination
)
{
max-width
:
100%
;
min-width
:
0
;
overflow
:
hidden
;
}
}
}
}
}
...
...
src/views/thinkTank/ThinkTankDetail/PolicyTracking/index.vue
浏览文件 @
ab4c3907
...
@@ -237,7 +237,7 @@
...
@@ -237,7 +237,7 @@
<div
class=
"title"
v-html=
"highlightPolicyText(item.titleZh)"
></div>
<div
class=
"title"
v-html=
"highlightPolicyText(item.titleZh)"
></div>
<div
class=
"info"
>
<div
class=
"info"
>
<div
class=
"text"
>
<div
class=
"text"
>
<span
v-html=
"highlightPolicyText(`${item.reportDateDisplay}·${item.
contentZh
}`)"
></span>
<span
v-html=
"highlightPolicyText(`${item.reportDateDisplay}·${item.
reportName
}`)"
></span>
</div>
</div>
<div
class=
"more"
@
click=
"toDetail(item)"
>
<div
class=
"more"
@
click=
"toDetail(item)"
>
...
@@ -346,7 +346,7 @@ const getAreaTagColor = (name, idx = 0) =>
...
@@ -346,7 +346,7 @@ const getAreaTagColor = (name, idx = 0) =>
const
POLICY_TRACKING_TIP_BOX1
=
const
POLICY_TRACKING_TIP_BOX1
=
"智库报告中政策建议的领域分布情况,数据来源:美国兰德公司官网"
;
"智库报告中政策建议的领域分布情况,数据来源:美国兰德公司官网"
;
const
POLICY_TRACKING_TIP_BOX2
=
const
POLICY_TRACKING_TIP_BOX2
=
"智库报告中政策建议
涉及领域
分布情况,数据来源:美国兰德公司官网"
;
"智库报告中政策建议
部门
分布情况,数据来源:美国兰德公司官网"
;
const
POLICY_TRACKING_TIP_BOX3
=
const
POLICY_TRACKING_TIP_BOX3
=
"智库报告热门研究领域变化趋势,数据来源:美国兰德公司官网"
;
"智库报告热门研究领域变化趋势,数据来源:美国兰德公司官网"
;
...
@@ -1221,7 +1221,7 @@ function mapPolicyRowToView(row) {
...
@@ -1221,7 +1221,7 @@ function mapPolicyRowToView(row) {
const
toDetail
=
item
=>
{
const
toDetail
=
item
=>
{
window
.
sessionStorage
.
setItem
(
"curTabName"
,
item
.
contentZh
??
item
.
content
??
""
);
window
.
sessionStorage
.
setItem
(
"curTabName"
,
item
.
contentZh
??
item
.
content
??
""
);
const
route
=
router
.
resolve
({
const
route
=
router
.
resolve
({
name
:
"Report
Detai
l"
,
name
:
"Report
Origina
l"
,
params
:
{
params
:
{
id
:
item
.
reportId
id
:
item
.
reportId
}
}
...
@@ -2110,7 +2110,7 @@ onMounted(async () => {
...
@@ -2110,7 +2110,7 @@ onMounted(async () => {
line-height
:
22px
;
line-height
:
22px
;
letter-spacing
:
0px
;
letter-spacing
:
0px
;
text-align
:
left
;
text-align
:
left
;
width
:
1020px
;
white-space
:
nowrap
;
white-space
:
nowrap
;
/* 强制不换行,保持一行 */
/* 强制不换行,保持一行 */
overflow
:
hidden
;
overflow
:
hidden
;
...
...
src/views/thinkTank/ThinkTankDetail/thinkInfo/index.vue
浏览文件 @
ab4c3907
...
@@ -726,36 +726,15 @@ const handleClickPerson = async item => {
...
@@ -726,36 +726,15 @@ const handleClickPerson = async item => {
return
!
Number
.
isNaN
(
typeIdNum
)
&&
!
Number
.
isNaN
(
personTypeNum
)
&&
typeIdNum
===
personTypeNum
;
return
!
Number
.
isNaN
(
typeIdNum
)
&&
!
Number
.
isNaN
(
personTypeNum
)
&&
typeIdNum
===
personTypeNum
;
});
});
console
.
log
(
"arr"
,
arr
);
console
.
log
(
"arr"
,
arr
);
if
(
arr
&&
arr
.
length
>
0
)
{
personTypeName
=
arr
[
0
].
typeName
;
console
.
log
(
"personTypeName"
,
personTypeName
);
if
(
personTypeName
===
"科技企业领袖"
)
{
type
=
1
;
}
else
if
(
personTypeName
===
"国会议员"
)
{
type
=
2
;
}
else
if
(
personTypeName
===
"智库研究人员"
)
{
type
=
3
;
}
else
{
personTypeName
=
""
;
ElMessage
.
warning
(
"找不到当前人员的类型值!"
);
return
;
}
window
.
sessionStorage
.
setItem
(
"curTabName"
,
item
.
name
);
const
route
=
router
.
resolve
({
const
route
=
router
.
resolve
({
path
:
"/characterPage"
,
path
:
"/characterPage"
,
query
:
{
query
:
{
type
:
type
,
// type=1为科技企业领袖,2为国会议员,3为智库研究人员
personId
:
item
.
personId
personId
:
item
.
personId
}
}
});
});
window
.
open
(
route
.
href
,
"_blank"
);
window
.
open
(
route
.
href
,
"_blank"
);
}
else
{
personTypeName
=
""
;
ElMessage
.
warning
(
"找不到当前人员的类型值!"
);
return
;
}
}
else
{
}
else
{
ElMessage
.
warning
(
"找不到当前人员的类型值!"
);
ElMessage
.
warning
(
"找不到当前人员的类型值!"
);
return
;
return
;
...
@@ -779,9 +758,10 @@ onMounted(() => {
...
@@ -779,9 +758,10 @@ onMounted(() => {
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
.wrap
{
.wrap
{
width
:
100%
;
width
:
100%
;
height
:
100
%
;
height
:
100
vh
;
display
:
flex
;
display
:
flex
;
gap
:
16px
;
gap
:
16px
;
overflow-y
:
auto
;
.left
{
.left
{
margin-top
:
16px
;
margin-top
:
16px
;
...
@@ -910,7 +890,7 @@ onMounted(() => {
...
@@ -910,7 +890,7 @@ onMounted(() => {
.right
{
.right
{
width
:
1104px
;
width
:
1104px
;
/* 三栏:390 + 390 + 900,间距 16×2 */
/* 三栏:390 + 390 + 900,间距 16×2 */
height
:
17
1
2px
;
height
:
17
3
2px
;
margin-top
:
16px
;
margin-top
:
16px
;
display
:
flex
;
display
:
flex
;
flex-direction
:
column
;
flex-direction
:
column
;
...
@@ -1461,6 +1441,7 @@ onMounted(() => {
...
@@ -1461,6 +1441,7 @@ onMounted(() => {
.box.box-core-researchers
{
.box.box-core-researchers
{
width
:
1104px
;
width
:
1104px
;
height
:
900px
;
height
:
900px
;
margin-bottom
:
90px
;
flex-shrink
:
0
;
flex-shrink
:
0
;
}
}
...
...
src/views/thinkTank/components/ThinkTankPolicyAdviceOverview.vue
浏览文件 @
ab4c3907
...
@@ -48,7 +48,7 @@
...
@@ -48,7 +48,7 @@
<div
class=
"card-item-title"
>
{{
item
.
name
}}
</div>
<div
class=
"card-item-title"
>
{{
item
.
name
}}
</div>
<div
class=
"card-item-time"
>
<div
class=
"card-item-time"
>
<span
class=
"info-text"
>
{{
item
.
times
}}
·
{{
item
.
thinkTankName
}}
·
{{
item
.
reportName
}}
</span>
<span
class=
"info-text"
>
{{
item
.
times
}}
·
{{
item
.
thinkTankName
}}
·
{{
item
.
reportName
}}
</span>
<div
class=
"card-open-image"
>
<div
class=
"card-open-image"
@
click
.
stop=
"handleOpenReportOriginal(item)"
>
<img
src=
"@/views/thinkTank/ThinkTankDetail/thinkDynamics/images/image open.png"
alt=
""
/>
<img
src=
"@/views/thinkTank/ThinkTankDetail/thinkDynamics/images/image open.png"
alt=
""
/>
</div>
</div>
</div>
</div>
...
@@ -115,6 +115,17 @@ const emit = defineEmits(["filter-change", "page-change", "item-click"]);
...
@@ -115,6 +115,17 @@ const emit = defineEmits(["filter-change", "page-change", "item-click"]);
const
router
=
useRouter
();
const
router
=
useRouter
();
/** 打开报告原文:新标签页打开 /thinkTank/reportOriginal/:id(优先 reportId) */
const
handleOpenReportOriginal
=
(
item
)
=>
{
const
reportId
=
item
?.
reportId
||
item
?.
report_id
||
item
?.
id
if
(
!
reportId
)
return
const
route
=
router
.
resolve
({
name
:
"ReportOriginal"
,
params
:
{
id
:
String
(
reportId
)
}
})
window
.
open
(
route
.
href
,
"_blank"
)
}
/** 政策建议关联法案:新标签页打开法案介绍页,billId 随接口 id 变化 */
/** 政策建议关联法案:新标签页打开法案介绍页,billId 随接口 id 变化 */
const
handleBillMoreClick
=
(
bill
)
=>
{
const
handleBillMoreClick
=
(
bill
)
=>
{
const
billId
=
bill
?.
id
;
const
billId
=
bill
?.
id
;
...
...
src/views/thinkTank/index.vue
浏览文件 @
ab4c3907
...
@@ -200,7 +200,7 @@
...
@@ -200,7 +200,7 @@
<div
id=
"box5Chart"
class=
"box5-chart-canvas"
></div>
<div
id=
"box5Chart"
class=
"box5-chart-canvas"
></div>
</div>
</div>
<div
class=
"source"
>
<div
class=
"source"
>
<TipTab
:text=
"'智库报告数量变化趋势,数据来源
:
美国各智库官网'"
/>
<TipTab
:text=
"'智库报告数量变化趋势,数据来源
:
美国各智库官网'"
/>
</div>
</div>
<div
class=
"chart-box"
>
<div
class=
"chart-box"
>
<div
class=
"btn-box"
v-if=
"!isShowAiContentBox5"
@
mouseenter=
"handleSwitchAiContentShowBox5(true)"
>
<div
class=
"btn-box"
v-if=
"!isShowAiContentBox5"
@
mouseenter=
"handleSwitchAiContentShowBox5(true)"
>
...
...
src/views/thinkTank/reportOriginal/index.vue
浏览文件 @
ab4c3907
...
@@ -65,12 +65,8 @@
...
@@ -65,12 +65,8 @@
<pdf
ref=
"leftPdfRef"
:pdfUrl=
"reportUrlEnWithPage"
class=
"pdf-pane-inner"
/>
<pdf
ref=
"leftPdfRef"
:pdfUrl=
"reportUrlEnWithPage"
class=
"pdf-pane-inner"
/>
</div>
</div>
<div
class=
"pdf-pane-wrap"
:class=
"
{ 'is-full': !valueSwitch }" v-if="reportUrlWithPage">
<div
class=
"pdf-pane-wrap"
:class=
"
{ 'is-full': !valueSwitch }" v-if="reportUrlWithPage">
<pdf
<pdf
:key=
"`right-pdf-$
{valueSwitch ? 'split' : 'full'}`" ref="rightPdfRef" :pdfUrl="reportUrlWithPage"
:key=
"`right-pdf-$
{valueSwitch ? 'split' : 'full'}`"
class="pdf-pane-inner" />
ref="rightPdfRef"
:pdfUrl="reportUrlWithPage"
class="pdf-pane-inner"
/>
</div>
</div>
</div>
</div>
</div>
</div>
...
@@ -287,7 +283,8 @@ onMounted(async () => {
...
@@ -287,7 +283,8 @@ onMounted(async () => {
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
.wrap
{
.wrap
{
overflow-y
:
auto
;
height
:
100vh
;
.header
{
.header
{
...
@@ -340,6 +337,14 @@ onMounted(async () => {
...
@@ -340,6 +337,14 @@ onMounted(async () => {
line-height
:
24px
;
line-height
:
24px
;
letter-spacing
:
0px
;
letter-spacing
:
0px
;
text-align
:
left
;
text-align
:
left
;
/* 👇 下面是 两行文本超出省略 核心代码 */
display
:
-
webkit-box
;
-webkit-line-clamp
:
1
;
/* 限制显示 2 行 */
-webkit-box-orient
:
vertical
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
word-break
:
break-all
;
}
}
.tag-box
{
.tag-box
{
...
@@ -469,8 +474,9 @@ onMounted(async () => {
...
@@ -469,8 +474,9 @@ onMounted(async () => {
margin
:
0
auto
;
margin
:
0
auto
;
background
:
rgb
(
255
,
255
,
255
);
background
:
rgb
(
255
,
255
,
255
);
width
:
1600px
;
width
:
1600px
;
height
:
928px
;
height
:
948px
;
overflow
:
hidden
;
margin-bottom
:
86px
;
border
:
1px
,
solid
,
rgb
(
234
,
236
,
238
);
border
:
1px
,
solid
,
rgb
(
234
,
236
,
238
);
box-shadow
:
0
0
20px
0
rgba
(
25
,
69
,
130
,
0
.1
);
box-shadow
:
0
0
20px
0
rgba
(
25
,
69
,
130
,
0
.1
);
...
...
src/views/thinkTank/reportOriginal/pdf.vue
浏览文件 @
ab4c3907
...
@@ -12,8 +12,8 @@
...
@@ -12,8 +12,8 @@
<
script
>
<
script
>
import
{
ref
,
shallowRef
,
nextTick
,
watch
}
from
'vue'
;
import
{
ref
,
shallowRef
,
nextTick
,
watch
}
from
'vue'
;
import
*
as
pdfjsLib
from
'pdfjs-dist/
build/pdf.mjs
'
;
import
*
as
pdfjsLib
from
'pdfjs-dist/
legacy/build/pdf
'
;
import
pdfWorkerUrl
from
'pdfjs-dist/
build/pdf.worker.min.mjs
?url'
;
import
pdfWorkerUrl
from
'pdfjs-dist/
legacy/build/pdf.worker.min
?url'
;
// 通过 Vite 的 ?url 产出静态资源地址,确保线上/线下都能正确加载 worker
// 通过 Vite 的 ?url 产出静态资源地址,确保线上/线下都能正确加载 worker
pdfjsLib
.
GlobalWorkerOptions
.
workerSrc
=
pdfWorkerUrl
;
pdfjsLib
.
GlobalWorkerOptions
.
workerSrc
=
pdfWorkerUrl
;
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论