Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
R
risk-monitor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蔡建
risk-monitor
Commits
15c01871
提交
15c01871
authored
11月 25, 2025
作者:
caijian
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'cj_dev'
上级
d0f3c45c
e4a5b60a
隐藏空白字符变更
内嵌
并排
正在显示
7 个修改的文件
包含
1032 行增加
和
461 行删除
+1032
-461
PolicyList.vue
src/components/PolicyList.vue
+175
-137
PolicyTab.vue
src/components/PolicyTab.vue
+3
-2
DescTab.vue
src/views/thinkTank/ThinkTankDetail/DescTab.vue
+257
-312
FundingSource.vue
src/views/thinkTank/ThinkTankDetail/FundingSource.vue
+304
-0
ReportTab.vue
src/views/thinkTank/ThinkTankDetail/ReportTab.vue
+8
-3
index.vue
src/views/thinkTank/ThinkTankDetail/index.vue
+8
-5
mockData.js
src/views/thinkTank/mockData.js
+277
-2
没有找到文件。
src/components/PolicyList.vue
浏览文件 @
15c01871
<
template
>
<div
class=
"policy-list"
>
<div
v-for=
"item in props.policyList"
:key=
"item.id"
class=
"policy-item"
>
<el-image
:src=
"$withFallbackImage(item.imageUrl, item.content) "
class=
"item-cover"
fit=
"cover"
/>
<div
class=
"item-details"
>
<h3
class=
"item-title"
>
{{
item
.
name
}}
</h3>
<div
class=
"item-content"
>
{{
item
.
times
}}
·
{{
item
.
content
}}
<el-icon><Link
/></el-icon></div>
<div
class=
"item-tags"
>
<el-tag
v-for=
"tag in item.tags"
:key=
"tag"
class=
"custom-tag"
>
{{
tag
}}
</el-tag>
<div
v-for=
"(item, index) in policyList"
:key=
"index"
class=
"policy-item"
>
<div
class=
"item-left"
>
<div
class=
"report-cover"
>
<img
:src=
"$withFallbackImage(item.imageUrl, index)"
alt=
"Report Cover"
/>
</div>
<div
v-if=
"item.relatedBill"
class=
"related-bill-box"
:class=
"`status-bg-$
{item.status}`"
>
<span>
{{
item
.
relatedBill
.
text
}}
</span>
<div
class=
"status-badge"
:class=
"`status-color-$
{item.status}`">
<span
class=
"badge-dot"
></span>
{{
getStatusInfo
(
item
.
status
).
text
}}
</div>
</div>
<div
class=
"item-right"
>
<h3
class=
"item-title"
>
{{
item
.
content
}}
</h3>
<div
class=
"item-meta"
>
<span
class=
"meta-date"
>
{{
formatDate
(
item
.
times
)
}}
</span>
<span
class=
"meta-divider"
>
·
</span>
<span
class=
"meta-source"
>
{{
item
.
name
}}
<el-icon
class=
"link-icon"
><TopRight
/></el-icon>
</span>
</div>
<div
class=
"item-tags"
v-if=
"item.tags && item.tags.length"
>
<span
v-for=
"(tag, tIndex) in item.tags"
:key=
"tIndex"
class=
"tag-pill"
>
{{
tag
}}
</span>
</div>
<div
v-else
class=
"related-bill-box status-bg-unimplemented"
>
<span>
不存在相关提案。
</span>
<div
class=
"status-badge status-color-unimplemented"
>
<span
class=
"badge-dot"
></span>
{{
item
.
status
}}
<div
class=
"item-actions"
v-if=
"item.statusRaw"
>
<div
v-for=
"(statusItem, sIndex) in parseStatus(item.statusRaw)"
:key=
"sIndex"
class=
"status-link"
>
<span
class=
"status-type"
>
{{
statusItem
.
type
}}
</span>
<span
class=
"status-year"
>
{{
statusItem
.
year
}}
</span>
<span
class=
"status-name"
>
《
{{
statusItem
.
name
}}
》
</span>
<el-icon
class=
"arrow-icon"
><Right
/></el-icon>
</div>
</div>
</div>
...
...
@@ -33,35 +48,53 @@
</div>
</
template
>
<
script
setup
>
import
{
ref
}
from
'vue'
import
{
Link
}
from
'@element-plus/icons-vue'
const
props
=
defineProps
({
policyList
:
{
type
:
Array
,
default
:
()
=>
[]
}
})
// --- Status Styling Helper ---
const
getStatusInfo
=
(
status
)
=>
{
switch
(
status
)
{
case
'implemented'
:
return
{
text
:
'已实施'
,
color
:
'#e66657'
,
bgColor
:
'#fdeeed'
};
case
'partial'
:
return
{
text
:
'部分实施'
,
color
:
'#d38f24'
,
bgColor
:
'#fcf3e4'
};
case
'unimplemented'
:
return
{
text
:
'未实施'
,
color
:
'#409eff'
,
bgColor
:
'#ecf5ff'
};
default
:
return
{
text
:
'未知'
,
color
:
'#909399'
,
bgColor
:
'#f4f4f5'
};
}
};
<
script
setup
lang=
"ts"
>
import
{
TopRight
,
Right
}
from
'@element-plus/icons-vue'
interface
PolicyItem
{
content
:
string
;
statusRaw
:
string
;
// 原始的长字符串
name
:
string
;
times
:
string
;
tags
?:
string
[];
coverUrl
?:
string
;
}
const
props
=
defineProps
<
{
policyList
:
PolicyItem
[]
}
>
()
// 格式化日期:2025-06-26 -> 2025年6月26日
const
formatDate
=
(
dateStr
:
string
)
=>
{
if
(
!
dateStr
)
return
''
;
const
date
=
new
Date
(
dateStr
);
return
`
${
date
.
getFullYear
()}
年
${
date
.
getMonth
()
+
1
}
月
${
date
.
getDate
()}
日`
;
}
// 解析状态字符串
// 输入: "法案 2024 《芯片科学法案》; 政令 2025 《推动美国...》"
// 输出: 数组对象
const
parseStatus
=
(
raw
:
string
)
=>
{
if
(
!
raw
)
return
[];
// 按分号分割多个条目
const
items
=
raw
.
split
(
/
[
;;
]
/
).
map
(
s
=>
s
.
trim
()).
filter
(
s
=>
s
);
return
items
.
map
(
itemStr
=>
{
// 简单正则匹配: "类型 年份 《名称》"
// 注意:这里假设数据格式比较规范,实际需根据后端数据调整
// 尝试移除书名号进行提取
const
cleanStr
=
itemStr
.
replace
(
/
[
《》
]
/g
,
''
);
const
parts
=
cleanStr
.
split
(
' '
);
return
{
type
:
parts
[
0
]
||
'政策'
,
year
:
parts
[
1
]
||
''
,
name
:
parts
.
slice
(
2
).
join
(
' '
)
||
cleanStr
// 剩余部分作为名称
}
});
}
</
script
>
<
style
scoped
>
/* --- Policy List Styles --- */
.policy-list
{
display
:
flex
;
flex-direction
:
column
;
...
...
@@ -70,139 +103,143 @@ const getStatusInfo = (status) => {
.policy-item
{
display
:
flex
;
padding
:
20px
0
;
border-bottom
:
1px
solid
#e4e7ed
;
border-bottom
:
1px
solid
#ebeef5
;
gap
:
16px
;
transition
:
background-color
0.2s
;
}
.policy-item
:last-child
{
border-bottom
:
none
;
}
.item-cover
{
width
:
80px
;
height
:
80px
;
margin-right
:
20px
;
/* 左侧封面 */
.item-left
{
flex-shrink
:
0
;
border-radius
:
4px
;
border
:
1px
solid
#ebeef5
;
}
.item-details
{
flex-grow
:
1
;
.report-cover
{
width
:
60px
;
height
:
80px
;
background-color
:
#f2f3f5
;
border
:
1px
solid
#e4e7ed
;
border-radius
:
2px
;
overflow
:
hidden
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
}
.report-cover
img
{
width
:
100%
;
height
:
100%
;
object-fit
:
cover
;
}
/* 右侧内容 */
.item-right
{
flex
:
1
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
space-between
;
}
/* 1. 标题 */
.item-title
{
margin
:
0
0
6px
0
;
font-size
:
16px
;
font-weight
:
600
;
color
:
#303133
;
margin
:
0
0
8px
;
cursor
:
pointer
;
font-weight
:
700
;
color
:
#1a1a1a
;
line-height
:
1.4
;
cursor
:
pointer
;
}
.item-title
:hover
{
color
:
#409
eff
;
color
:
#409
EFF
;
}
.item-content
{
color
:
#909399
;
font-size
:
14px
;
/* 2. 元数据 */
.item-meta
{
display
:
flex
;
align-items
:
center
;
font-size
:
13px
;
color
:
#606266
;
margin-bottom
:
8px
;
}
.item-tags
{
margin-bottom
:
12px
;
}
.custom-tag
{
margin-right
:
8px
;
background-color
:
#f0f2f5
;
color
:
#606266
;
border-color
:
#e4e7ed
;
font-size
:
12px
;
.meta-divider
{
margin
:
0
8px
;
font-weight
:
bold
;
}
.
related-bill-box
{
.
meta-source
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
padding
:
8px
12px
;
border-radius
:
6px
;
font-size
:
14px
;
line-height
:
1.4
;
gap
:
4px
;
cursor
:
pointer
;
}
.meta-source
:hover
{
color
:
#409EFF
;
}
.status-badge
{
.link-icon
{
font-size
:
12px
;
}
/* 3. 标签 */
.item-tags
{
display
:
flex
;
align-items
:
center
;
font-size
:
13px
;
padding
:
4px
8px
;
border-radius
:
4px
;
white-space
:
nowrap
;
font-weight
:
500
;
gap
:
8px
;
margin-bottom
:
10px
;
}
.
badge-dot
{
width
:
6px
;
height
:
6px
;
border-radius
:
50%
;
background-color
:
currentColor
;
margin-right
:
6
px
;
.
tag-pill
{
background-color
:
#f2f3f5
;
color
:
#5e6d82
;
font-size
:
12px
;
padding
:
2px
8px
;
border-radius
:
4
px
;
}
/* Dynamic status colors */
.status-bg-implemented
{
background-color
:
#fdeeed
;
/* 4. 底部状态链接 */
.item-actions
{
display
:
flex
;
flex-wrap
:
wrap
;
gap
:
10px
;
}
.status-color-implemented
{
color
:
#e66657
;
.status-link
{
display
:
inline-flex
;
align-items
:
center
;
background-color
:
#ecf5ff
;
/* 浅蓝色背景 */
color
:
#409EFF
;
/* 蓝色文字 */
padding
:
4px
12px
;
border-radius
:
4px
;
font-size
:
13px
;
font-weight
:
500
;
cursor
:
pointer
;
transition
:
all
0.2s
;
}
.status-
bg-partial
{
background-color
:
#
fcf3e4
;
.status-
link
:hover
{
background-color
:
#
d9ecff
;
}
.status-color-partial
{
color
:
#d38f24
;
.status-type
{
font-weight
:
bold
;
margin-right
:
4px
;
}
.status-
bg-unimplemented
{
background-color
:
#ecf5ff
;
.status-
year
{
margin-right
:
4px
;
}
.status-
color-unimplemented
{
color
:
#409eff
;
.status-
name
{
margin-right
:
4px
;
}
/* 响应式设计 */
@media
(
max-width
:
768px
)
{
.policy-item
{
flex-direction
:
column
;
gap
:
12px
;
padding
:
16px
0
;
}
.item-cover
{
width
:
100%
;
height
:
120px
;
margin-right
:
0
;
margin-bottom
:
12px
;
}
.item-title
{
font-size
:
15px
;
}
.related-bill-box
{
flex-direction
:
column
;
align-items
:
flex-start
;
gap
:
8px
;
padding
:
12px
;
}
.status-badge
{
align-self
:
flex-end
;
}
.arrow-icon
{
margin-left
:
4px
;
font-size
:
12px
;
}
</
style
>
</
style
>
\ No newline at end of file
src/components/PolicyTab.vue
浏览文件 @
15c01871
...
...
@@ -82,7 +82,7 @@ import PolicyList from './PolicyList.vue';
import
CardTitle
from
'./CardTitle.vue'
;
import
{
getOverviewPolicy
}
from
'@/api'
import
PolicyOverview
from
'@/views/thinkTank/components/PolicyOverview.vue'
import
{
mockPolicyList
}
from
'@/views/thinkTank/mockData'
;
const
props
=
defineProps
({
showSearch
:
{
type
:
Boolean
,
...
...
@@ -120,7 +120,8 @@ const getPolicies = async () => {
researchTypeIds
:
activeTechField
.
value
,
statusList
:
activeStatus
.
value
,
})
policies
.
value
=
data
// policies.value = data
policies
.
value
=
mockPolicyList
}
...
...
src/views/thinkTank/ThinkTankDetail/DescTab.vue
浏览文件 @
15c01871
<
template
>
<div
class=
"desc-tab"
>
<!-- 上半部分:基本信息和
概况
-->
<!-- 上半部分:基本信息和
经费来源
-->
<div
class=
"top-section"
>
<!-- 左侧:基本信息卡片 -->
<div
class=
"basic-info-card"
>
<!-- 基本信息 cardtitle -->
<CardTitle
title=
"基本信息"
/>
<div
class=
"tank-image"
>
<img
src=
"https://images.unsplash.com/photo-1486406146926-c627a92ad1ab?ixlib=rb-4.0.3&q=85&fm=jpg&crop=entropy&cs=srgb&w=400"
alt=
"智库建筑"
/>
...
...
@@ -41,58 +40,19 @@
<div
class=
"branch-list"
>
<div
class=
"branch-item"
v-for=
"(item, key) in branchInfo"
:key=
"key"
>
<span
class=
"location"
>
{{
key
}}
:
</span>
<span
class=
"desc"
>
{{
item
.
join
(
'、'
)
}}
</span>
<span
class=
"desc"
>
{{
item
.
join
(
'、'
)
}}
</span>
</div>
</div>
</div>
</div>
<!-- 右侧:经费概况和研究领域 -->
<div
class=
"right-section"
>
<!-- 经费概况 -->
<div
class=
"funding-overview"
>
<div
class=
"section-header"
>
<CardTitle
title=
"经费来源"
/>
<el-icon
class=
"expand-icon"
><MoreFilled
/></el-icon>
</div>
<div
class=
"funding-content"
>
<!-- 左侧总计信息 -->
<div
class=
"funding-left"
>
<!-- 总计 -->
<div
class=
"funding-total"
>
<div
class=
"total-label"
>
总计
</div>
<div
class=
"total-amount"
>
{{
fundTotal
.
totalJe
}}
美元
</div>
</div>
<!-- 主要分类 -->
<div
class=
"funding-categories"
>
<div
class=
"category-group"
>
<div
class=
"category-header"
>
<div
class=
"category-title"
>
政府部门
</div>
<div
class=
"category-amount"
>
{{
fundTotal
.
zfJe
}}
美元
</div>
</div>
</div>
<div
class=
"category-group"
>
<div
class=
"category-header"
>
<div
class=
"category-title"
>
其他机构
</div>
<div
class=
"category-amount"
>
{{
fundTotal
.
otherJe
}}
美元
</div>
</div>
</div>
</div>
</div>
<!-- 右侧ECharts环形饼图 -->
<div
class=
"funding-right"
>
<div
ref=
"fundingChart"
class=
"funding-chart"
></div>
</div>
</div>
</div>
<!-- 右侧:经费来源 -->
<div
class=
"funding-section"
>
<FundingSource
style=
"margin-bottom: 20px"
/>
<!-- 中间部分:研究领域演变 -->
<div
class=
"timeline-section"
>
<div
class=
"section-header"
>
<CardTitle
title=
"研究领域
概览
"
/>
<CardTitle
title=
"研究领域
演变
"
/>
<el-icon
class=
"expand-icon"
><MoreFilled
/></el-icon>
</div>
...
...
@@ -102,7 +62,6 @@
<div
class=
"period-title"
>
{{
value
.
time
}}
</div>
<div
class=
"period-desc"
>
{{
value
.
describe
}}
</div>
</div>
</div>
<div
class=
"timeline-line"
>
...
...
@@ -113,28 +72,37 @@
</div>
</div>
</div>
<!-- 核心研究人员 -->
<!-- 底部:核心研究人员 -->
<div
class=
"core-researchers-section"
>
<div
class=
"section-header"
>
<div
class=
"section-header"
>
<CardTitle
title=
"核心研究人员"
/>
<el-icon
class=
"more-icon"
>
<MoreFilled
/>
</el-icon>
</div>
<div
class=
"researchers-grid"
>
<div
class=
"researchers-column"
>
<el-icon
class=
"more-icon"
><MoreFilled
/></el-icon>
</div>
<div
class=
"researchers-content"
>
<!-- 左侧:树状图 -->
<div
class=
"researchers-treemap"
>
<div
ref=
"researcherChart"
class=
"researcher-chart"
></div>
</div>
<!-- 右侧:人员列表 -->
<div
class=
"researchers-list"
>
<div
v-for=
"researcher in coreResearchers"
:key=
"researcher.id"
class=
"researcher-item"
>
<div
class=
"researcher-avatar"
>
<el-image
:src=
"$withFallbackImage(researcher.avatar, researcher.name)
"
:alt=
"researcher.name"
/>
<el-image
:src=
"$withFallbackImage(researcher.avatar, researcher.name)"
:alt=
"researcher.name"
/>
</div>
<div
class=
"researcher-info"
>
<h4
class=
"researcher-name"
>
{{
researcher
.
name
}}
</h4>
<p
class=
"researcher-position"
>
{{
researcher
.
describe
}}
</p>
<div
class=
"researcher-previous"
v-if=
"researcher.previousRoles && researcher.previousRoles.length"
>
<span
class=
"previous-label"
>
之前:
</span>
<span
class=
"previous-roles"
>
{{
researcher
.
previousRoles
.
join
(
'、'
)
}}
</span>
</div>
<p
class=
"researcher-position"
>
{{
researcher
.
currentPosition
}}
</p>
</div>
</div>
</div>
...
...
@@ -151,6 +119,9 @@
import
{
ref
,
onMounted
,
nextTick
}
from
'vue'
import
{
MoreFilled
}
from
'@element-plus/icons-vue'
import
*
as
echarts
from
'echarts'
import
CardTitle
from
'@/components/CardTitle.vue'
import
FundingSource
from
'./FundingSource.vue'
import
{
getThinkTankBasicInfo
,
getThinkTankBranchInfo
,
...
...
@@ -160,15 +131,30 @@ import {
getThinkTankPersonList
}
from
'@/api'
import
{
useRoute
}
from
'vue-router'
import
{
mockRandBasicInfo
,
mockRandBranchInfo
,
mockRandFundsSource
,
mockRandFundsByType
,
mockRandFundsByEntity
,
mockRandFundTotal
,
mockRandResearchAreas
,
mockRandCoreResearchers
,
mockRandResearcherCategories
}
from
'../mockData'
// 组件状态
const
activeTimelinePeriod
=
ref
(
0
)
const
fundingChart
=
ref
(
null
)
const
researcherChart
=
ref
(
null
)
const
route
=
useRoute
()
// 经费数据
const
fundingData
=
ref
([])
const
fundsByType
=
ref
([])
const
fundsByEntity
=
ref
([])
// 初始化
ECharts图表
// 初始化
经费饼图
const
initFundingChart
=
()
=>
{
if
(
!
fundingChart
.
value
)
return
...
...
@@ -183,7 +169,7 @@ const initFundingChart = () => {
{
name
:
'经费来源'
,
type
:
'pie'
,
radius
:
[
'50%'
,
'70%'
],
// 环形图
radius
:
[
'50%'
,
'70%'
],
center
:
[
'50%'
,
'50%'
],
avoidLabelOverlap
:
false
,
itemStyle
:
{
...
...
@@ -192,38 +178,10 @@ const initFundingChart = () => {
borderWidth
:
2
},
label
:
{
show
:
true
,
position
:
'outside'
,
formatter
:
(
params
)
=>
{
return
`{amount|
${
params
.
value
}
万} {percent|
${
params
.
percent
}
%}\n{name|
${
params
.
name
}
}`
},
rich
:
{
amount
:
{
fontSize
:
12
,
fontWeight
:
'bold'
,
color
:
'#1f2937'
},
percent
:
{
fontSize
:
11
,
color
:
'#6b7280'
},
name
:
{
fontSize
:
11
,
color
:
'#4b5563'
,
lineHeight
:
16
}
},
lineHeight
:
14
show
:
false
},
labelLine
:
{
show
:
true
,
length
:
20
,
length2
:
15
,
smooth
:
0.2
,
lineStyle
:
{
color
:
'#d1d5db'
,
width
:
1
}
show
:
false
},
data
:
fundingData
.
value
.
map
(
item
=>
({
value
:
item
.
value
,
...
...
@@ -235,83 +193,105 @@ const initFundingChart = () => {
chart
.
setOption
(
option
)
// 响应式处理
const
handleResize
=
()
=>
{
chart
.
resize
()
}
window
.
addEventListener
(
'resize'
,
handleResize
)
// 组件销毁时清理
return
()
=>
{
window
.
removeEventListener
(
'resize'
,
handleResize
)
chart
.
dispose
()
}
}
// 时间线数据
const
timelinePeriods
=
ref
([
{
title
:
'1940s-1950s'
,
description
:
'军事战略研究与国家安全研究,包括核战略、数学大战略分析'
},
{
title
:
'1960s-1970s'
,
description
:
'扩展至社会科学领域,包括教育政策、医疗卫生、城市问题研究'
},
{
title
:
'1980s-1990s'
,
description
:
'增加国际发展研究,关注苏联解体后的地缘政治格局'
},
{
title
:
'2000s-2010s'
,
description
:
'重点关注反恐战略,网络安全、能源政策和气候变化'
},
{
title
:
'2020s-现在'
,
description
:
'聚焦人工智能、大数据分析、全球竞争与合作关系'
// 初始化研究人员树状图
const
initResearcherChart
=
()
=>
{
if
(
!
researcherChart
.
value
)
return
const
chart
=
echarts
.
init
(
researcherChart
.
value
)
// 将分类数据转换为树状图格式
const
treemapData
=
[]
Object
.
keys
(
mockRandResearcherCategories
).
forEach
(
category
=>
{
const
children
=
Object
.
keys
(
mockRandResearcherCategories
[
category
]).
map
(
item
=>
({
name
:
item
,
value
:
mockRandResearcherCategories
[
category
][
item
]
}))
treemapData
.
push
({
name
:
category
,
value
:
children
.
reduce
((
sum
,
item
)
=>
sum
+
item
.
value
,
0
),
children
:
children
})
})
const
option
=
{
tooltip
:
{
trigger
:
'item'
,
formatter
:
'{b}: {c}人'
},
series
:
[
{
type
:
'treemap'
,
data
:
treemapData
,
roam
:
false
,
nodeClick
:
false
,
breadcrumb
:
{
show
:
false
},
label
:
{
show
:
true
,
formatter
:
'{b}
\
n{c}人'
,
fontSize
:
12
},
upperLabel
:
{
show
:
true
,
height
:
30
},
itemStyle
:
{
borderColor
:
'#fff'
,
borderWidth
:
2
,
gapWidth
:
2
}
}
]
}
])
// 旧的经费数据(已被上面的ECharts数据替代)
// const fundingData = ref({
// total: '4.358亿美元',
// government: '3.271亿美元',
// other: '1.087亿美元'
// })
chart
.
setOption
(
option
)
const
handleResize
=
()
=>
{
chart
.
resize
()
}
window
.
addEventListener
(
'resize'
,
handleResize
)
return
()
=>
{
window
.
removeEventListener
(
'resize'
,
handleResize
)
chart
.
dispose
()
}
}
// 研究领域数据
const
researchAreas
=
ref
([])
const
thinkTankInfo
=
ref
({})
const
getThinkTankInfo
=
async
()
=>
{
const
{
data
}
=
await
getThinkTankBasicInfo
({
id
:
route
.
params
.
id
})
console
.
log
(
data
)
thinkTankInfo
.
value
=
data
thinkTankInfo
.
value
=
mockRandBasicInfo
}
const
branchInfo
=
ref
({})
const
getBranchInfo
=
async
()
=>
{
const
{
data
}
=
await
getThinkTankBranchInfo
({
id
:
route
.
params
.
id
})
// 以 area 为分组,将city 以逗号分隔
let
branchInfoObj
=
{}
data
.
forEach
(
item
=>
{
if
(
!
branchInfoObj
[
item
.
area
])
{
branchInfoObj
[
item
.
area
]
=
[]
}
branchInfoObj
[
item
.
area
].
push
(
item
.
city
)
})
branchInfo
.
value
=
branchInfoObj
branchInfo
.
value
=
mockRandBranchInfo
}
const
getFundsSource
=
async
()
=>
{
const
{
data
}
=
await
getThinkTankFundsSource
({
id
:
route
.
params
.
id
})
console
.
log
(
'getFundsSource'
,
data
)
fundingData
.
value
=
data
.
map
(
item
=>
({
fundingData
.
value
=
mockRandFundsSource
.
map
(
item
=>
({
value
:
item
.
amount
,
name
:
item
.
institution
,
// color: item.percent
}))
initFundingChart
()
fundsByType
.
value
=
mockRandFundsByType
fundsByEntity
.
value
=
mockRandFundsByEntity
nextTick
(()
=>
{
initFundingChart
()
})
}
const
fundTotal
=
ref
({
...
...
@@ -320,23 +300,21 @@ const fundTotal = ref({
otherJe
:
0
})
const
getFundTotal
=
async
()
=>
{
const
{
data
}
=
await
getThinkTankFundsTotal
({
id
:
route
.
params
.
id
})
console
.
log
(
'getFundTotal'
,
data
)
fundTotal
.
value
=
data
fundTotal
.
value
=
mockRandFundTotal
}
const
getResearchArea
=
async
()
=>
{
const
{
data
}
=
await
getThinkTankResearchArea
({
id
:
route
.
params
.
id
})
console
.
log
(
'getResearchArea'
,
data
)
researchAreas
.
value
=
data
researchAreas
.
value
=
mockRandResearchAreas
}
const
getPersonList
=
async
()
=>
{
const
{
data
}
=
await
getThinkTankPersonList
({
id
:
route
.
params
.
id
})
console
.
log
(
'getPersonList'
,
data
)
coreResearchers
.
value
=
data
coreResearchers
.
value
=
mockRandCoreResearchers
nextTick
(()
=>
{
initResearcherChart
()
})
}
// 初始化图表
// 初始化
onMounted
(
async
()
=>
{
getThinkTankInfo
()
getBranchInfo
()
...
...
@@ -348,9 +326,21 @@ onMounted(async () => {
// 核心研究人员数据
const
coreResearchers
=
ref
([])
// 格式化货币显示
const
formatCurrency
=
(
amount
)
=>
{
if
(
!
amount
)
return
'0美元'
const
formatted
=
(
amount
/
100000000
).
toFixed
(
2
)
return
`
${
formatted
}
亿美元`
}
// 格式化金额(万美元)
const
formatAmount
=
(
amount
)
=>
{
return
`
${
amount
}
万`
}
</
script
>
<
style
scoped
>
<
style
scoped
lang=
"scss"
>
.desc-tab
{
min-height
:
100vh
;
}
...
...
@@ -360,6 +350,7 @@ const coreResearchers = ref([])
display
:
flex
;
gap
:
20px
;
align-items
:
flex-start
;
margin-bottom
:
20px
;
}
/* 基本信息卡片 */
...
...
@@ -406,11 +397,10 @@ const coreResearchers = ref([])
font-size
:
14px
;
}
.additional-info
h4
{
font-size
:
16px
;
font-weight
:
600
;
color
:
#111827
;
margin
:
0
0
16px
0
;
.additional-info
{
margin-top
:
24px
;
padding-top
:
24px
;
border-top
:
1px
solid
#e5e7eb
;
}
.branch-list
{
...
...
@@ -434,16 +424,12 @@ const coreResearchers = ref([])
color
:
#6b7280
;
}
/* 右侧区域 */
.right-section
{
display
:
flex
;
flex-direction
:
column
;
gap
:
20px
;
/* 经费来源区域 */
.funding-section
{
flex
:
1
;
}
/* 通用卡片样式 */
.funding-overview
,
.research-overview
{
.funding-overview
{
background
:
white
;
border-radius
:
12px
;
padding
:
24px
;
...
...
@@ -457,154 +443,102 @@ const coreResearchers = ref([])
margin-bottom
:
20px
;
}
.section-header
h3
{
font-size
:
18px
;
font-weight
:
600
;
color
:
#111827
;
margin
:
0
;
}
.expand-icon
{
color
:
#9ca3af
;
cursor
:
pointer
;
font-size
:
18px
;
}
/* 经费
概况
*/
.funding-
content
{
/* 经费
汇总
*/
.funding-
summary
{
display
:
flex
;
gap
:
40px
;
align-items
:
flex-start
;
}
.funding-left
{
flex
:
0
0
280px
;
min-width
:
0
;
gap
:
30px
;
margin-bottom
:
24px
;
padding-bottom
:
20px
;
border-bottom
:
1px
solid
#e5e7eb
;
}
.funding-total
{
margin-bottom
:
20px
;
padding-bottom
:
16px
;
border-bottom
:
1px
solid
#e5e7eb
;
.summary-item
{
flex
:
1
;
}
.
total
-label
{
.
summary
-label
{
font-size
:
14px
;
color
:
#6b7280
;
margin-bottom
:
4
px
;
margin-bottom
:
8
px
;
}
.
total
-amount
{
font-size
:
2
4
px
;
.
summary
-amount
{
font-size
:
2
0
px
;
font-weight
:
700
;
color
:
#1f2937
;
}
.funding-categories
{
margin-bottom
:
20px
;
}
.category-group
{
margin-bottom
:
16px
;
}
.category-header
{
/* 经费详情 */
.funding-details
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
padding
:
8px
0
;
}
.category-title
{
font-size
:
16px
;
font-weight
:
600
;
color
:
#374151
;
}
.category-amount
{
font-size
:
16px
;
font-weight
:
600
;
color
:
#dc2626
;
}
.funding-right
{
flex
:
1
;
position
:
relative
;
min-height
:
400px
;
}
.funding-chart
{
width
:
100%
;
height
:
400px
;
min-height
:
400px
;
}
/* 研究领域概览 */
.research-content
{
display
:
flex
;
align-items
:
center
;
gap
:
24px
;
}
.research-chart
{
flex-shrink
:
0
;
}
.research-list
{
flex
:
1
;
gap
:
20px
;
align-items
:
flex-start
;
}
.research-item
{
.funding-table-left
,
.funding-table-right
{
flex
:
0
0
200px
;
display
:
flex
;
align-items
:
center
;
flex-direction
:
column
;
gap
:
12px
;
margin-bottom
:
12px
;
}
.research-item
:last-child
{
margin-bottom
:
0
;
.table-item
{
display
:
flex
;
flex-direction
:
column
;
gap
:
4px
;
padding
:
8px
0
;
border-bottom
:
1px
solid
#f3f4f6
;
}
.color-dot
{
width
:
12px
;
height
:
12px
;
border-radius
:
50%
;
flex-shrink
:
0
;
.table-item
:last-child
{
border-bottom
:
none
;
}
.research-info
{
display
:
flex
;
align-items
:
center
;
gap
:
8px
;
flex
:
1
;
.table-name
{
font-size
:
13px
;
color
:
#374151
;
line-height
:
1
.4
;
}
.research-info
.percentage
{
.table-amount
{
font-size
:
14px
;
font-weight
:
600
;
color
:
#111827
;
min-width
:
30px
;
font-size
:
14px
;
}
.
research-info
.name
{
color
:
#374151
;
font-size
:
14px
;
.
table-percent
{
font-size
:
12px
;
color
:
#6b7280
;
}
/* 饼图样式 */
.pie-chart
{
position
:
relative
;
.funding-chart-wrapper
{
flex
:
1
;
min-height
:
300px
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
}
.pie-chart
svg
{
transform
:
rotate
(
-90deg
);
.funding-chart
{
width
:
100%
;
height
:
300px
;
min-height
:
300px
;
}
/*
时间线部分
*/
/*
研究领域演变
*/
.timeline-section
{
background
:
white
;
border-radius
:
12px
;
padding
:
24px
;
box-shadow
:
0
2px
8px
rgba
(
0
,
0
,
0
,
0
.06
);
margin-bottom
:
20px
;
}
.timeline-container
{
...
...
@@ -654,7 +588,7 @@ const coreResearchers = ref([])
top
:
0
;
left
:
0
;
height
:
100%
;
width
:
2
0%
;
width
:
10
0%
;
background
:
linear-gradient
(
90deg
,
#3b82f6
0%
,
#1d4ed8
100%
);
border-radius
:
2px
;
}
...
...
@@ -683,9 +617,8 @@ const coreResearchers = ref([])
box-shadow
:
0
0
0
2px
#3b82f6
;
}
/* 核心研究人员
样式
*/
/* 核心研究人员 */
.core-researchers-section
{
margin-top
:
20px
;
background
:
white
;
border-radius
:
12px
;
padding
:
24px
;
...
...
@@ -693,46 +626,50 @@ const coreResearchers = ref([])
margin-bottom
:
30px
;
}
.section-header
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
margin-bottom
:
24px
;
}
.section-title
{
font-size
:
18px
;
font-weight
:
600
;
color
:
#111827
;
margin
:
0
;
}
.more-icon
{
color
:
#6b7280
;
cursor
:
pointer
;
font-size
:
1
6
px
;
font-size
:
1
8
px
;
}
.more-icon
:hover
{
color
:
#374151
;
}
.researchers-grid
{
.researchers-content
{
display
:
flex
;
gap
:
30px
;
align-items
:
flex-start
;
}
.researchers-treemap
{
flex
:
1
;
min-height
:
400px
;
}
.researcher-chart
{
width
:
100%
;
height
:
400px
;
min-height
:
400px
;
}
/* 每行两个div */
.researchers-column
{
.researchers-list
{
flex
:
0
0
400px
;
display
:
flex
;
flex-
wrap
:
wrap
;
flex-
direction
:
column
;
gap
:
20px
;
width
:
100%
;
}
.researcher-item
{
width
:
48%
;
display
:
flex
;
align-items
:
flex-start
;
gap
:
12px
;
padding
:
12px
0
;
border-bottom
:
1px
solid
#f3f4f6
;
}
.researcher-item
:last-child
{
border-bottom
:
none
;
}
.researcher-avatar
{
...
...
@@ -756,13 +693,27 @@ const coreResearchers = ref([])
font-size
:
16px
;
font-weight
:
600
;
color
:
#111827
;
margin
:
0
0
4
px
0
;
margin
:
0
0
6
px
0
;
line-height
:
1
.3
;
}
.researcher-previous
{
font-size
:
12px
;
color
:
#6b7280
;
margin-bottom
:
4px
;
}
.previous-label
{
color
:
#9ca3af
;
}
.previous-roles
{
color
:
#6b7280
;
}
.researcher-position
{
font-size
:
13px
;
color
:
#
6b7280
;
color
:
#
374151
;
margin
:
0
;
line-height
:
1
.4
;
word-wrap
:
break-word
;
...
...
@@ -774,24 +725,23 @@ const coreResearchers = ref([])
flex-direction
:
column
;
}
.funding-content
,
.research-content
{
.funding-details
{
flex-direction
:
column
;
text-align
:
center
;
}
.funding-left
{
.funding-table-left
,
.funding-table-right
{
flex
:
none
;
width
:
100%
;
}
.funding-
right
{
min-height
:
30
0px
;
.funding-
chart-wrapper
{
min-height
:
25
0px
;
}
.funding-chart
{
height
:
30
0px
;
min-height
:
30
0px
;
height
:
25
0px
;
min-height
:
25
0px
;
}
.timeline-periods
{
...
...
@@ -803,9 +753,13 @@ const coreResearchers = ref([])
display
:
none
;
}
.researchers-grid
{
grid-template-columns
:
1
fr
;
gap
:
20px
;
.researchers-content
{
flex-direction
:
column
;
}
.researchers-list
{
flex
:
none
;
width
:
100%
;
}
}
...
...
@@ -816,20 +770,11 @@ const coreResearchers = ref([])
.basic-info-card
,
.funding-overview
,
.research-overview
,
.timeline-section
,
.core-researchers-section
{
padding
:
16px
;
}
.researchers-grid
{
gap
:
16px
;
}
.researchers-column
{
gap
:
16px
;
}
.researcher-item
{
gap
:
10px
;
padding
:
8px
0
;
...
...
src/views/thinkTank/ThinkTankDetail/FundingSource.vue
0 → 100644
浏览文件 @
15c01871
<
template
>
<div
class=
"funding-source-container"
>
<div
class=
"chart-header"
>
<CardTitle
title=
"经费来源"
/>
<div
class=
"header-icons"
>
<el-icon><Coin
/></el-icon>
<el-icon><Download
/></el-icon>
<el-icon><Star
/></el-icon>
</div>
</div>
<div
class=
"chart-body"
>
<div
class=
"stats-panel"
>
<div
class=
"stat-card total-card"
>
<div
class=
"label"
>
总计
</div>
<div
class=
"value"
>
4.358亿美元
</div>
</div>
<div
class=
"stat-card govt-card"
>
<div
class=
"label"
>
政府部门
</div>
<div
class=
"value"
>
3.271亿美元
</div>
</div>
<div
class=
"stat-card other-card"
>
<div
class=
"label"
>
其他机构
</div>
<div
class=
"value"
>
1.087亿美元
</div>
</div>
</div>
<div
class=
"chart-panel"
ref=
"chartRef"
></div>
</div>
</div>
</
template
>
<
script
setup
>
import
{
ref
,
onMounted
,
onUnmounted
,
nextTick
}
from
'vue'
;
import
*
as
echarts
from
'echarts'
;
import
{
Coin
,
Download
,
Star
}
from
'@element-plus/icons-vue'
;
import
CardTitle
from
'@/components/CardTitle.vue'
;
// 1. 模拟数据
// 注意:为了还原图表,这里的数据是凑出来的近似值,确保比例看起来像截图
const
chartData
=
[
// 右侧数据 (通常从12点顺时针开始)
{
value
:
7830
,
name
:
'美国国土安全部'
,
percent
:
'21%'
},
{
value
:
7290
,
name
:
'美国办公室国防部长和...'
,
percent
:
'21%'
},
{
value
:
6740
,
name
:
'美国卫生与公众服务部...'
,
percent
:
'18%'
},
{
value
:
4840
,
name
:
'美国空军'
,
percent
:
'18%'
},
{
value
:
3880
,
name
:
'美国陆军'
,
percent
:
'16%'
},
{
value
:
3520
,
name
:
'捐款'
,
percent
:
'16%'
},
// 左侧数据
{
value
:
3110
,
name
:
'基金'
,
percent
:
'14%'
},
{
value
:
2905
,
name
:
'大学'
,
percent
:
'12%'
},
{
value
:
2840
,
name
:
'私营部门'
,
percent
:
'12%'
},
{
value
:
2400
,
name
:
'州和地方政府机构'
,
percent
:
'12%'
},
{
value
:
2130
,
name
:
'其他非营利组织'
,
percent
:
'11%'
},
{
value
:
2060
,
name
:
'非美国政府机构和国际...'
,
percent
:
'8%'
},
{
value
:
1850
,
name
:
'其他联邦机构'
,
percent
:
'8%'
},
{
value
:
1200
,
name
:
'其他'
,
percent
:
'8%'
},
];
// 颜色盘 (从截图吸取的近似色)
const
colorPalette
=
[
'#8cbbf1'
,
// 浅蓝
'#a5d67d'
,
// 浅绿
'#f6c469'
,
// 橙黄
'#fdf27e'
,
// 黄色
'#94e6d6'
,
// 青绿
'#6b85ef'
,
// 深蓝紫
'#d3d7fd'
,
// 极浅蓝
'#d9f3b2'
,
// 极浅绿
'#eb7d7d'
,
// 红
'#a28ee3'
,
// 紫
'#f4a678'
,
// 橙
'#6ba7f5'
,
// 蓝
'#f5a8a8'
,
// 浅红
];
const
chartRef
=
ref
(
null
);
let
myChart
=
null
;
const
initChart
=
()
=>
{
if
(
!
chartRef
.
value
)
return
;
myChart
=
echarts
.
init
(
chartRef
.
value
);
const
option
=
{
color
:
colorPalette
,
tooltip
:
{
trigger
:
'item'
,
formatter
:
'{b}: {c}万 ({d}%)'
},
series
:
[
{
name
:
'经费来源'
,
type
:
'pie'
,
radius
:
[
'45%'
,
'60%'
],
// 环形图半径
center
:
[
'50%'
,
'50%'
],
// 居中
data
:
chartData
,
// 标签配置
label
:
{
show
:
true
,
position
:
'outside'
,
formatter
:
function
(
params
)
{
// 这里的逻辑是为了模仿截图:右边的文字名字在右侧,左边的文字名字在左侧
// 简单的判断逻辑:基于 ECharts 内部计算的 label 角度,或者根据数据索引
// 这里我们构建一个富文本结构
return
`{name|
${
params
.
name
}
}\n{val|
${
params
.
value
}
万} {pct|
${
params
.
data
.
percent
}
}`
;
},
// 关键配置:使用 edge 对齐方式让标签像表格一样排列在两侧
alignTo
:
'edge'
,
edgeDistance
:
10
,
// 距离容器边缘的距离
minMargin
:
5
,
lineHeight
:
20
,
rich
:
{
name
:
{
fontSize
:
13
,
fontWeight
:
'bold'
,
color
:
'#333'
,
padding
:
[
0
,
5
]
},
val
:
{
fontSize
:
12
,
color
:
'#666'
},
pct
:
{
fontSize
:
12
,
color
:
'#666'
,
padding
:
[
0
,
5
]
}
}
},
// 引导线配置
labelLine
:
{
length
:
15
,
length2
:
60
,
// 第二段线长一点,以便连接到边缘
maxSurfaceAngle
:
80
},
// 每一项的样式
itemStyle
:
{
borderColor
:
'#fff'
,
borderWidth
:
2
}
}
]
};
myChart
.
setOption
(
option
);
};
// 响应式处理
const
resizeHandler
=
()
=>
{
if
(
myChart
)
{
myChart
.
resize
();
}
};
onMounted
(()
=>
{
nextTick
(()
=>
{
initChart
();
window
.
addEventListener
(
'resize'
,
resizeHandler
);
});
});
onUnmounted
(()
=>
{
window
.
removeEventListener
(
'resize'
,
resizeHandler
);
if
(
myChart
)
{
myChart
.
dispose
();
}
});
</
script
>
<
style
lang=
"scss"
scoped
>
.funding-source-container
{
width
:
100%
;
background
:
#fff
;
border-radius
:
8px
;
padding
:
20px
;
box-shadow
:
0
2px
12px
0
rgba
(
0
,
0
,
0
,
0
.05
);
font-family
:
"Helvetica Neue"
,
Helvetica
,
"PingFang SC"
,
"Hiragino Sans GB"
,
"Microsoft YaHei"
,
"微软雅黑"
,
Arial
,
sans-serif
;
// 头部样式
.chart-header
{
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
margin-bottom
:
20px
;
.title-wrapper
{
display
:
flex
;
align-items
:
center
;
.blue-bar
{
width
:
4px
;
height
:
18px
;
background-color
:
#409eff
;
// Element Plus Primary Blue
margin-right
:
8px
;
border-radius
:
2px
;
}
.title-text
{
font-size
:
18px
;
font-weight
:
700
;
color
:
#303133
;
}
}
.header-icons
{
display
:
flex
;
gap
:
15px
;
color
:
#909399
;
cursor
:
pointer
;
.el-icon
{
font-size
:
18px
;
&
:hover
{
color
:
#409eff
;
}
}
}
}
// 主体布局
.chart-body
{
display
:
flex
;
flex-direction
:
row
;
height
:
450px
;
// 固定一个高度给图表展示
// 左侧统计面板
.stats-panel
{
width
:
200px
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
center
;
gap
:
20px
;
flex-shrink
:
0
;
.stat-card
{
padding
:
15px
;
border-radius
:
6px
;
display
:
flex
;
flex-direction
:
column
;
gap
:
8px
;
.label
{
font-size
:
14px
;
}
.value
{
font-size
:
20px
;
font-weight
:
800
;
}
// 不同卡片的特定样式
&
.total-card
{
background-color
:
#eef6ff
;
// 浅蓝背景
.label
{
color
:
#409eff
;
}
.value
{
color
:
#185ebd
;
}
}
&
.govt-card
{
background-color
:
#fff2f2
;
// 浅红背景
.label
{
color
:
#f56c6c
;
}
.value
{
color
:
#c43e3e
;
}
}
&
.other-card
{
background-color
:
#f0f9eb
;
// 浅绿背景
.label
{
color
:
#67c23a
;
}
.value
{
color
:
#3a8e1e
;
}
}
}
}
// 右侧图表区域
.chart-panel
{
flex
:
1
;
min-width
:
0
;
// 防止 flex 子项溢出
height
:
100%
;
}
}
}
// 移动端适配微调
@media
(
max-width
:
768px
)
{
.chart-body
{
flex-direction
:
column
!
important
;
height
:
auto
!
important
;
.stats-panel
{
width
:
100%
!
important
;
flex-direction
:
row
!
important
;
overflow-x
:
auto
;
padding-bottom
:
10px
;
}
.chart-panel
{
height
:
400px
!
important
;
}
}
}
</
style
>
\ No newline at end of file
src/views/thinkTank/ThinkTankDetail/ReportTab.vue
浏览文件 @
15c01871
...
...
@@ -72,6 +72,7 @@ import { onMounted, ref } from 'vue';
import
{
Search
}
from
'@element-plus/icons-vue'
;
import
{
getThinkTankReport
}
from
'@/api'
;
import
{
useRoute
}
from
'vue-router'
;
import
{
mockReportList
}
from
'../mockData'
;
const
route
=
useRoute
();
const
props
=
defineProps
({
...
...
@@ -102,7 +103,8 @@ const reportList = ref([
onMounted
(()
=>
{
getThinkTankReport
({
id
:
route
.
params
.
id
}).
then
(
res
=>
{
reportList
.
value
=
res
.
data
;
// reportList.value = res.data;
reportList
.
value
=
mockReportList
;
});
})
</
script
>
...
...
@@ -145,8 +147,11 @@ onMounted(() => {
.report-card
{
cursor
:
pointer
;
border-radius
:
10px
;
box-shadow
:
0
2px
12px
0
rgba
(
0
,
0
,
0
,
0.05
);
transition
:
transform
0.2s
ease-in-out
,
box-shadow
0.2s
ease-in-out
;
border
:
1px
solid
#e4e7ed
;
padding
:
10px
;
}
.report-card
:hover
{
...
...
@@ -173,9 +178,9 @@ onMounted(() => {
/* overflow: hidden; */
text-overflow
:
ellipsis
;
display
:
-webkit-box
;
-webkit-line-clamp
:
2
;
-webkit-line-clamp
:
1
;
overflow
:
hidden
;
-webkit-box-orient
:
vertical
;
min-height
:
42px
;
}
.card-meta
{
...
...
src/views/thinkTank/ThinkTankDetail/index.vue
浏览文件 @
15c01871
...
...
@@ -50,7 +50,7 @@ import PolicyTab from '@/components/PolicyTab.vue';
import
DescTab
from
'./DescTab.vue'
;
import
{
getThinkTankSummary
}
from
'@/api'
;
import
{
useRoute
}
from
'vue-router'
;
import
{
mockThinkTankList
}
from
'../mockData'
;
// --- Component State ---
const
activeTab
=
ref
(
'reports'
);
const
route
=
useRoute
();
...
...
@@ -77,13 +77,16 @@ const currentComponent = computed(() => {
onMounted
(()
=>
{
getThinkTankSummary
({
id
:
route
.
params
.
id
}).
then
(
res
=>
{
console
.
log
(
res
.
data
);
summary
.
value
=
res
.
data
||
{};
// summary.value = res.data || {};
summary
.
value
=
mockThinkTankList
[
0
];
});
});
</
script
>
<
style
scoped
>
/* 变量 1200px - 定义在组件根元素上 */
.page-container
{
--max-width
:
1650px
;
background-color
:
#f5f7fa
;
font-family
:
'Helvetica Neue'
,
Helvetica
,
'PingFang SC'
,
'Hiragino Sans GB'
,
'Microsoft YaHei'
,
Arial
,
sans-serif
;
min-height
:
100vh
;
...
...
@@ -99,7 +102,7 @@ onMounted(() => {
}
.header-container
{
max-width
:
1200px
;
max-width
:
var
(
--max-width
)
;
margin
:
0
auto
;
padding
:
24px
24px
0
;
display
:
flex
;
...
...
@@ -116,7 +119,7 @@ onMounted(() => {
}
.tabs-container
{
max-width
:
1200px
;
max-width
:
var
(
--max-width
)
;
margin
:
0
auto
;
padding
:
0
24px
;
}
...
...
@@ -212,7 +215,7 @@ onMounted(() => {
}
.content-container
{
max-width
:
1200px
;
max-width
:
var
(
--max-width
)
;
width
:
100%
;
background-color
:
#fff
;
padding
:
24px
;
...
...
src/views/thinkTank/mockData.js
浏览文件 @
15c01871
...
...
@@ -162,4 +162,279 @@ export const mockReportList = [
"thinkTankName"
:
"兰德科技智库"
,
imageUrl
:
report12
}
]
\ No newline at end of file
]
export
const
mockPolicyList
=
[
{
"content"
:
"创建并定制针对人工智能技术的验证、确认与评估技术。"
,
"status"
:
"法案 2024 《芯片科学法案》; 政令 2025 《推动美国人工智能技术栈出口》"
,
"reportId"
:
null
,
"name"
:
"保持美国在人工智能与机器学习领域的优势"
,
"times"
:
"2025-06-26"
,
tags
:
[
'人工智能'
,
'机器学习'
]
},
{
"content"
:
"为运用人工智能的新作战概念建立开发、测试与评估流程。"
,
"status"
:
"法案 2024 《芯片科学法案》; 政令 2025 《关于优化美军作战决策结构的建议》"
,
"reportId"
:
null
,
"name"
:
"保持美国在人工智能与机器学习领域的优势"
,
"times"
:
"2025-06-26"
,
tags
:
[
'人工智能'
,
'机器学习'
]
},
{
"content"
:
"通过制定和维护一个前瞻性的人工智能发展路线图来管理预期,该路线图应阐明国防部在近期(一至两年)、中期(三至五年)和远期(六至十年)部署人工智能的现实目标"
,
"status"
:
"法案 2024 《芯片科学法案》; 政令 2025 《关于优化美军作战决策结构的建议》"
,
"reportId"
:
null
,
"name"
:
"保持美国在人工智能与机器学习领域的优势"
,
"times"
:
"2025-06-26"
,
tags
:
[
'人工智能'
,
'机器学习'
]
},
{
"content"
:
"考虑采取更全面的方法来打击全球供应链中强迫劳动使用的选项。"
,
"status"
:
"法案 2024 《维吾尔强迫劳动预防法》"
,
"reportId"
:
null
,
"name"
:
"美国贸易执法是否发挥了作用,能否做得更多?"
,
"times"
:
"2025-03-15"
,
tags
:
[
'人工智能'
,
'机器学习'
]
},
{
"content"
:
"与利益相关者共同收集证据,为关于贸易执法的公共讨论提供信息。"
,
"status"
:
"法案 2024 《维吾尔强迫劳动预防法》"
,
"reportId"
:
null
,
"name"
:
"美国贸易执法是否发挥了作用,能否做得更多?"
,
"times"
:
"2025-03-15"
},
{
"content"
:
"推动清洁能源生产供内用,化石燃料重新配置出口。"
,
"status"
:
"法案 2024 《重塑美国人口结构法案》; 法案 2025 《开放人才法案》; 政令 2025 《推动美国人工智能技术栈出口》"
,
"reportId"
:
null
,
"name"
:
"美国贸易执法是否发挥了作用,能否做得更多?"
,
"times"
:
"2025-06-26"
},
{
"content"
:
"允许OPT的国际学生出国旅行并持多次入境签证重新进入美国。"
,
"status"
:
"法案 2024 《重塑美国人口结构法案》; 法案 2025 《开放人才法案》"
,
"reportId"
:
null
,
"name"
:
"中美经济竞争:复杂经济和地缘政治关系中的收益与风险"
,
"times"
:
"2025-06-26"
}
]
// 兰德公司详情模拟数据
export
const
mockRandCorporationDetail
=
{
id
:
1
,
name
:
"兰德科技智库"
,
ename
:
"RAND Corporation"
,
describe
:
"兰德公司(RAND Corporation)成立于1948年,是全球最负盛名的政策研究智库之一。作为一家非营利性研究机构,兰德公司致力于通过客观分析和有效解决方案来改善政策和决策。公司总部位于美国加利福尼亚州圣莫尼卡,在华盛顿特区、匹兹堡、波士顿、新奥尔良等地设有办事处。兰德公司拥有超过1900名员工,包括来自50多个国家的学者、分析师和研究人员。"
,
country
:
"美国"
,
url
:
"https://www.rand.org"
,
logo
:
rand
,
tags
:
[
"国家安全"
,
"科技政策"
,
"医疗卫生"
,
"能源政策"
,
"公共安全"
,
"国防研究"
,
"国际关系"
,
"经济政策"
],
// 扩展信息
founded
:
"1948年"
,
headquarters
:
"美国加利福尼亚州圣莫尼卡"
,
employees
:
"1900+"
,
researchAreas
:
[
"国家安全与国防"
,
"科技与创新政策"
,
"医疗卫生政策"
,
"能源与环境"
,
"教育与劳动力"
,
"国际关系与外交"
,
"经济与金融"
,
"公共安全与司法"
],
notableAchievements
:
[
"为美国国防部提供战略分析和政策建议"
,
"在人工智能、网络安全等前沿科技领域开展深入研究"
,
"发布多份关于中美科技竞争的重要报告"
,
"在医疗卫生政策研究方面具有国际影响力"
]
}
// DescTab 组件所需的兰德公司详细数据
// 基本信息
export
const
mockRandBasicInfo
=
{
country
:
"美国"
,
foundingDate
:
"1948年"
,
position
:
"美国加利福尼亚州圣莫尼卡"
,
nature
:
"非营利性研究与分析机构"
,
memnum
:
"约1,700名员工"
,
budget
:
"约3.5亿美元"
}
// 分支机构信息(按地区分组)
export
const
mockRandBranchInfo
=
{
"北美"
:
[
"圣莫尼卡(总部)"
,
"华盛顿特区"
,
"匹兹堡"
,
"波士顿"
],
"欧洲"
:
[
"英国剑桥"
,
"比利时布鲁塞尔"
],
"中东"
:
[
"卡塔尔多哈"
],
"澳大利亚"
:
[
"堪培拉"
]
}
// 经费来源数据(用于饼图,单位:万美元)
// 总计:43580万美元 = 4.358亿美元
// 政府部门:32710万美元 = 3.271亿美元
// 其他机构:10870万美元 = 1.087亿美元
// 按来源类型分类(左侧表格)
export
const
mockRandFundsByType
=
[
{
name
:
"基金"
,
amount
:
3110
,
percent
:
14
},
{
name
:
"大学"
,
amount
:
2905
,
percent
:
12
},
{
name
:
"私营部门"
,
amount
:
2840
,
percent
:
12
},
{
name
:
"州和地方政府机构"
,
amount
:
2400
,
percent
:
12
},
{
name
:
"其他非营利组织"
,
amount
:
2130
,
percent
:
11
},
{
name
:
"非美国政府机构和国际..."
,
amount
:
2060
,
percent
:
8
},
{
name
:
"其他联邦机构"
,
amount
:
1850
,
percent
:
8
},
{
name
:
"其他"
,
amount
:
1200
,
percent
:
8
}
]
// 按具体政府实体分类(右侧表格)
export
const
mockRandFundsByEntity
=
[
{
name
:
"美国国土安全部"
,
amount
:
7830
,
percent
:
21
},
{
name
:
"美国办公室国防部长和..."
,
amount
:
7290
,
percent
:
21
},
{
name
:
"美国卫生与公众服务部..."
,
amount
:
6740
,
percent
:
18
},
{
name
:
"美国空军"
,
amount
:
4840
,
percent
:
18
},
{
name
:
"美国陆军"
,
amount
:
3880
,
percent
:
16
},
{
name
:
"捐款"
,
amount
:
3520
,
percent
:
16
}
]
// 用于饼图的完整数据
export
const
mockRandFundsSource
=
[
{
amount
:
7830
,
name
:
"美国国土安全部"
,
institution
:
"美国国土安全部"
},
{
amount
:
7290
,
name
:
"美国办公室国防部长"
,
institution
:
"美国办公室国防部长"
},
{
amount
:
6740
,
name
:
"美国卫生与公众服务部"
,
institution
:
"美国卫生与公众服务部"
},
{
amount
:
4840
,
name
:
"美国空军"
,
institution
:
"美国空军"
},
{
amount
:
3880
,
name
:
"美国陆军"
,
institution
:
"美国陆军"
},
{
amount
:
3520
,
name
:
"捐款"
,
institution
:
"捐款"
},
{
amount
:
3110
,
name
:
"基金"
,
institution
:
"基金"
},
{
amount
:
2905
,
name
:
"大学"
,
institution
:
"大学"
},
{
amount
:
2840
,
name
:
"私营部门"
,
institution
:
"私营部门"
},
{
amount
:
2400
,
name
:
"州和地方政府机构"
,
institution
:
"州和地方政府机构"
},
{
amount
:
2130
,
name
:
"其他非营利组织"
,
institution
:
"其他非营利组织"
},
{
amount
:
2060
,
name
:
"非美国政府机构和国际组织"
,
institution
:
"非美国政府机构和国际组织"
},
{
amount
:
1850
,
name
:
"其他联邦机构"
,
institution
:
"其他联邦机构"
},
{
amount
:
1200
,
name
:
"其他"
,
institution
:
"其他"
}
]
// 经费总计(单位:美元)
export
const
mockRandFundTotal
=
{
totalJe
:
435800000
,
// 4.358亿美元
zfJe
:
327100000
,
// 3.271亿美元
otherJe
:
108700000
// 1.087亿美元
}
// 研究领域数据
export
const
mockRandResearchAreas
=
[
{
id
:
1
,
time
:
"1940s-1950s"
,
describe
:
"专注于军事战略和国家安全研究,包括核战略、航空航天技术和系统分析"
},
{
id
:
2
,
time
:
"1960s-1970s"
,
describe
:
"扩展至社会科学领域,包括教育政策、医疗卫生、城市问题和刑事司法"
},
{
id
:
3
,
time
:
"1980s-1990s"
,
describe
:
"增加国际政策研究,关注苏联解体后的地缘政治变化和技术政策"
},
{
id
:
4
,
time
:
"2000s-2010s"
,
describe
:
"重点关注反恐战略、网络安全、能源政策和气候变化"
},
{
id
:
5
,
time
:
"2020s-现在"
,
describe
:
"聚焦人工智能、大数据分析、全球公共卫生和新兴技术政策"
}
]
// 核心研究人员(包含之前的职位信息)
export
const
mockRandCoreResearchers
=
[
{
id
:
1
,
name
:
"杰森·马西尼"
,
nameEn
:
"Jason Massini"
,
previousRoles
:
[
"哈佛大学经济系"
,
"美国财政部"
],
currentPosition
:
"总裁兼首席执行官"
,
avatar
:
null
},
{
id
:
2
,
name
:
"安德鲁·R·霍恩"
,
nameEn
:
"Andrew R. Horne"
,
previousRoles
:
[
"白宫科技政策办公室"
],
currentPosition
:
"高级副总裁,研究与分析"
,
avatar
:
null
},
{
id
:
3
,
name
:
"梅丽莎·罗"
,
nameEn
:
"Melissa Luo"
,
previousRoles
:
[
"美国国防部"
],
currentPosition
:
"副总裁,全球研究人才"
,
avatar
:
null
},
{
id
:
4
,
name
:
"安妮塔·钱德拉"
,
nameEn
:
"Anita Chandra"
,
previousRoles
:
[
"哈佛大学经济系"
,
"美国商务部"
],
currentPosition
:
"副总裁兼主任,兰德社会与经济福祉"
,
avatar
:
null
},
{
id
:
5
,
name
:
"Timothy Marler"
,
nameEn
:
"Timothy Marler"
,
previousRoles
:
[
"斯坦福大学"
],
currentPosition
:
"高级研究员,人工智能与机器学习"
,
avatar
:
null
}
]
// 研究人员背景分类(用于树状图)
export
const
mockRandResearcherCategories
=
{
"政府部门及国家实验室"
:
{
"商务部"
:
12
,
"财政部"
:
8
,
"能源部"
:
15
,
"国家能源技术实验室"
:
6
,
"其他"
:
10
},
"领先科技企业"
:
{
"谷歌"
:
18
,
"微软"
:
14
,
"英伟达"
:
9
,
"英特尔"
:
11
,
"亚马逊"
:
13
,
"其他"
:
7
},
"顶尖大学与研究机构"
:
{
"哈佛大学"
:
22
,
"加州大学"
:
19
,
"斯坦福大学"
:
16
,
"麻省理工学院"
:
14
,
"其他"
:
12
},
"国际人才"
:
{
"印度"
:
15
,
"日本"
:
12
,
"德国"
:
10
,
"中国"
:
8
,
"其他"
:
6
}
}
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论