Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
R
risk-monitor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蔡建
risk-monitor
Commits
a4b931c9
提交
a4b931c9
authored
3月 06, 2026
作者:
张烨
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' into zy-dev
上级
aa92a509
f09bfd39
隐藏空白字符变更
内嵌
并排
正在显示
16 个修改的文件
包含
2056 行增加
和
852 行删除
+2056
-852
g2.mdc
.cursor/rules/g2.mdc
+53
-0
billHome.js
src/api/bill/billHome.js
+25
-15
newsItem.vue
src/components/base/newsList/newsItem.vue
+147
-0
personAvatar.vue
src/components/base/people/personAvatar.vue
+54
-0
constStyle.vue
src/components/devStyle/components/constStyle.vue
+36
-0
index.vue
src/components/devStyle/components/index.vue
+22
-0
textStyle.vue
src/components/devStyle/components/textStyle.vue
+90
-0
company.js
src/router/modules/company.js
+3
-1
devStyle.js
src/router/modules/devStyle.js
+19
-0
common.scss
src/styles/common.scss
+132
-3
descriptions.scss
src/styles/descriptions.scss
+5
-2
systemUtils.ts
src/utils/systemUtils.ts
+40
-0
OverviewCard.vue
src/views/bill/billHome/OverviewCard.vue
+88
-0
ResourceLibrarySection.vue
src/views/bill/billHome/ResourceLibrarySection.vue
+1068
-0
index.vue
src/views/bill/billHome/index.vue
+268
-830
vite.config.js
vite.config.js
+6
-1
没有找到文件。
.cursor/rules/g2.mdc
0 → 100644
浏览文件 @
a4b931c9
---
alwaysApply: true
---
# Overview
Insert overview text here. The agent will only see this should they choose to apply the rule.
```markdown
---
alwaysApply: true
---
# 前端开发(Cursor 专用执行要点)
## 1. HTML / 模板
- 属性命名:统一用小写-中线分割。动态 class 也用这种格式,使用单引号:`:class="{ 'xxx-xxx': isXxx }"`
- v-for 必须有唯一 key,`v-for + :key`(如`:key="item.id"`),禁止仅凭索引。示例:`<li v-for="item in list" :key="item.id"></li>`
- 禁止 v-if 与 v-for 同时在同一节点;如需筛选请用计算属性/方法过滤后再 v-for
- 无内容组件或标签必须自闭合,如 `<MyComp />` `<img />` `<input />`
- HTML 属性用双引号,动态属性外已双引号则用单引号
- 模板表达式保持极简,只写取值或很简单的显示;任何有数据处理(如数组/字符串操作、三元、函数执行等)必须抽到方法或计算属性完成
## 2. CSS
- 样式模块优先通用组件,确需定制严格按设计来写
- 全部样式变量统一来源于全局(如 `:root { --color-main-primary: #055fC2; ... }`)
- `<style scoped>` 默认加 scoped
- 修改子组件样式用 `:deep()`(Vue3 推荐写法),如:`.xxx :deep(.el-xxx) { ... }`
- 严禁页面大量内联 style,样式尽量写到 class 或 :style 绑定表达式
## 3. 文件系统
- 文件夹采用小驼峰,无数字/无关字符
- 每个业务模块 API 独立放模块对应文件夹
- 静态资源分全局 assets 与模块 assets:全局图片 assets/images,icon 建议 SVG,模块区分子文件夹
## 4. 组件
- 组件名大驼峰(PascalCase)。组件类型目录小驼峰,具体组件目录(如 AreaTag)大驼峰
- 单文件组件名 index.vue,多组件文件按具体功能如 LeftBtn.vue
- 优先用通用组件,业务组件只能放业务模块,不得放全局
## 5. JS/TS
- 命名统一规范
- 变量:小驼峰 userName、isVisible
- 常量:大写+下划线,如 MAX_COUNT
- 枚举:枚举名大驼峰,枚举值全大写+下划线 enum Status { SUCCESS = 'SUCCESS' }
- 普通函数:小驼峰+动词前缀 getUser/formatTime
- 事件函数:小驼峰+handle/on handleSubmit/onClose
- 布尔型函数:is/has/should + 大驼峰,如 isValid()
- 异步强制 async/await,catch 错误。禁止 Promise.then 链式嵌套(如遇回调 hell 必须拆分/抽象重写)
- 一律用 const/let 替换 var,优先 const
- 注释:
- 单行注释:后加空格,如 `// 注释内容`
- 方法/复杂模块加 /** JSDoc 注释 */
## 6. 其它
- 所有复杂渲染逻辑逻辑一律抽到计算属性或方法,模板结构保持简洁
src/api/bill/billHome.js
浏览文件 @
a4b931c9
...
...
@@ -14,20 +14,20 @@ export function getBillIndustry(params) {
// 涉华法案统计
export
function
getBillCount
(
params
)
{
return
request
({
method
:
'GET'
,
url
:
`/api/BillOverview/billCount`
,
params
})
return
request
({
method
:
'GET'
,
url
:
`/api/BillOverview/billCount`
,
params
})
}
// 获取关键条款
export
function
getBillOverviewKeyTK
()
{
return
request
({
method
:
'GET'
,
url
:
`/api/BillOverview/keyTk`
,
return
request
({
method
:
'GET'
,
url
:
`/api/BillOverview/keyTk`
,
})
})
}
// 获取热门法案列表
...
...
@@ -104,22 +104,32 @@ export function getBillPostOrg(params) {
})
}
// 获取
关键议员提案
// 获取
涉华法案进展分布
/**
* @param {year}
* @param {year}
*/
export
function
get
MemberProposal
(
params
)
{
export
function
get
BillProcess
(
params
)
{
return
request
({
method
:
'GET'
,
url
:
`/
api/BillOverview/memberProposal
/
${
params
.
year
}
`
,
url
:
`/
bill/BillOverview/billsProcess
/
${
params
.
year
}
`
,
})
}
// 获取资源库
// 获取资源库法案
export
function
getBills
(
params
,
signal
)
{
return
request
({
method
:
'GET'
,
url
:
`/api/BillOverview/bills`
,
url
:
`/bill/BillOverview/bills`
,
params
,
signal
})
}
// 获取资源库国会议员
export
function
getBillsPerson
(
params
,
signal
)
{
return
request
({
method
:
'GET'
,
url
:
`/bill/BillOverview/billsPerson`
,
params
,
signal
})
...
...
src/components/base/newsList/newsItem.vue
0 → 100644
浏览文件 @
a4b931c9
<
template
>
<div
class=
"box3-item"
@
click=
"handleToNewsAnalysis(news)"
>
<div
class=
"left"
>
<img
:src=
"news[props.img] ? news[props.img] : DefaultIconNews"
alt=
""
/>
</div>
<div
class=
"right"
>
<div
class=
"right-top"
>
<div
class=
"title"
><span
class=
"text-inner"
>
{{
news
[
props
.
title
]
}}
</span></div>
<div
class=
"time"
>
{{
news
[
props
.
from
]
}}
</div>
</div>
<div
class=
"right-footer"
>
{{
news
[
props
.
content
]
}}
</div>
</div>
</div>
</
template
>
<
script
setup
>
import
DefaultIconNews
from
"@/assets/icons/default-icon-news.png"
;
const
props
=
defineProps
({
// 新闻列表数据
news
:
{
type
:
Object
,
default
:
()
=>
{
}
},
img
:
{
type
:
String
,
default
:
'img'
},
title
:
{
type
:
String
,
default
:
"title"
},
from
:
{
type
:
String
,
default
:
"from"
},
content
:
{
type
:
String
,
default
:
"content"
},
});
const
emit
=
defineEmits
([
'item-click'
,
'more-click'
]);
const
handleToNewsAnalysis
=
(
item
,
index
)
=>
{
emit
(
'item-click'
,
item
,
index
)
};
</
script
>
<
style
lang=
"scss"
scoped
>
.box3-item
{
display
:
flex
;
align-items
:
center
;
height
:
78px
;
margin
:
0px
21px
;
cursor
:
pointer
;
&
:hover
{
.right-top
.title
{
color
:
rgb
(
5
,
95
,
194
)
!
important
;
font-weight
:
700
;
}
.right-top
.text-inner
{
border-bottom-color
:
rgb
(
5
,
95
,
194
)
!
important
;
}
}
}
.left
{
width
:
97px
;
// flex-shrink: 0;
height
:
72px
;
img
{
width
:
100%
;
height
:
100%
;
border-radius
:
4px
;
}
}
.right
{
flex
:
1
;
min-width
:
0
;
margin-left
:
20px
;
.right-top
{
display
:
flex
;
justify-content
:
space-between
;
.title
{
// width: 500px;
height
:
24px
;
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
'Source Han Sans CN'
;
font-size
:
16px
;
font-weight
:
700
;
line-height
:
24px
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
.text-inner
{
border-bottom
:
1px
solid
transparent
;
}
}
.time
{
text-align
:
right
;
height
:
22px
;
color
:
rgba
(
95
,
101
,
108
,
1
);
font-family
:
'Source Han Sans CN'
;
font-size
:
14px
;
font-weight
:
400
;
line-height
:
22px
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
}
.right-footer
{
height
:
48px
;
/* 调整为2行的高度:24px × 2 = 48px */
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
'Source Han Sans CN'
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
24px
;
overflow
:
hidden
;
display
:
-
webkit-box
;
/* 关键 */
-webkit-line-clamp
:
2
;
/* 显示2行 */
-webkit-box-orient
:
vertical
;
/* 垂直方向排列 */
text-overflow
:
ellipsis
;
/* 第二行省略号 */
white-space
:
normal
;
/* 改为 normal */
word-break
:
break-word
;
/* 允许单词换行 */
}
}
</
style
>
\ No newline at end of file
src/components/base/people/personAvatar.vue
0 → 100644
浏览文件 @
a4b931c9
<
template
>
<el-space
@
click=
"onClick(person)"
>
<ElAvatar
:size=
"48"
:src=
"person[img]"
alignment=
"center"
/>
<el-space
:size=
"0"
direction=
"vertical"
alignment=
"flex-start"
>
<div
class=
"text-header"
>
{{
person
[
name
]
}}
</div>
<div
class=
"person-position"
>
{{
person
[
position
]
}}
</div>
</el-space>
</el-space>
</
template
>
<
script
setup
>
import
'@/styles/common.scss'
import
{
ElSpace
}
from
'element-plus'
;
const
props
=
defineProps
({
// 新闻列表数据
person
:
{
type
:
Object
,
default
:
()
=>
{
}
},
img
:
{
type
:
String
,
default
:
'avatarUrl'
},
name
:
{
type
:
String
,
default
:
"name"
},
position
:
{
type
:
String
,
default
:
"position"
},
introduction
:
{
type
:
String
,
default
:
"introduction"
},
});
const
emit
=
defineEmits
([
'item-click'
,
'more-click'
]);
const
onClick
=
(
item
)
=>
{
emit
(
'item-click'
,
item
)
console
.
log
(
item
)
};
</
script
>
<
style
lang=
"scss"
scoped
>
.person-position
{
font-size
:
16px
;
line-height
:
24px
;
color
:
var
(
--
text-primary-65-color
);
}
</
style
>
\ No newline at end of file
src/components/devStyle/components/constStyle.vue
0 → 100644
浏览文件 @
a4b931c9
<
script
setup
>
import
{
ElSpace
,
ElButton
}
from
'element-plus'
;
import
"@/styles/main.css"
import
{
copyToClipboardThenTip
}
from
'@/utils/systemUtils'
const
colors
=
[
{
title
:
"黑色90% / 主标题文字颜色"
,
name
:
"--text-primary-90-color"
},
{
title
:
"黑色80% / 小标题文字颜色"
,
name
:
"--text-primary-80-color"
},
{
title
:
"黑色65% / 正文颜色"
,
name
:
"--text-primary-65-color"
},
{
title
:
"黑色50%"
,
name
:
"--text-primary-50-color"
},
{
title
:
"黑色10%"
,
name
:
"--bg-black-10"
},
{
title
:
"黑色5% / 分割线颜色"
,
name
:
"--bg-black-5"
},
{
title
:
"黑色2% / 灰色背景色"
,
name
:
"--bg-black-2"
},
{
title
:
"白色主色"
,
name
:
"--bg-white-100"
},
{
title
:
"主色"
,
name
:
"--color-primary-100"
},
]
function
copyColorVar
(
item
)
{
const
color
=
`var(
${
item
.
name
}
)`
copyToClipboardThenTip
(
color
)
}
</
script
>
<
template
>
<el-space
direction=
"vertical"
alignment=
"flex-start"
>
<div
class=
"text-title-2"
>
颜色
</div>
<el-space>
<el-button
v-for=
"(item, index) in colors"
:key=
"index"
:color=
"`var($
{item.name})`"
v-on:click="copyColorVar(item)">
{{
item
.
title
}}
</el-button>
</el-space>
</el-space>
</
template
>
<
style
scoped
></
style
>
\ No newline at end of file
src/components/devStyle/components/index.vue
0 → 100644
浏览文件 @
a4b931c9
<
script
setup
lang=
"ts"
>
import
"@/styles/container.scss"
import
TextStyle
from
'./textStyle.vue'
;
import
ConstStyle
from
'./constStyle.vue'
;
import
{
ElScrollbar
,
ElSpace
}
from
"element-plus"
;
</
script
>
<
template
>
<el-scrollbar>
<div
class=
"common-page"
>
<el-space
direction=
"vertical"
alignment=
"flex-start"
>
<div
class=
"text-title-0-show"
>
开发样式
</div>
<div
class=
"text-title-1-show"
>
样式变量
</div>
<const-style></const-style>
<div
class=
"text-title-1-show"
>
文字样式
</div>
<text-style></text-style>
</el-space>
</div>
</el-scrollbar>
</
template
>
\ No newline at end of file
src/components/devStyle/components/textStyle.vue
0 → 100644
浏览文件 @
a4b931c9
<
template
>
<table
style=
"width: 100%; border-collapse: collapse; border: 1px solid #ebeef5;"
>
<!-- 表头 -->
<thead>
<tr
class=
"text-title-2"
>
<th>
名称
</th>
<th>
类型名称
</th>
<th>
操作
</th>
</tr>
</thead>
<!-- 表格内容 -->
<tbody>
<template
v-for=
"(row, index) in tableData"
:key=
"index"
>
<!-- 隔行变色效果 -->
<tr
:style=
"
{
height: '60px',
backgroundColor: index % 2 === 1 ? '#fafafa' : 'transparent'
}">
<!-- 名称列 -->
<td
style=
"padding: 12px; border: 1px solid #ebeef5;"
>
<div
:class=
"row.className"
>
{{
row
.
name
}}
</div>
</td>
<!-- 类型名称列(带复制功能) -->
<td
style=
"padding: 12px; border: 1px solid #ebeef5;"
>
<div
@
click=
"copyToClipboardThenTip(row.className)"
style=
"cursor: pointer;"
>
<span>
{{
row
.
className
}}
</span>
</div>
</td>
<!-- 操作列 -->
<td
style=
"padding: 12px; border: 1px solid #ebeef5; text-align: center;"
>
<el-button
type=
"primary"
link
@
click=
"copyToClipboardThenTip(row.className)"
>
<el-icon>
<DocumentCopy
/>
</el-icon>
复制
</el-button>
</td>
</tr>
</
template
>
</tbody>
</table>
</template>
<
script
setup
>
import
{
ref
}
from
'vue'
import
{
DocumentCopy
}
from
'@element-plus/icons-vue'
import
"@/styles/common.scss"
import
{
copyToClipboardThenTip
}
from
'@/utils/systemUtils'
// 表格数据
const
tableData
=
ref
([
// { name: '0级标题', className: 'text-title-0' },
{
name
:
'0级标题-加粗'
,
className
:
'text-title-0-bold'
},
{
name
:
'0级标题-综艺'
,
className
:
'text-title-0-show'
},
// { name: '1级标题', className: 'text-title-1' },
{
name
:
'1级标题-加粗'
,
className
:
'text-title-1-bold'
},
{
name
:
'1级标题-综艺'
,
className
:
'text-title-1-show'
},
{
name
:
'2级标题'
,
className
:
'text-title-2'
},
{
name
:
'2级标题-加粗'
,
className
:
'text-title-2-bold'
},
{
name
:
'2级标题-综艺'
,
className
:
'text-title-2-show'
},
{
name
:
'3级标题'
,
className
:
'text-title-3'
},
{
name
:
'3级标题-加粗'
,
className
:
'text-title-3-bold'
},
{
name
:
'3级标题-综艺'
,
className
:
'text-title-3-show'
},
{
name
:
'正文'
,
className
:
'text-regular'
},
{
name
:
'正文-加粗'
,
className
:
'text-bold'
},
{
name
:
'正文-紧凑'
,
className
:
'text-compact'
},
{
name
:
'正文-紧凑-加粗'
,
className
:
'text-compact-bold'
},
{
name
:
'1级提示文字'
,
className
:
'text-tip-1'
},
{
name
:
'1级提示文字-加粗'
,
className
:
'text-tip-1-bold'
},
{
name
:
'2级提示文字'
,
className
:
'text-tip-2'
},
{
name
:
'2级提示文字-加粗'
,
className
:
'text-tip-2-bold'
},
{
name
:
'3级提示文字'
,
className
:
'text-tip-3'
},
])
</
script
>
<
style
scoped
></
style
>
\ No newline at end of file
src/router/modules/company.js
浏览文件 @
a4b931c9
//企业主页
const
companyPages
=
()
=>
import
(
'@/views/companyPages/index.vue'
)
const
companyPagesRoutes
=
[
// 智库系统的主要路由
{
...
...
@@ -9,7 +11,7 @@ const companyPagesRoutes = [
component
:
companyPages
,
meta
:
{
title
:
"企业主页"
,
dynamicTitle
:
true
dynamicTitle
:
true
}
},
...
...
src/router/modules/devStyle.js
0 → 100644
浏览文件 @
a4b931c9
//样式主页
const
StylePages
=
()
=>
import
(
"@/components/devStyle/components/index.vue"
);
const
stylePagesRoutes
=
[
// 智库系统的主要路由
{
path
:
"/devStylePages"
,
name
:
"devStylePages"
,
component
:
StylePages
,
meta
:
{
title
:
"开发样式"
,
dynamicTitle
:
true
}
},
]
export
default
stylePagesRoutes
\ No newline at end of file
src/styles/common.scss
浏览文件 @
a4b931c9
...
...
@@ -10,12 +10,141 @@
.flex-display
{
display
:
flex
;
}
/***文本样式***/
.text-base
{
color
:
var
(
--
color-primary-90
);
}
//0级标题
.text-title-0
{
@extend
.text-base
;
color
:
var
(
--
color-primary-90
);
font-size
:
32px
;
}
.text-title-0-bold
{
@extend
.text-title-0
;
font-weight
:
Bold
;
}
.text-title-0-show
{
@extend
.text-title-0
;
font-size
:
48px
;
font-family
:
"YouSheBiaoTiHei"
;
}
//1级标题
.text-title-1
{
@extend
.text-base
;
color
:
var
(
--
color-primary-90
);
font-size
:
24px
;
}
.text-title-1-bold
{
@extend
.text-title-1
;
font-weight
:
Bold
;
}
.text-title-1-show
{
@extend
.text-title-1
;
font-size
:
30px
;
font-family
:
"YouSheBiaoTiHei"
;
}
//2级标题
.text-title-2
{
@extend
.text-base
;
color
:
var
(
--
color-primary-90
);
font-size
:
20px
;
line-height
:
26px
;
}
.text-title-2-bold
{
@extend
.text-title-2
;
font-weight
:
Bold
;
}
.text-title-2-show
{
@extend
.text-title-2
;
font-size
:
24px
;
font-family
:
"YouSheBiaoTiHei"
;
line-height
:
normal
!
important
;
// 取消继承的行高
}
//3级标题
.text-title-3
{
@extend
.text-base
;
color
:
var
(
--
color-primary-90
);
font-size
:
18px
;
line-height
:
24px
;
}
.text-title-3-bold
{
@extend
.text-title-3
;
font-weight
:
Bold
;
}
.text-title-3-show
{
@extend
.text-title-3
;
font-size
:
20px
;
font-family
:
"YouSheBiaoTiHei"
;
line-height
:
normal
!
important
;
// 取消继承的行高
}
//正文
.text-regular
{
@extend
.text-base
;
font-size
:
16px
;
line-height
:
24px
;
color
:
var
(
--
text-primary-80-color
);
line-height
:
30px
;
}
.text-header
{
//正文-加粗
.text-bold
{
@extend
.text-base
;
font-weight
:
Bold
;
}
//正文-紧凑
.text-compact
{
@extend
.text-base
;
font-size
:
16px
;
line-height
:
24px
;
}
.text-compact-bold
{
@extend
.text-base
;
font-size
:
16px
;
line-height
:
24px
;
font-weight
:
Bold
;
}
//1级提示文字
.text-tip-1
{
@extend
.text-base
;
color
:
var
(
--
color-primary-90
);
font-size
:
16px
;
line-height
:
24px
;
}
.text-tip-1-bold
{
@extend
.text-tip-1
;
font-weight
:
Bold
;
}
//2级提示文字
.text-tip-2
{
@extend
.text-base
;
color
:
var
(
--
color-primary-90
);
font-size
:
14px
;
line-height
:
22px
;
}
.text-tip-2-bold
{
@extend
.text-tip-2
;
font-weight
:
Bold
;
}
//3级提示文字
.text-tip-3
{
@extend
.text-base
;
color
:
var
(
--
color-primary-90
);
font-size
:
12px
;
}
src/styles/descriptions.scss
浏览文件 @
a4b931c9
...
...
@@ -2,8 +2,10 @@
/***没有nav下划线***/
.common-descriptions
.el-descriptions__label
{
@extend
.text-
header
;
@extend
.text-
tip-1-bold
;
}
.common-descriptions
.el-descriptions__content
{
@extend
.text-base
@extend
.text-tip-1
;
color
:
var
(
--
text-primary-80-color
);
}
\ No newline at end of file
src/utils/systemUtils.ts
0 → 100644
浏览文件 @
a4b931c9
import
{
ElMessage
}
from
"element-plus"
;
interface
BaseReturn
{
status
:
boolean
;
message
:
string
;
}
export
async
function
copyToClipboard
(
txet
:
string
):
Promise
<
BaseReturn
>
{
try
{
// 使用现代 Clipboard API
await
navigator
.
clipboard
.
writeText
(
txet
);
console
.
log
(
"已复制:"
,
txet
);
return
{
status
:
true
,
message
:
"已复制:"
+
txet
};
}
catch
(
err
)
{
console
.
error
(
"复制失败:"
,
err
);
// 降级方案:使用document.execCommand
const
textArea
=
document
.
createElement
(
"textarea"
);
textArea
.
value
=
txet
;
document
.
body
.
appendChild
(
textArea
);
textArea
.
select
();
try
{
const
successful
=
document
.
execCommand
(
"copy"
);
if
(
successful
)
{
return
{
status
:
true
,
message
:
"已复制:"
+
txet
};
}
}
catch
(
err
)
{}
document
.
body
.
removeChild
(
textArea
);
return
{
status
:
false
,
message
:
"复制失败,请手动复制"
};
}
}
// 复制类型名称到剪贴板
export
async
function
copyToClipboardThenTip
(
text
:
string
):
Promise
<
void
>
{
const
{
status
,
message
}
=
await
copyToClipboard
(
text
);
if
(
status
)
{
ElMessage
.
success
(
message
);
}
else
{
ElMessage
.
error
(
message
);
}
}
src/views/bill/billHome/OverviewCard.vue
0 → 100644
浏览文件 @
a4b931c9
<
template
>
<div
class=
"overview-card"
>
<div
class=
"overview-card-header"
>
<div
class=
"overview-card-header-left"
>
<div
class=
"overview-card-header-icon"
>
<img
:src=
"icon"
alt=
""
/>
</div>
<div
class=
"overview-card-header-title"
>
{{
title
}}
</div>
</div>
<div
v-if=
"$slots.right"
class=
"overview-card-header-right"
>
<slot
name=
"right"
/>
</div>
</div>
<div
class=
"overview-card-main"
>
<slot
/>
</div>
</div>
</
template
>
<
script
setup
>
defineProps
({
title
:
{
type
:
String
,
default
:
""
},
icon
:
{
type
:
String
,
default
:
""
}
});
</
script
>
<
style
lang=
"scss"
scoped
>
.overview-card
{
height
:
450px
;
box-sizing
:
border-box
;
border
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
border-radius
:
10px
;
box-shadow
:
0px
0px
20px
0px
rgba
(
25
,
69
,
130
,
0
.1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
overflow
:
hidden
;
.overview-card-header
{
height
:
53px
;
border-bottom
:
1px
solid
rgba
(
240
,
242
,
244
,
1
);
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
padding
:
0
27px
0
22px
;
.overview-card-header-left
{
display
:
flex
;
align-items
:
center
;
.overview-card-header-icon
{
width
:
19px
;
height
:
19px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.overview-card-header-title
{
margin-left
:
19px
;
height
:
26px
;
color
:
rgba
(
20
,
89
,
187
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
20px
;
font-weight
:
700
;
line-height
:
26px
;
}
}
.overview-card-header-right
{
display
:
flex
;
align-items
:
center
;
justify-content
:
flex-end
;
height
:
100%
;
}
}
.overview-card-main
{
height
:
calc
(
100%
-
53px
);
}
}
</
style
>
src/views/bill/billHome/ResourceLibrarySection.vue
0 → 100644
浏览文件 @
a4b931c9
<
template
>
<div
class=
"resource-library-section"
>
<div
class=
"home-content-footer-header"
>
<div
class=
"btn-box"
>
<div
class=
"btn"
:class=
"
{ btnActive: activeTabName === cate.name, disabled: index > 2 }"
v-for="(cate, index) in tabList" :key="index" @click="index
<
=
2
&&
handleClickTab
(
cate
)"
>
{{
cate
.
name
}}
</div>
</div>
</div>
<div
class=
"home-content-footer-main"
>
<div
class=
"left"
v-if=
"['国会法案', '国会议员', '议员合作关系'].includes(activeTabName)"
>
<div
class=
"select-box"
>
<div
class=
"select-box-header"
>
<div
class=
"icon"
></div>
<div
class=
"title"
>
科技领域
</div>
</div>
<div
class=
"select-main"
>
<el-checkbox-group
class=
"checkbox-group"
v-model=
"activeAreaList"
@
change=
"handleAreaChange"
>
<el-checkbox
class=
"filter-checkbox"
label=
"全部领域"
>
全部领域
</el-checkbox>
<el-checkbox
v-for=
"(area, index) in cateKuList"
:key=
"index"
:label=
"area.id"
class=
"filter-checkbox"
>
{{
area
.
name
}}
</el-checkbox>
</el-checkbox-group>
</div>
</div>
<div
class=
"select-box"
v-if=
"activeTabName !== '议员合作关系'"
>
<div
class=
"select-box-header"
>
<div
class=
"icon"
></div>
<div
class=
"title"
>
党派
</div>
</div>
<div
class=
"select-main"
>
<el-checkbox-group
class=
"checkbox-group"
v-model=
"activeDpList"
@
change=
"handleDpChange"
>
<el-checkbox
v-for=
"(dp, index) in dpList"
:key=
"index"
:label=
"dp.id"
class=
"filter-checkbox"
>
{{
dp
.
name
}}
</el-checkbox>
</el-checkbox-group>
</div>
</div>
<div
class=
"select-box"
v-if=
"activeTabName !== '议员合作关系'"
>
<div
class=
"select-box-header"
>
<div
class=
"icon"
></div>
<div
class=
"title"
>
议院
</div>
</div>
<div
class=
"select-main"
>
<el-checkbox-group
class=
"checkbox-group"
v-model=
"activeYyList"
@
change=
"handleYyChange"
>
<el-checkbox
v-for=
"(yy, index) in yyList"
:key=
"index"
:label=
"yy.id"
class=
"filter-checkbox"
>
{{
yy
.
name
}}
</el-checkbox>
</el-checkbox-group>
</div>
</div>
<div
class=
"select-box"
v-if=
"activeTabName === '国会法案'"
>
<div
class=
"select-box-header"
>
<div
class=
"icon"
></div>
<div
class=
"title"
>
发布时间
</div>
</div>
<div
class=
"select-main"
>
<el-checkbox-group
class=
"checkbox-group"
v-model=
"activePubTime"
@
change=
"handlePubTimeChange"
>
<el-checkbox
v-for=
"(time, index) in pubTime"
:key=
"index"
:label=
"time.id"
class=
"filter-checkbox"
>
{{
time
.
name
}}
</el-checkbox>
</el-checkbox-group>
</div>
</div>
<div
class=
"select-box"
v-if=
"activeTabName === '议员合作关系'"
>
<div
class=
"select-box-header"
>
<div
class=
"icon"
></div>
<div
class=
"title"
>
合作关系
</div>
</div>
<div
class=
"select-main"
>
<el-checkbox-group
class=
"checkbox-group"
v-model=
"activeCoopList"
@
change=
"handleCoopChange"
>
<el-checkbox
v-for=
"(coop, index) in coopList"
:key=
"index"
:label=
"coop.id"
class=
"filter-checkbox"
>
{{
coop
.
name
}}
</el-checkbox>
</el-checkbox-group>
</div>
</div>
</div>
<div
class=
"right"
>
<div
class=
"right-header"
>
<div
class=
"right-header-box"
>
<el-select
v-model=
"footerSelect1"
placeholder=
"选择委员会"
style=
"width: 240px"
@
change=
"handleFooterSelect1Change"
>
<el-option
v-for=
"item in postOrgList"
:key=
"item.departmentId"
:label=
"item.departmentName"
:value=
"item.departmentId"
/>
</el-select>
</div>
<template
v-if=
"activeTabName === '国会法案'"
>
<div
class=
"right-header-box"
>
<el-select
v-model=
"footerSelect2"
placeholder=
"选择提出议员"
style=
"width: 240px"
@
change=
"handleFooterSelect2Change"
>
<el-option
v-for=
"item in postMemberList"
:key=
"item.memberId"
:label=
"item.memberName"
:value=
"item.memberId"
/>
</el-select>
</div>
<div
class=
"right-header-box right-header-sort"
style=
"margin-left: auto"
>
<el-checkbox
v-model=
"isInvolveCn"
true-label=
"Y"
false-label=
"N"
class=
"involve-checkbox"
@
change=
"handleInvolveCnChange"
>
只看涉华法案
</el-checkbox>
<el-select
v-model=
"releaseTime"
placeholder=
"选择排序方式"
style=
"width: 120px"
@
change=
"handlePxChange"
>
<template
#
prefix
>
<div
style=
"display: flex; align-items: center; height: 100%"
>
<img
:src=
"desc"
style=
"width: 14px; height: 14px"
/>
</div>
</
template
>
<el-option
v-for=
"item in releaseTimeList"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</div>
</template>
</div>
<div
class=
"right-main"
v-loading=
"loading"
>
<
template
v-if=
"activeTabName === '国会法案'"
>
<div
class=
"right-main-box"
v-for=
"(item, index) in bills"
:key=
"index"
>
<div
v-if=
"item.riskSignal"
class=
"risk-tag"
:class=
"getRiskTagClass(item.riskSignal)"
>
{{
item
.
riskSignal
}}
</div>
<div
class=
"header"
>
<div
class=
"title"
@
click=
"onClickToDetail(item)"
:title=
"item.name"
>
{{
item
.
name
}}
</div>
<div
class=
"en-title"
:title=
"item.eName"
>
{{
item
.
eName
}}
</div>
</div>
<div
class=
"main"
>
<div
class=
"item"
><div
class=
"item-left"
>
提案人:
</div><div
class=
"item-right"
>
{{
item
.
tcr
}}
</div></div>
<div
class=
"item"
><div
class=
"item-left"
>
委员会:
</div><div
class=
"item-right"
>
{{
item
.
wyh
}}
</div></div>
<div
class=
"item"
><div
class=
"item-left"
>
相关领域:
</div><div
class=
"item-right1"
><div
class=
"tag"
v-for=
"(val, idx) in item.areaList"
:key=
"idx"
>
{{
val
}}
</div></div></div>
<div
class=
"item"
><div
class=
"item-left"
>
最新动议:
</div><div
class=
"item-right"
><CommonPrompt
:content=
"item.zxdy"
/></div></div>
<div
class=
"item"
>
<div
class=
"item-left"
>
法案进展:
</div>
<div
class=
"item-right2"
>
<div
class=
"tag"
v-for=
"(val, idx) in [...item.progress].reverse()"
:key=
"idx"
:style=
"
{ zIndex: item.progress.length - idx }">
{{
val
}}
</div>
</div>
</div>
</div>
</div>
<div
class=
"right-footer"
>
<div
class=
"footer-left"
>
{{
`共 ${total
}
项`
}}
<
/div
>
<
div
class
=
"footer-right"
>
<
el
-
pagination
@
current
-
change
=
"handleCurrentChange"
:
page
-
size
=
"pageSize"
:
current
-
page
=
"currentPage"
background
layout
=
"prev, pager, next"
:
total
=
"total"
/>
<
/div
>
<
/div
>
<
/template
>
<
div
v
-
else
-
if
=
"activeTabName === '国会议员'"
>
<
div
class
=
"member-grid"
>
<
div
class
=
"member-card"
v
-
for
=
"item in memberList"
:
key
=
"item.id"
>
<
div
class
=
"member-card-top"
>
<
div
class
=
"member-avatar-wrap"
>
<
img
class
=
"member-avatar"
:
src
=
"item.avatar || defaultAvatar"
alt
=
"avatar"
/>
<
div
class
=
"member-icon-row"
>
<
img
v
-
if
=
"item.partyIcon"
class
=
"member-mini-icon-img"
:
src
=
"item.partyIcon"
alt
=
"party"
/>
<
img
v
-
if
=
"item.chamberIcon"
class
=
"member-mini-icon-img"
:
src
=
"item.chamberIcon"
alt
=
"chamber"
/>
<
/div
>
<
/div
>
<
div
class
=
"member-main"
>
<
div
class
=
"member-title-row"
>
<
div
class
=
"member-name"
>
{{
item
.
name
||
'-'
}}
<
/div
>
<
div
class
=
"member-link"
>
{{
item
.
billCountText
||
'0项提案 >'
}}
<
/div
>
<
/div
>
<
div
class
=
"member-meta"
>
{{
item
.
partyText
||
'-'
}}
·
{{
item
.
chamberText
||
'-'
}}
·
{{
item
.
termText
||
'-'
}}
<
/div
>
<
div
class
=
"member-committee"
>
{{
item
.
committeeText
||
'-'
}}
<
/div
>
<
div
class
=
"member-tags"
>
<
div
class
=
"member-tag"
v
-
for
=
"(tag, idx) in item.focusTags"
:
key
=
"idx"
>
{{
tag
}}
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
div
class
=
"member-card-bottom"
@
click
=
"handleClickLatestProposal(item)"
>
<
div
class
=
"member-latest"
>
最新提案:
{{
item
.
latestProposal
||
'-'
}}
<
/div
>
<
div
class
=
"member-arrow"
>><
/div
>
<
/div
>
<
/div
>
<
/div
>
<
div
class
=
"right-footer"
>
<
div
class
=
"footer-left"
>
{{
`共 ${memberTotal
}
项`
}}
<
/div
>
<
div
class
=
"footer-right"
>
<
el
-
pagination
@
current
-
change
=
"handleMemberCurrentChange"
:
page
-
size
=
"memberPageSize"
:
current
-
page
=
"memberCurrentPage"
background
layout
=
"prev, pager, next"
:
total
=
"memberTotal"
/>
<
/div
>
<
/div
>
<
/div
>
<
div
v
-
else
-
if
=
"activeTabName === '议员合作关系'"
class
=
"coop-list"
>
<
div
class
=
"member-card"
v
-
for
=
"item in memberList"
:
key
=
"`coop-${item.id
}
`"
>
<
div
class
=
"member-name"
>
{{
item
.
name
||
'-'
}}
<
/div
>
<
div
class
=
"member-info"
>
党派:
{{
item
.
party
||
'-'
}}
<
/div
>
<
div
class
=
"member-info"
>
议院:
{{
item
.
chamber
||
'-'
}}
<
/div
>
<
div
class
=
"member-info"
>
任期:
{{
item
.
term
||
'-'
}}
<
/div
>
<
div
class
=
"member-info"
>
委员会:
{{
item
.
committee
||
'-'
}}
<
/div
>
<
div
class
=
"member-info"
>
关注领域:
{{
item
.
focus
||
'-'
}}
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/template
>
<
script
setup
>
import
{
onMounted
,
ref
}
from
"vue"
;
import
{
getHylyList
,
getPostOrgList
,
getPostMemberList
,
getBills
,
getBillsPerson
}
from
"@/api/bill/billHome"
;
import
CommonPrompt
from
"../commonPrompt/index.vue"
;
import
desc
from
"./assets/icons/icon-desc.png"
;
import
defaultAvatar
from
"./assets/images/user.png"
;
import
zyyIcon
from
"@/assets/icons/zyy.png"
;
import
cyyIcon
from
"@/assets/icons/cyy.png"
;
import
ghdIcon
from
"@/assets/icons/ghd.png"
;
import
mzdIcon
from
"@/assets/icons/mzd.png"
;
const
props
=
defineProps
({
onClickToDetail
:
{
type
:
Function
,
required
:
true
}
,
onAfterPageChange
:
{
type
:
Function
,
default
:
null
}
}
);
const
tabList
=
ref
([
{
name
:
"国会法案"
,
active
:
true
}
,
{
name
:
"国会议员"
,
active
:
false
}
,
{
name
:
"议员合作关系"
,
active
:
false
}
,
{
name
:
"涉华委员会"
,
active
:
false
}
]);
const
activeTabName
=
ref
(
"国会法案"
);
const
handleClickTab
=
tab
=>
{
activeTabName
.
value
=
tab
.
name
;
if
(
tab
.
name
===
"国会议员"
)
{
memberCurrentPage
.
value
=
1
;
handleGetBillsPerson
();
return
;
}
if
(
tab
.
name
===
"国会法案"
)
{
currentPage
.
value
=
1
;
handleGetBills
();
}
}
;
const
releaseTime
=
ref
(
true
);
const
releaseTimeList
=
ref
([{
label
:
"正序"
,
value
:
true
}
,
{
label
:
"倒序"
,
value
:
false
}
]);
const
isInvolveCn
=
ref
(
"Y"
);
const
cateKuList
=
ref
([]);
const
activeAreaList
=
ref
([
"全部领域"
]);
const
dpList
=
ref
([{
id
:
"全部党派"
,
name
:
"全部党派"
}
,
{
id
:
"Democratic"
,
name
:
"民主党"
}
,
{
id
:
"Republican"
,
name
:
"共和党"
}
]);
const
activeDpList
=
ref
([
"全部党派"
]);
const
yyList
=
ref
([{
id
:
"全部议院"
,
name
:
"全部议院"
}
,
{
id
:
"S"
,
name
:
"参议院"
}
,
{
id
:
"H"
,
name
:
"众议院"
}
]);
const
activeYyList
=
ref
([
"全部议院"
]);
const
pubTime
=
ref
([{
id
:
"全部时间"
,
name
:
"全部时间"
}
,
{
id
:
"2025"
,
name
:
"2025年"
}
,
{
id
:
"2024"
,
name
:
"2024年"
}
,
{
id
:
"2023"
,
name
:
"2023年"
}
,
{
id
:
"2022"
,
name
:
"2022年"
}
,
{
id
:
"2021"
,
name
:
"2021年"
}
]);
const
activePubTime
=
ref
([
"全部时间"
]);
const
coopList
=
ref
([
{
id
:
"全部合作关系"
,
name
:
"全部合作关系"
}
,
{
id
:
"跨党派合作"
,
name
:
"跨党派合作"
}
,
{
id
:
"同党派合作"
,
name
:
"同党派合作"
}
,
{
id
:
"地域利益合作"
,
name
:
"地域利益合作"
}
,
{
id
:
"委员会内合作"
,
name
:
"委员会内合作"
}
]);
const
activeCoopList
=
ref
([
"全部合作关系"
]);
const
footerSelect1
=
ref
(
"全部委员会"
);
const
footerSelect2
=
ref
(
"全部提出议员"
);
const
postOrgList
=
ref
([{
departmentName
:
"全部委员会"
,
departmentId
:
"全部委员会"
}
]);
const
postMemberList
=
ref
([{
memberName
:
"全部提出议员"
,
memberId
:
"全部提出议员"
}
]);
const
memberList
=
ref
([]);
const
memberTotal
=
ref
(
0
);
const
memberPageSize
=
ref
(
15
);
const
memberCurrentPage
=
ref
(
1
);
const
bills
=
ref
([]);
const
total
=
ref
(
0
);
const
pageSize
=
ref
(
4
);
const
currentPage
=
ref
(
1
);
const
loading
=
ref
(
false
);
const
abortController
=
ref
(
null
);
const
getRiskTagClass
=
riskSignal
=>
{
if
(
riskSignal
===
"特别重大风险"
)
return
"risk-tag-critical"
;
if
(
riskSignal
===
"重大风险"
)
return
"risk-tag-high"
;
if
(
riskSignal
===
"较大风险"
)
return
"risk-tag-medium"
;
return
""
;
}
;
const
handleGetHylyList
=
async
()
=>
{
try
{
const
res
=
await
getHylyList
();
cateKuList
.
value
=
res
.
data
||
[];
}
catch
(
error
)
{
}
}
;
const
handleGetPostOrgList
=
async
()
=>
{
try
{
const
res
=
await
getPostOrgList
();
if
(
res
.
code
===
200
)
{
const
list
=
(
res
.
data
||
[]).
filter
(
item
=>
item
.
departmentId
);
postOrgList
.
value
=
[{
departmentName
:
"全部委员会"
,
departmentId
:
"全部委员会"
}
,
...
list
];
}
}
catch
(
error
)
{
}
}
;
const
handleGetPostMemberList
=
async
()
=>
{
try
{
const
res
=
await
getPostMemberList
();
if
(
res
.
code
===
200
)
{
const
list
=
(
res
.
data
||
[]).
filter
(
item
=>
item
.
memberId
);
postMemberList
.
value
=
[{
memberName
:
"全部提出议员"
,
memberId
:
"全部提出议员"
}
,
...
list
];
}
}
catch
(
error
)
{
}
}
;
// 获取资源库法案列表
const
handleGetBills
=
async
()
=>
{
if
(
abortController
.
value
)
abortController
.
value
.
abort
();
abortController
.
value
=
new
AbortController
();
loading
.
value
=
true
;
const
params
=
{
currentPage
:
currentPage
.
value
,
pageSize
:
pageSize
.
value
,
isInvolveCn
:
isInvolveCn
.
value
}
;
if
(
!
activeYyList
.
value
.
includes
(
"全部议院"
))
params
.
congressIds
=
activeYyList
.
value
.
join
(
","
);
if
(
footerSelect1
.
value
!==
"全部委员会"
)
params
.
departmentId
=
footerSelect1
.
value
;
if
(
!
activeDpList
.
value
.
includes
(
"全部党派"
))
params
.
partyIds
=
activeDpList
.
value
.
join
(
","
);
if
(
footerSelect2
.
value
!==
"全部提出议员"
)
params
.
personId
=
footerSelect2
.
value
;
if
(
!
activeAreaList
.
value
.
includes
(
"全部领域"
))
params
.
researchIds
=
activeAreaList
.
value
.
join
(
","
);
if
(
releaseTime
.
value
!==
true
)
params
.
sortFun
=
releaseTime
.
value
;
if
(
!
activePubTime
.
value
.
includes
(
"全部时间"
))
params
.
years
=
activePubTime
.
value
.
join
(
","
);
try
{
const
res
=
await
getBills
(
params
,
abortController
.
value
.
signal
);
if
(
res
.
code
===
200
&&
res
.
data
&&
res
.
data
.
content
)
{
bills
.
value
=
res
.
data
.
content
.
map
(
item
=>
({
billId
:
item
.
billId
,
name
:
item
.
billName
,
eName
:
item
.
billNameEn
,
tcr
:
item
.
personName
,
wyh
:
item
.
congressName
,
areaList
:
item
.
hylyList
||
[],
zxdy
:
item
.
latestAction
,
progress
:
item
.
stageList
||
[],
riskSignal
:
item
.
riskSignal
||
""
}
));
total
.
value
=
res
.
data
.
totalElements
;
}
else
{
bills
.
value
=
[];
total
.
value
=
0
;
}
}
catch
(
error
)
{
if
(
error
.
name
!==
"AbortError"
)
{
bills
.
value
=
[];
total
.
value
=
0
;
}
}
finally
{
loading
.
value
=
false
;
}
}
;
// 获取资源库国会议员列表
const
handleGetBillsPerson
=
async
()
=>
{
if
(
abortController
.
value
)
abortController
.
value
.
abort
();
abortController
.
value
=
new
AbortController
();
loading
.
value
=
true
;
const
params
=
{
currentPage
:
memberCurrentPage
.
value
,
pageSize
:
memberPageSize
.
value
}
;
if
(
footerSelect1
.
value
!==
"全部委员会"
)
params
.
committeeId
=
footerSelect1
.
value
;
if
(
!
activeYyList
.
value
.
includes
(
"全部议院"
))
params
.
congressIds
=
activeYyList
.
value
;
if
(
!
activeDpList
.
value
.
includes
(
"全部党派"
))
params
.
partyIds
=
activeDpList
.
value
;
if
(
!
activeAreaList
.
value
.
includes
(
"全部领域"
))
params
.
domainIds
=
activeAreaList
.
value
;
const
formatDateYm
=
dateStr
=>
{
if
(
!
dateStr
)
return
""
;
const
date
=
String
(
dateStr
).
slice
(
0
,
10
);
const
parts
=
date
.
split
(
"-"
);
if
(
parts
.
length
<
2
)
return
dateStr
;
return
`${parts[0]
}
.${parts[1]
}
`
;
}
;
try
{
const
res
=
await
getBillsPerson
(
params
,
abortController
.
value
.
signal
);
if
(
res
.
code
===
200
&&
res
.
data
&&
res
.
data
.
content
)
{
memberList
.
value
=
res
.
data
.
content
.
map
(
item
=>
{
const
partyMap
=
{
Democratic
:
"民主党"
,
Republican
:
"共和党"
}
;
const
partyText
=
partyMap
[
item
.
partyId
]
||
item
.
partyId
||
"-"
;
const
chamberText
=
item
.
congressType
||
"-"
;
const
start
=
formatDateYm
(
item
.
startTime
);
const
end
=
formatDateYm
(
item
.
endTime
);
const
termText
=
start
||
end
?
`${start
}
${end ? `
-
$
{
end
}
` : ""
}
`
:
"-"
;
const
focusTags
=
(
item
.
domainNames
||
[]).
slice
(
0
,
3
);
const
proposalSize
=
Number
(
item
.
proposalSize
||
0
);
const
partyIcon
=
item
.
partyId
===
"Democratic"
?
mzdIcon
:
item
.
partyId
===
"Republican"
?
ghdIcon
:
""
;
const
chamberIcon
=
chamberText
===
"众议院"
?
zyyIcon
:
chamberText
===
"参议院"
?
cyyIcon
:
""
;
return
{
id
:
item
.
id
,
name
:
item
.
name
||
"-"
,
avatar
:
item
.
imageUrl
||
""
,
partyIcon
,
chamberIcon
,
billCountText
:
`${proposalSize.toLocaleString()
}
项提案 >`
,
partyText
,
chamberText
,
termText
,
committeeText
:
item
.
position
||
"-"
,
focusTags
,
latestProposal
:
item
.
latestBillInfo
?.
billName
||
"-"
,
latestProposalBillId
:
item
.
latestBillInfo
?.
billId
||
""
,
party
:
item
.
partyId
,
chamber
:
item
.
congressType
,
term
:
`${item.startTime || ""
}
${item.endTime ? `
至
$
{
item
.
endTime
}
` : ""
}
`
,
committee
:
item
.
position
,
focus
:
(
item
.
domainNames
||
[]).
join
(
"、"
)
}
;
}
);
memberTotal
.
value
=
res
.
data
.
totalElements
||
0
;
}
else
{
memberList
.
value
=
[];
memberTotal
.
value
=
0
;
}
}
catch
(
error
)
{
if
(
error
.
name
!==
"AbortError"
)
{
memberList
.
value
=
[];
memberTotal
.
value
=
0
;
}
}
finally
{
loading
.
value
=
false
;
}
}
;
const
normalizeWithAll
=
(
val
,
allLabel
,
targetRef
)
=>
{
if
(
val
.
includes
(
allLabel
)
&&
val
.
length
>
1
)
{
targetRef
.
value
=
val
[
val
.
length
-
1
]
===
allLabel
?
[
allLabel
]
:
val
.
filter
(
item
=>
item
!==
allLabel
);
}
else
if
(
val
.
length
===
0
)
{
targetRef
.
value
=
[
allLabel
];
}
else
{
targetRef
.
value
=
val
;
}
currentPage
.
value
=
1
;
memberCurrentPage
.
value
=
1
;
if
(
activeTabName
.
value
===
"国会议员"
)
{
handleGetBillsPerson
();
return
;
}
handleGetBills
();
}
;
const
handleAreaChange
=
val
=>
normalizeWithAll
(
val
,
"全部领域"
,
activeAreaList
);
const
handleDpChange
=
val
=>
normalizeWithAll
(
val
,
"全部党派"
,
activeDpList
);
const
handleYyChange
=
val
=>
normalizeWithAll
(
val
,
"全部议院"
,
activeYyList
);
const
handlePubTimeChange
=
val
=>
normalizeWithAll
(
val
,
"全部时间"
,
activePubTime
);
const
handleCoopChange
=
val
=>
normalizeWithAll
(
val
,
"全部合作关系"
,
activeCoopList
);
const
handleFooterSelect1Change
=
val
=>
{
footerSelect1
.
value
=
val
;
currentPage
.
value
=
1
;
memberCurrentPage
.
value
=
1
;
if
(
activeTabName
.
value
===
"国会议员"
)
{
handleGetBillsPerson
();
return
;
}
handleGetBills
();
}
;
const
handleFooterSelect2Change
=
val
=>
{
footerSelect2
.
value
=
val
;
currentPage
.
value
=
1
;
handleGetBills
();
}
;
const
handlePxChange
=
val
=>
{
releaseTime
.
value
=
val
;
currentPage
.
value
=
1
;
handleGetBills
();
}
;
const
handleInvolveCnChange
=
val
=>
{
isInvolveCn
.
value
=
val
;
currentPage
.
value
=
1
;
handleGetBills
();
}
;
const
handleCurrentChange
=
page
=>
{
currentPage
.
value
=
page
;
handleGetBills
();
props
.
onAfterPageChange
&&
props
.
onAfterPageChange
();
}
;
const
handleClickLatestProposal
=
item
=>
{
if
(
!
item
?.
latestProposalBillId
)
return
;
props
.
onClickToDetail
({
billId
:
item
.
latestProposalBillId
,
name
:
item
.
latestProposal
}
);
}
;
const
handleMemberCurrentChange
=
page
=>
{
memberCurrentPage
.
value
=
page
;
handleGetBillsPerson
();
props
.
onAfterPageChange
&&
props
.
onAfterPageChange
();
}
;
onMounted
(()
=>
{
handleGetHylyList
();
handleGetPostOrgList
();
handleGetPostMemberList
();
handleGetBills
();
}
);
<
/script
>
<
style
lang
=
"scss"
scoped
>
.
home
-
content
-
footer
-
header
{
width
:
1600
px
;
margin
:
0
auto
;
margin
-
top
:
37
px
;
margin
-
bottom
:
36
px
;
height
:
42
px
;
display
:
flex
;
justify
-
content
:
space
-
between
;
.
btn
-
box
{
display
:
flex
;
gap
:
24
px
;
width
:
1000
px
;
.
btn
{
height
:
42
px
;
line
-
height
:
42
px
;
padding
:
0
20
px
;
color
:
rgba
(
59
,
65
,
75
,
1
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
20
px
;
font
-
weight
:
400
;
border
-
radius
:
21
px
;
cursor
:
pointer
;
&
:
hover
{
background
:
rgba
(
20
,
89
,
187
,
0.1
);
}
}
.
btnActive
{
background
:
var
(
--
color
-
main
-
active
);
color
:
#
fff
;
font
-
weight
:
700
;
&
:
hover
{
color
:
#
fff
;
background
:
var
(
--
color
-
main
-
active
);
}
}
.
disabled
{
cursor
:
not
-
allowed
;
opacity
:
0.5
;
&
:
hover
{
background
:
transparent
;
}
}
}
}
.
home
-
content
-
footer
-
main
{
width
:
1600
px
;
height
:
1401
px
;
margin
:
0
auto
;
display
:
flex
;
justify
-
content
:
space
-
between
;
align
-
items
:
flex
-
start
;
.
left
{
width
:
300
px
;
padding
-
bottom
:
33
px
;
box
-
sizing
:
border
-
box
;
border
:
1
px
solid
rgba
(
234
,
236
,
238
,
1
);
border
-
radius
:
10
px
;
box
-
shadow
:
0
px
0
px
20
px
0
px
rgba
(
25
,
69
,
130
,
0.1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
.
select
-
box
{
margin
-
top
:
20
px
;
.
select
-
box
-
header
{
display
:
flex
;
gap
:
17
px
;
.
icon
{
margin
-
top
:
4
px
;
width
:
8
px
;
height
:
16
px
;
background
:
var
(
--
color
-
main
-
active
);
border
-
radius
:
0
4
px
4
px
0
;
}
.
title
{
color
:
var
(
--
color
-
main
-
active
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
20
px
;
font
-
weight
:
700
;
line
-
height
:
26
px
;
letter
-
spacing
:
1
px
;
text
-
align
:
left
;
}
}
.
select
-
main
{
margin
-
left
:
25
px
;
margin
-
top
:
16
px
;
.
checkbox
-
group
{
display
:
flex
;
flex
-
wrap
:
wrap
;
.
filter
-
checkbox
{
width
:
50
%
;
margin
-
right
:
0
;
margin
-
bottom
:
4
px
;
:
deep
(.
el
-
checkbox__label
)
{
color
:
rgb
(
95
,
101
,
108
);
font
-
size
:
16
px
;
font
-
weight
:
400
;
font
-
family
:
"Microsoft YaHei"
;
line
-
height
:
24
px
;
}
}
}
}
}
}
.
right
{
margin
-
left
:
20
px
;
width
:
1280
px
;
.
right
-
header
{
height
:
48
px
;
display
:
flex
;
gap
:
18
px
;
.
right
-
header
-
sort
{
display
:
flex
;
align
-
items
:
center
;
gap
:
20
px
;
}
.
involve
-
checkbox
{
height
:
40
px
;
display
:
inline
-
flex
;
align
-
items
:
center
;
margin
-
right
:
0
;
:
deep
(.
el
-
checkbox__inner
)
{
width
:
18
px
;
height
:
18
px
;
border
-
radius
:
5
px
;
}
:
deep
(.
el
-
checkbox__input
.
is
-
checked
.
el
-
checkbox__inner
)
{
background
-
color
:
#
1677
ff
;
border
-
color
:
#
1677
ff
;
}
:
deep
(.
el
-
checkbox__inner
::
after
)
{
box
-
sizing
:
content
-
box
;
}
:
deep
(.
el
-
checkbox__label
)
{
color
:
#
5
f656c
;
font
-
family
:
"Microsoft YaHei"
;
font
-
size
:
16
px
;
font
-
weight
:
400
;
line
-
height
:
24
px
;
padding
-
left
:
10
px
;
}
}
}
.
right
-
main
{
height
:
1264
px
;
.
member
-
grid
,
.
coop
-
list
{
display
:
grid
;
column
-
gap
:
16
px
;
row
-
gap
:
16
px
;
.
member
-
card
{
height
:
200
px
;
padding
:
10
px
16
px
0
;
box
-
sizing
:
border
-
box
;
border
-
radius
:
10
px
;
box
-
shadow
:
0
px
0
px
20
px
0
px
rgba
(
25
,
69
,
130
,
0.1
);
background
:
#
fff
;
overflow
:
hidden
;
display
:
flex
;
flex
-
direction
:
column
;
justify
-
content
:
space
-
between
;
.
member
-
card
-
top
{
display
:
flex
;
gap
:
16
px
;
}
.
member
-
avatar
-
wrap
{
width
:
88
px
;
display
:
flex
;
flex
-
direction
:
column
;
align
-
items
:
center
;
flex
-
shrink
:
0
;
position
:
relative
;
/* padding-bottom: 22px; */
margin
-
top
:
5
px
;
}
.
member
-
avatar
{
width
:
88
px
;
height
:
88
px
;
border
-
radius
:
50
%
;
object
-
fit
:
cover
;
}
.
member
-
icon
-
row
{
position
:
absolute
;
left
:
50
%
;
bottom
:
18
px
;
transform
:
translateX
(
-
50
%
);
display
:
flex
;
gap
:
2
px
;
align
-
items
:
center
;
}
.
member
-
mini
-
icon
-
img
{
width
:
16
px
;
height
:
16
px
;
padding
:
2
px
;
box
-
sizing
:
border
-
box
;
object
-
fit
:
contain
;
border
-
radius
:
50
%
;
background
:
#
fff
;
}
.
member
-
main
{
flex
:
1
;
min
-
width
:
0
;
padding
-
top
:
2
px
;
}
.
member
-
title
-
row
{
display
:
flex
;
align
-
items
:
baseline
;
justify
-
content
:
space
-
between
;
align
-
items
:
center
;
gap
:
8
px
;
}
.
member
-
name
{
color
:
rgb
(
59
,
65
,
75
);
font
-
family
:
"Source Han Sans CN"
;
font
-
size
:
18
px
;
font
-
weight
:
700
;
line
-
height
:
24
px
;
white
-
space
:
nowrap
;
overflow
:
hidden
;
text
-
overflow
:
ellipsis
;
}
.
member
-
link
{
flex
-
shrink
:
0
;
color
:
#
1459
bb
;
font
-
size
:
16
px
;
line
-
height
:
24
px
;
}
.
member
-
meta
,
.
member
-
committee
{
margin
-
top
:
6
px
;
color
:
#
5
f656c
;
font
-
size
:
16
px
;
line
-
height
:
24
px
;
font
-
weight
:
400
;
white
-
space
:
nowrap
;
overflow
:
hidden
;
text
-
overflow
:
ellipsis
;
}
.
member
-
tags
{
margin
-
top
:
10
px
;
display
:
flex
;
gap
:
8
px
;
flex
-
wrap
:
wrap
;
}
.
member
-
tag
{
height
:
24
px
;
padding
:
5
px
8
px
;
border
-
radius
:
4
px
;
background
:
rgb
(
231
,
243
,
255
);
color
:
rgb
(
5
,
95
,
194
);
font
-
size
:
14
px
;
font
-
weight
:
400
;
line
-
height
:
14
px
;
}
.
member
-
card
-
bottom
{
height
:
52
px
;
margin
:
10
px
-
16
px
0
;
padding
:
0
16
px
;
display
:
flex
;
align
-
items
:
center
;
justify
-
content
:
space
-
between
;
border
-
top
:
1
px
solid
#
eaeced
;
color
:
#
5
f656c
;
font
-
size
:
16
px
;
cursor
:
pointer
;
&
:
hover
{
background
:
rgba
(
20
,
89
,
187
,
0.04
);
}
}
.
member
-
latest
{
flex
:
1
;
white
-
space
:
nowrap
;
overflow
:
hidden
;
text
-
overflow
:
ellipsis
;
padding
-
right
:
8
px
;
}
.
member
-
arrow
{
font
-
size
:
16
px
;
line
-
height
:
1
;
color
:
#
5
f656c
;
}
.
member
-
info
{
color
:
#
5
f656c
;
font
-
family
:
"Microsoft YaHei"
;
font
-
size
:
15
px
;
font
-
weight
:
400
;
line
-
height
:
28
px
;
}
}
}
.
member
-
grid
{
grid
-
template
-
columns
:
repeat
(
3
,
1
fr
);
}
.
coop
-
list
{
grid
-
template
-
columns
:
1
fr
;
}
.
right
-
main
-
box
{
position
:
relative
;
width
:
1280
px
;
height
:
300
px
;
padding
-
bottom
:
24
px
;
border
-
radius
:
10
px
;
box
-
shadow
:
0
px
0
px
20
px
0
px
rgba
(
25
,
69
,
130
,
0.1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
margin
-
bottom
:
16
px
;
overflow
:
hidden
;
.
risk
-
tag
{
position
:
absolute
;
top
:
16
px
;
right
:
40
px
;
height
:
28
px
;
border
-
radius
:
20
px
;
display
:
inline
-
flex
;
align
-
items
:
center
;
gap
:
6
px
;
padding
:
0
10
px
;
box
-
sizing
:
border
-
box
;
font
-
family
:
"Microsoft YaHei"
;
font
-
size
:
14
px
;
font
-
weight
:
500
;
line
-
height
:
28
px
;
white
-
space
:
nowrap
;
&
::
before
{
content
:
""
;
width
:
5
px
;
height
:
5
px
;
border
-
radius
:
50
%
;
background
:
currentColor
;
flex
-
shrink
:
0
;
}
}
.
risk
-
tag
-
critical
{
background
:
rgba
(
206
,
79
,
81
,
0.1
);
color
:
rgb
(
206
,
79
,
81
);
}
.
risk
-
tag
-
high
{
background
:
rgba
(
255
,
149
,
77
,
0.1
);
color
:
rgb
(
255
,
149
,
77
);
}
.
risk
-
tag
-
medium
{
background
:
rgba
(
232
,
189
,
11
,
0.1
);
color
:
rgb
(
232
,
189
,
11
);
}
.
header
{
height
:
91
px
;
width
:
1200
px
;
margin
:
0
auto
;
border
-
bottom
:
1
px
solid
rgba
(
234
,
236
,
238
,
1
);
padding
-
top
:
19
px
;
.
title
{
cursor
:
pointer
;
height
:
26
px
;
color
:
rgba
(
59
,
65
,
75
,
1
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
20
px
;
font
-
weight
:
700
;
line
-
height
:
26
px
;
letter
-
spacing
:
0
px
;
text
-
align
:
left
;
overflow
:
hidden
;
text
-
overflow
:
ellipsis
;
white
-
space
:
nowrap
;
}
.
en
-
title
{
margin
-
top
:
8
px
;
height
:
24
px
;
color
:
rgba
(
95
,
101
,
108
,
1
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
16
px
;
font
-
weight
:
400
;
line
-
height
:
24
px
;
letter
-
spacing
:
0
px
;
text
-
align
:
left
;
overflow
:
hidden
;
text
-
overflow
:
ellipsis
;
white
-
space
:
nowrap
;
}
}
.
main
{
width
:
1200
px
;
margin
:
0
auto
;
margin
-
top
:
2
px
;
.
item
{
margin
-
top
:
12
px
;
display
:
flex
;
.
item
-
left
{
width
:
100
px
;
color
:
rgb
(
59
,
65
,
75
);
font
-
family
:
"Microsoft YaHei"
;
font
-
size
:
16
px
;
font
-
weight
:
700
;
line
-
height
:
24
px
;
letter
-
spacing
:
1
px
;
text
-
align
:
left
;
}
.
item
-
right
{
max
-
width
:
1000
px
;
margin
-
left
:
10
px
;
color
:
rgba
(
95
,
101
,
108
,
1
);
font
-
family
:
"Microsoft YaHei"
;
font
-
size
:
16
px
;
font
-
weight
:
400
;
line
-
height
:
24
px
;
letter
-
spacing
:
0
px
;
text
-
align
:
left
;
}
.
item
-
right1
{
margin
-
left
:
10
px
;
display
:
flex
;
gap
:
8
px
;
.
tag
{
height
:
24
px
;
line
-
height
:
24
px
;
padding
:
0
8
px
;
border
-
radius
:
4
px
;
background
:
rgba
(
231
,
243
,
255
,
1
);
color
:
var
(
--
color
-
main
-
active
);
font
-
family
:
"Microsoft YaHei"
;
font
-
size
:
14
px
;
font
-
weight
:
400
;
}
}
.
item
-
right2
{
margin
-
left
:
10
px
;
display
:
flex
;
align
-
items
:
center
;
.
tag
{
height
:
24
px
;
line
-
height
:
22
px
;
padding
:
0
10
px
0
30
px
;
background
:
rgba
(
255
,
255
,
255
,
1
);
color
:
rgb
(
95
,
101
,
108
);
border
-
top
:
1
px
solid
rgb
(
234
,
236
,
238
);
border
-
bottom
:
1
px
solid
rgb
(
234
,
236
,
238
);
position
:
relative
;
margin
-
left
:
-
10
px
;
font
-
family
:
"Microsoft YaHei"
;
font
-
size
:
14
px
;
font
-
weight
:
400
;
&
::
after
{
content
:
""
;
position
:
absolute
;
top
:
50
%
;
right
:
-
8.485
px
;
width
:
16.97
px
;
height
:
16.97
px
;
background
:
inherit
;
border
-
top
:
1
px
solid
rgb
(
234
,
236
,
238
);
border
-
right
:
1
px
solid
rgb
(
234
,
236
,
238
);
transform
:
translateY
(
-
50
%
)
rotate
(
45
deg
);
z
-
index
:
1
;
box
-
shadow
:
2
px
-
2
px
2
px
rgba
(
0
,
0
,
0
,
0.05
);
box
-
sizing
:
border
-
box
;
}
&
:
first
-
child
{
margin
-
left
:
0
;
padding
-
left
:
10
px
;
border
-
left
:
1
px
solid
rgb
(
234
,
236
,
238
);
border
-
radius
:
4
px
0
0
4
px
;
}
&
:
last
-
child
{
background
:
rgb
(
59
,
65
,
75
);
color
:
rgba
(
255
,
255
,
255
,
1
);
border
-
color
:
rgb
(
59
,
65
,
75
);
padding
-
right
:
10
px
;
border
-
radius
:
0
;
border
-
right
:
none
;
&
::
after
{
display
:
block
;
border
-
color
:
rgb
(
59
,
65
,
75
);
box
-
shadow
:
none
;
}
}
&
:
first
-
child
:
last
-
child
{
margin
-
left
:
0
;
padding
:
0
10
px
;
border
-
radius
:
4
px
0
0
4
px
;
background
:
rgb
(
59
,
65
,
75
);
color
:
rgba
(
255
,
255
,
255
,
1
);
border
:
1
px
solid
rgb
(
59
,
65
,
75
);
border
-
right
:
none
;
}
}
}
}
}
}
}
.
right
-
footer
{
height
:
85
px
;
display
:
flex
;
justify
-
content
:
space
-
between
;
box
-
sizing
:
border
-
box
;
padding
-
top
:
12
px
;
.
footer
-
left
{
color
:
rgba
(
59
,
65
,
75
,
1
);
font
-
family
:
"Microsoft YaHei"
;
font
-
size
:
16
px
;
font
-
weight
:
400
;
line
-
height
:
32
px
;
}
}
}
}
<
/style
>
src/views/bill/billHome/index.vue
浏览文件 @
a4b931c9
...
...
@@ -13,7 +13,10 @@
<DivideHeader
id=
"position1"
class=
"divide1"
:titleText=
"'最新动态'"
></DivideHeader>
<div
class=
"home-content-center"
>
<div
class=
"center-top"
>
<div
class=
"box1"
>
<overviewMainBox
class=
"box1"
title=
"热门法案"
@
toDetail=
"handleClickToDetail"
>
<template
#
headerIcon
>
<img
style=
"width: 100%; height: 100%"
src=
"./assets/images/box1-header-icon.png"
alt=
""
/>
</
template
>
<div
class=
"box1-left"
@
click=
"handleSwithCurBill('left')"
>
<div
class=
"icon"
>
<img
src=
"./assets/images/box1-left.svg"
alt=
""
/>
...
...
@@ -24,17 +27,6 @@
<img
src=
"./assets/images/box1-right.svg"
alt=
""
/>
</div>
</div>
<div
class=
"box1-header"
>
<div
class=
"box1-header-left"
>
<div
class=
"icon"
>
<img
src=
"./assets/images/box1-header-icon.png"
alt=
""
/>
</div>
<div
class=
"title"
>
{{
"热门法案"
}}
</div>
</div>
<div
class=
"box1-header-right"
@
click=
"handleClickToDetail()"
>
{{
"查看详情 >"
}}
</div>
</div>
<div
class=
"box1-main"
style=
"display: block"
>
<el-carousel
ref=
"carouselRef"
height=
"354px"
:autoplay=
"true"
:interval=
"3000"
arrow=
"never"
indicator-position=
"none"
@
change=
"handleCarouselChange"
>
...
...
@@ -42,7 +34,6 @@
<div
class=
"carousel-content"
style=
"display: flex; height: 100%"
>
<div
class=
"box1-main-left"
>
<div
class=
"box1-main-left-title"
>
<!-- "H.R.1(119th)-大而美法案" -->
{{ bill.billName }}
</div>
<div
class=
"box1-main-left-info"
>
...
...
@@ -102,7 +93,7 @@
</el-carousel-item>
</el-carousel>
</div>
</
div
>
</
overviewMainBox
>
<RiskSignal
:list=
"warningList"
@
more-click=
"handleToMoreRiskSignal"
@
item-click=
"handleClickToDetailO"
riskLevel=
"signalLevel"
postDate=
"signalTime"
name=
"signalTitle"
/>
...
...
@@ -112,320 +103,71 @@
<div
class=
"center-center"
>
<NewsList
:list=
"newsList"
/>
<MessageBubble
:messageList=
"messageList"
imageUrl=
"personImage"
@
more-click=
"handleToSocialDetail"
@
person-click=
"handleCl
ci
kToCharacter"
name=
"personName"
@
more-click=
"handleToSocialDetail"
@
person-click=
"handleCl
ic
kToCharacter"
name=
"personName"
content=
"remarks"
source=
"orgName"
/>
</div>
<DivideHeader
id=
"position3"
class=
"divide3"
:titleText=
"'数据总览'"
></DivideHeader>
<div
class=
"center-footer"
>
<div
class=
"box5"
>
<div
class=
"box5-header"
>
<div
class=
"box5-header-left"
>
<div
class=
"box5-header-icon"
>
<img
src=
"./assets/images/box5-header-icon.png"
alt=
""
/>
</div>
<div
class=
"box5-header-title"
>
{{
"涉华法案数量"
}}
</div>
</div>
<div
class=
"box5-header-right"
>
<!--
<div
class=
"header-right-icon"
>
<img
src=
"./assets/images/tips-icon.png"
alt=
""
/>
</div>
<div
class=
"header-right-text"
>
{{
"数据来源:美国国会官方网站"
}}
</div>
-->
<div
class=
"box5-select"
>
<el-select
v-model=
"box5Select"
placeholder=
"选择领域"
@
change=
"handleBox5Change"
style=
"width: 150px"
>
<el-option
label=
"全部领域"
value=
"全部领域"
/>
<el-option
v-for=
"item in categoryList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
/>
</el-select>
</div>
</div>
</div>
<OverviewCard
class=
"overview-card--double box5"
title=
"涉华法案数量"
:icon=
"box5HeaderIcon"
>
<
template
#
right
>
<el-select
v-model=
"box5Select"
placeholder=
"选择领域"
@
change=
"handleBox5Change"
style=
"width: 150px"
>
<el-option
label=
"全部领域"
value=
"全部领域"
/>
<el-option
v-for=
"item in categoryList"
:key=
"item.id"
:label=
"item.name"
:value=
"item.id"
/>
</el-select>
</
template
>
<div
class=
"box5-main"
:style=
"getEmptyStateStyle(box5HasData)"
>
<el-empty
v-if=
"!box5HasData"
description=
"暂无数据"
:image-size=
"100"
/>
<div
v-else
id=
"box5Chart"
style=
"width: 100%; height: 100%"
></div>
</div>
</div>
<div
class=
"box6"
>
<div
class=
"box6-header"
>
<div
class=
"header-icon"
>
<img
src=
"./assets/images/box6-header-icon.png"
alt=
""
/>
</div>
<div
class=
"header-title"
>
{{
"涉华法案领域分布"
}}
</div>
<div
class=
"box6-header-right"
>
<el-select
v-model=
"box9selectetedTime"
placeholder=
"选择时间"
style=
"width: 90px"
>
<el-option
v-for=
"item in box9YearList"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</div>
</div>
</OverviewCard>
<OverviewCard
class=
"overview-card--single box6"
title=
"涉华法案领域分布"
:icon=
"box6HeaderIcon"
>
<
template
#
right
>
<el-select
v-model=
"box9selectetedTime"
placeholder=
"选择时间"
style=
"width: 90px"
>
<el-option
v-for=
"item in box9YearList"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</
template
>
<div
class=
"box6-main"
:style=
"getEmptyStateStyle(box9HasData)"
>
<el-empty
v-if=
"!box9HasData"
description=
"暂无数据"
:image-size=
"100"
/>
<div
v-else
id=
"box9Chart"
style=
"width: 100%; height: 100%"
></div>
</div>
</
div
>
</
OverviewCard
>
</div>
<div
class=
"center-footer1"
>
<div
class=
"box7"
>
<div
class=
"box7-header"
>
<div
class=
"box7-header-left"
>
<div
class=
"box7-header-icon"
>
<img
src=
"./assets/images/box7-header-icon.png"
alt=
""
/>
</div>
<div
class=
"box7-header-title"
>
{{
"法案提出部门"
}}
</div>
</div>
<div
class=
"box7-header-right"
>
<!--
<div
class=
"header-right-icon"
>
<img
src=
"./assets/images/tips-icon.png"
alt=
""
/>
</div>
-->
<!--
<div
class=
"header-right-text"
>
{{
"数据来源:美国国会官方网站"
}}
</div>
-->
<el-select
v-model=
"box7selectetedTime"
placeholder=
"选择时间"
style=
"width: 90px"
>
<el-option
v-for=
"item in box7YearList"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</div>
</div>
<!--
<div
class=
"box-center"
>
<OverviewCard
class=
"overview-card--single box7"
title=
"法案提出部门"
:icon=
"box7HeaderIcon"
>
<
template
#
right
>
<el-select
v-model=
"box7selectetedTime"
placeholder=
"选择时间"
style=
"width: 90px"
>
<el-option
v-for=
"item in box7YearList"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
<el-option
v-for=
"item in box7YearList"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</
div>
--
>
</
template
>
<div
class=
"box7-main"
:style=
"getEmptyStateStyle(box7HasData)"
>
<el-empty
v-if=
"!box7HasData"
description=
"暂无数据"
:image-size=
"100"
/>
<div
v-else
id=
"box7Chart"
style=
"width: 100%; height: 100%"
></div>
</div>
</div>
<div
class=
"box8"
>
<div
class=
"box8-header"
>
<div
class=
"box8-header-left"
>
<div
class=
"box8-header-icon"
>
<img
src=
"./assets/images/box7-header-icon.png"
alt=
""
/>
</div>
<div
class=
"box8-header-title"
>
{{
"关键议员提案"
}}
</div>
</div>
<div
class=
"box8-header-right"
>
<!--
<div
class=
"header-right-icon"
>
<img
src=
"./assets/images/tips-icon.png"
alt=
""
/>
</div>
-->
<!--
<div
class=
"header-right-text"
>
{{
"数据来源:美国国会官方网站"
}}
</div>
-->
<el-select
v-model=
"box8selectetedTime"
placeholder=
"选择时间"
style=
"width: 90px"
>
<el-option
v-for=
"item in box8YearList"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</div>
</div>
<!--
<div
class=
"box-center"
>
</OverviewCard>
<OverviewCard
class=
"overview-card--single box8"
title=
"涉华法案进展分布"
:icon=
"box7HeaderIcon"
>
<
template
#
right
>
<el-select
v-model=
"box8selectetedTime"
placeholder=
"选择时间"
style=
"width: 90px"
>
<el-option
v-for=
"item in box8YearList"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
<el-option
v-for=
"item in box8YearList"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</div>
-->
<div
class=
"box8-main"
:style=
"getEmptyStateStyle(box8Data.length > 0)"
>
<el-empty
v-if=
"box8Data.length === 0"
description=
"暂无数据"
:image-size=
"100"
/>
<div
v-else
class=
"box8-main-item"
v-for=
"(item, index) in box8Data"
:key=
"index"
@
click=
"handleClcikToCharacter(item.memberId, item.name)"
>
<div
class=
"box8-main-item-left"
>
<img
:src=
"getProxyUrl(item.img)"
alt=
""
referrerpolicy=
"no-referrer"
class=
"left-img"
/>
<div
class=
"left-icon1"
>
<img
:src=
"item.dangpai"
alt=
""
/>
</div>
<div
class=
"left-icon2"
>
<img
:src=
"item.yuan"
alt=
""
/>
</div>
</div>
<div
class=
"box8-main-item-center"
>
<div
class=
"box8-main-item-center-top"
>
{{
item
.
name
}}
</div>
<div
class=
"box8-main-item-center-footer"
>
{{
item
.
zhiwei
}}
</div>
</div>
<div
class=
"box8-main-item-right"
>
{{
`${item.num
}
项提案 >`
}}
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
div
class
=
"box9"
>
<
div
class
=
"box9-header"
>
<
div
class
=
"box9-header-left"
>
<
div
class
=
"box9-header-icon"
>
<
img
src
=
"./assets/images/box7-header-icon.png"
alt
=
""
/>
<
/div
>
<
div
class
=
"box9-header-title"
>
{{
"关键条款"
}}
<
/div
>
<
/div
>
</
template
>
<div
class=
"box8-main"
:style=
"getEmptyStateStyle(box8HasData)"
>
<el-empty
v-if=
"!box8HasData"
description=
"暂无数据"
:image-size=
"100"
/>
<
template
v-else
>
<div
class=
"box8-desc"
>
• 通过涉华法案
{{
box8Summary
}}
项
</div>
<div
id=
"box8Chart"
class=
"box8-chart"
></div>
</
template
>
</div>
</OverviewCard>
<OverviewCard
class=
"overview-card--single box9"
title=
"关键条款"
:icon=
"box7HeaderIcon"
>
<div
class=
"box9-main"
id=
"wordCloudChart"
></div>
<
/
div
>
</
OverviewCard
>
</div>
</div>
</div>
<div
class=
"home-content-footer"
>
<DivideHeader
id=
"position4"
class=
"divide4"
:titleText=
"'资源库'"
></DivideHeader>
<
div
class
=
"home-content-footer-header"
>
<
div
class
=
"btn-box"
>
<
div
class
=
"btn"
:
class
=
"{ btnActive: activeTabName === cate.name, disabled: index !== 0
}
"
v
-
for
=
"(cate, index) in tabList"
:
key
=
"index"
@
click
=
"index === 0 && handleClickTab(cate)"
>
{{
cate
.
name
}}
<
/div
>
<
/div
>
<
/div
>
<
div
class
=
"home-content-footer-main"
>
<
div
class
=
"left"
>
<
div
class
=
"select-box"
>
<
div
class
=
"select-box-header"
>
<
div
class
=
"icon"
><
/div
>
<
div
class
=
"title"
>
{{
"科技领域"
}}
<
/div
>
<
/div
>
<
div
class
=
"select-main"
>
<
el
-
checkbox
-
group
class
=
"checkbox-group"
v
-
model
=
"activeAreaList"
@
change
=
"handleAreaChange"
>
<
el
-
checkbox
class
=
"filter-checkbox"
label
=
"全部领域"
>
全部领域
<
/el-checkbox
>
<
el
-
checkbox
v
-
for
=
"(area, index) in cateKuList"
:
key
=
"index"
:
label
=
"area.id"
class
=
"filter-checkbox"
>
{{
area
.
name
}}
<
/el-checkbox
>
<
/el-checkbox-group
>
<
/div
>
<
/div
>
<
div
class
=
"select-box"
>
<
div
class
=
"select-box-header"
>
<
div
class
=
"icon"
><
/div
>
<
div
class
=
"title"
>
{{
"党派"
}}
<
/div
>
<
/div
>
<
div
class
=
"select-main"
>
<
el
-
checkbox
-
group
class
=
"checkbox-group"
v
-
model
=
"activeDpList"
@
change
=
"handleDpChange"
>
<
el
-
checkbox
v
-
for
=
"(dp, index) in dpList"
:
key
=
"index"
:
label
=
"dp.id"
class
=
"filter-checkbox"
>
{{
dp
.
name
}}
<
/el-checkbox
>
<
/el-checkbox-group
>
<
/div
>
<
/div
>
<
div
class
=
"select-box"
>
<
div
class
=
"select-box-header"
>
<
div
class
=
"icon"
><
/div
>
<
div
class
=
"title"
>
{{
"议院"
}}
<
/div
>
<
/div
>
<
div
class
=
"select-main"
>
<
el
-
checkbox
-
group
class
=
"checkbox-group"
v
-
model
=
"activeYyList"
@
change
=
"handleYyChange"
>
<
el
-
checkbox
v
-
for
=
"(yy, index) in yyList"
:
key
=
"index"
:
label
=
"yy.id"
class
=
"filter-checkbox"
>
{{
yy
.
name
}}
<
/el-checkbox
>
<
/el-checkbox-group
>
<
/div
>
<
/div
>
<
div
class
=
"select-box"
>
<
div
class
=
"select-box-header"
>
<
div
class
=
"icon"
><
/div
>
<
div
class
=
"title"
>
{{
"发布时间"
}}
<
/div
>
<
/div
>
<
div
class
=
"select-main"
>
<
el
-
checkbox
-
group
class
=
"checkbox-group"
v
-
model
=
"activePubTime"
@
change
=
"handlePubTimeChange"
>
<
el
-
checkbox
v
-
for
=
"(time, index) in pubTime"
:
key
=
"index"
:
label
=
"time.id"
class
=
"filter-checkbox"
>
{{
time
.
name
}}
<
/el-checkbox
>
<
/el-checkbox-group
>
<
/div
>
<
/div
>
<
/div
>
<
div
class
=
"right"
>
<
div
class
=
"right-header"
>
<
div
class
=
"right-header-box"
>
<
el
-
select
v
-
model
=
"footerSelect1"
placeholder
=
"选择委员会"
style
=
"width: 240px"
@
change
=
"handleFooterSelect1Change"
>
<
el
-
option
v
-
for
=
"item in postOrgList"
:
key
=
"item.departmentId"
:
label
=
"item.departmentName"
:
value
=
"item.departmentId"
/>
<
/el-select
>
<
/div
>
<
div
class
=
"right-header-box"
>
<
el
-
select
v
-
model
=
"footerSelect2"
placeholder
=
"选择提出议员"
style
=
"width: 240px"
@
change
=
"handleFooterSelect2Change"
>
<
el
-
option
v
-
for
=
"item in postMemberList"
:
key
=
"item.memberId"
:
label
=
"item.memberName"
:
value
=
"item.memberId"
/>
<
/el-select
>
<
/div
>
<
div
class
=
"right-header-box"
style
=
"margin-left: auto"
>
<
el
-
select
v
-
model
=
"releaseTime"
placeholder
=
"选择排序方式"
style
=
"width: 120px"
@
change
=
"handlePxChange"
>
<
template
#
prefix
>
<
div
style
=
"display: flex; align-items: center; height: 100%"
>
<
img
:
src
=
"desc"
style
=
"width: 14px; height: 14px"
/>
<
/div
>
<
/template
>
<
el
-
option
v
-
for
=
"item in releaseTimeList"
:
key
=
"item.value"
:
label
=
"item.label"
:
value
=
"item.value"
/>
<
/el-select
>
<
/div
>
<
/div
>
<
div
class
=
"right-main"
v
-
loading
=
"loading"
>
<
div
class
=
"right-main-box"
v
-
for
=
"(item, index) in bills"
:
key
=
"index"
>
<
div
class
=
"header"
>
<
div
class
=
"title"
@
click
=
"handleClickToDetailO(item)"
:
title
=
"item.name"
>
{{
item
.
name
}}
<
/div
>
<
div
class
=
"en-title"
:
title
=
"item.eName"
>
{{
item
.
eName
}}
<
/div
>
<
/div
>
<
div
class
=
"main"
>
<
div
class
=
"item"
>
<
div
class
=
"item-left"
>
{{
"提案人:"
}}
<
/div
>
<
div
class
=
"item-right"
>
{{
item
.
tcr
}}
<
/div
>
<
/div
>
<
div
class
=
"item"
>
<
div
class
=
"item-left"
>
{{
"委员会:"
}}
<
/div
>
<
div
class
=
"item-right"
>
{{
item
.
wyh
}}
<
/div
>
<
/div
>
<
div
class
=
"item"
>
<
div
class
=
"item-left"
>
{{
"相关领域:"
}}
<
/div
>
<
div
class
=
"item-right1"
>
<
div
class
=
"tag"
v
-
for
=
"(val, idx) in item.areaList"
:
key
=
"idx"
>
{{
val
}}
<
/div
>
<
/div
>
<
/div
>
<
div
class
=
"item"
>
<
div
class
=
"item-left"
>
{{
"最新动议:"
}}
<
/div
>
<
div
class
=
"item-right"
>
<
CommonPrompt
:
content
=
"item.zxdy"
/>
<
/div
>
<
/div
>
<
div
class
=
"item"
>
<
div
class
=
"item-left"
>
{{
"法案进展:"
}}
<
/div
>
<
div
class
=
"item-right2"
>
<
div
class
=
"tag"
v
-
for
=
"(val, idx) in [...item.progress].reverse()"
:
key
=
"idx"
:
style
=
"{ zIndex: item.progress.length - idx
}
"
>
{{
val
}}
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
div
class
=
"right-footer"
>
<
div
class
=
"footer-left"
>
{{
`共 ${total
}
项`
}}
<
/div
>
<
div
class
=
"footer-right"
>
<
el
-
pagination
@
current
-
change
=
"handleCurrentChange"
:
page
-
size
=
"pageSize"
:
current
-
page
=
"currentPage"
background
layout
=
"prev, pager, next"
:
total
=
"total"
/>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<
/div
>
<ResourceLibrarySection
:on-click-to-detail=
"handleClickToDetailO"
:on-after-page-change=
"handlePageChange"
/>
</div>
</div>
</div>
...
...
@@ -444,16 +186,15 @@ import {
getBillOverviewKeyTK
,
getBillCount
,
getBillPostOrg
,
get
MemberProposal
,
get
BillProcess
,
getNews
,
getRemarks
,
getPostOrgList
,
getPostMemberList
,
getBills
getRemarks
}
from
"@/api/bill/billHome"
;
import
{
getPersonSummaryInfo
}
from
"@/api/common/index"
;
import
DivideHeader
from
"@/components/DivideHeader.vue"
;
import
CommonPrompt
from
"../commonPrompt/index.vue"
;
import
overviewMainBox
from
"@/components/base/boxBackground/overviewMainBox.vue"
;
import
OverviewCard
from
"./OverviewCard.vue"
;
import
ResourceLibrarySection
from
"./ResourceLibrarySection.vue"
;
import
{
useContainerScroll
}
from
"@/hooks/useScrollShow"
;
import
getMultiLineChart
from
"./utils/multiLineChart"
;
...
...
@@ -461,34 +202,15 @@ import getWordCloudChart from "./utils/worldCloudChart";
import
getPieChart
from
"./utils/piechart"
;
import
getDoublePieChart
from
"./utils/doublePieChart"
;
import
desc
from
"./assets/icons/icon-desc.png"
;
import
box5HeaderIcon
from
"./assets/images/box5-header-icon.png"
;
import
box6HeaderIcon
from
"./assets/images/box6-header-icon.png"
;
import
box7HeaderIcon
from
"./assets/images/box7-header-icon.png"
;
import
Cyy
from
"@/assets/icons/cyy.png"
;
import
Ghd
from
"@/assets/icons/ghd.png"
;
import
Mzd
from
"@/assets/icons/mzd.png"
;
import
{
ElMessage
}
from
"element-plus"
;
// 处理图片代理
const
getProxyUrl
=
url
=>
{
if
(
!
url
)
return
""
;
const
urlStr
=
String
(
url
);
// 排除非 http 开头(相对路径)、已经是代理链接、或者是本地链接
if
(
!
urlStr
.
startsWith
(
"http"
)
||
urlStr
.
includes
(
"images.weserv.nl"
)
||
urlStr
.
includes
(
"localhost"
)
||
urlStr
.
includes
(
"127.0.0.1"
)
)
{
return
url
;
}
// 移除协议头 http:// 或 https://
const
cleanUrl
=
urlStr
.
replace
(
/^https
?
:
\/\/
/i
,
""
);
return
`https://images.weserv.nl/?url=${encodeURIComponent(cleanUrl)
}
`
;
}
;
// 跳转人物主页
const
handleCl
ci
kToCharacter
=
async
(
id
,
name
)
=>
{
const
handleCl
ic
kToCharacter
=
async
(
id
,
name
)
=>
{
const
personTypeList
=
JSON
.
parse
(
window
.
sessionStorage
.
getItem
(
"personTypeList"
));
let
type
=
0
;
...
...
@@ -1143,29 +865,189 @@ watch(box9selectetedTime, () => {
handleBox9Data
();
});
const
box8Data
=
ref
([]);
const
box8HasData
=
ref
(
true
);
const
box8Summary
=
ref
(
0
);
let
box8ChartInstance
=
null
;
const
box8MockDataByYear
=
{
"2025"
:
{
passCount
:
19
,
stages
:
[
{
name
:
"已提案"
,
count
:
24
},
{
name
:
"众议院通过"
,
count
:
20
},
{
name
:
"众议院不通过"
,
count
:
25
},
{
name
:
"解决分歧"
,
count
:
23
},
{
name
:
"参议院通过"
,
count
:
26
},
{
name
:
"总统否决"
,
count
:
48
},
{
name
:
"已立法"
,
count
:
19
}
]
}
};
const
getBox8ChartOption
=
stageList
=>
{
const
axisMax
=
100
;
const
countList
=
stageList
.
map
(
item
=>
item
.
count
||
0
);
const
totalCount
=
countList
.
reduce
((
sum
,
cur
)
=>
sum
+
cur
,
0
);
const
safeTotal
=
totalCount
>
0
?
totalCount
:
1
;
const
rawWidths
=
countList
.
map
(
count
=>
(
count
/
safeTotal
)
*
axisMax
);
const
markerData
=
rawWidths
.
map
((
width
,
index
)
=>
{
if
(
index
===
rawWidths
.
length
-
1
)
{
const
used
=
rawWidths
.
slice
(
0
,
index
).
reduce
((
sum
,
cur
)
=>
sum
+
Number
(
cur
.
toFixed
(
4
)),
0
);
return
Number
(
Math
.
max
(
axisMax
-
used
,
0
).
toFixed
(
4
));
}
return
Number
(
width
.
toFixed
(
4
));
});
let
cumulative
=
0
;
const
offsetData
=
markerData
.
map
(
width
=>
{
const
start
=
Number
(
cumulative
.
toFixed
(
4
));
cumulative
+=
width
;
return
start
;
});
const
trackData
=
stageList
.
map
(()
=>
axisMax
);
return
{
tooltip
:
{
trigger
:
"item"
,
confine
:
true
,
backgroundColor
:
"rgba(34, 44, 58, 0.92)"
,
borderWidth
:
0
,
textStyle
:
{
color
:
"#fff"
,
fontSize
:
13
},
formatter
:
params
=>
{
const
item
=
stageList
[
params
.
dataIndex
];
if
(
!
item
)
return
""
;
return
`
${
item
.
name
}
<br/>
${
item
.
count
}
项`
;
}
},
grid
:
{
left
:
118
,
right
:
60
,
top
:
6
,
bottom
:
6
},
xAxis
:
{
type
:
"value"
,
min
:
0
,
max
:
axisMax
,
show
:
false
},
yAxis
:
{
type
:
"category"
,
inverse
:
true
,
data
:
stageList
.
map
(
item
=>
item
.
name
),
axisTick
:
{
show
:
false
},
axisLine
:
{
show
:
false
},
axisLabel
:
{
color
:
"#3b414b"
,
fontSize
:
16
}
},
series
:
[
{
type
:
"bar"
,
barWidth
:
32
,
barGap
:
"-100%"
,
silent
:
true
,
data
:
trackData
,
itemStyle
:
{
color
:
params
=>
(
params
.
dataIndex
===
stageList
.
length
-
1
?
"rgba(206, 79, 81, 0.1)"
:
"rgb(246, 250, 255)"
)
},
label
:
{
show
:
true
,
position
:
"right"
,
formatter
:
params
=>
`
${
countList
[
params
.
dataIndex
]}
项`
,
color
:
params
=>
(
params
.
dataIndex
===
stageList
.
length
-
1
?
"rgb(206, 79, 81)"
:
"#3b414b"
),
fontSize
:
36
/
2
,
fontWeight
:
params
=>
(
params
.
dataIndex
===
stageList
.
length
-
1
?
700
:
400
)
}
},
{
type
:
"bar"
,
stack
:
"progress"
,
barWidth
:
32
,
silent
:
true
,
data
:
offsetData
,
itemStyle
:
{
color
:
"transparent"
}
},
{
type
:
"bar"
,
stack
:
"progress"
,
barWidth
:
32
,
data
:
markerData
,
itemStyle
:
{
color
:
params
=>
(
params
.
dataIndex
===
stageList
.
length
-
1
?
"rgb(206, 79, 81)"
:
"rgb(5, 95, 194)"
)
},
emphasis
:
{
disabled
:
false
,
itemStyle
:
{
borderColor
:
"rgba(255, 255, 255, 0.9)"
,
borderWidth
:
2
,
shadowBlur
:
10
,
shadowColor
:
"rgba(5, 95, 194, 0.35)"
}
}
}
]
};
};
const
handleBox8Data
=
async
()
=>
{
const
stageOrder
=
[
"提案"
,
"众议院通过"
,
"众议院不通过"
,
"分歧已解决"
,
"参议院通过"
,
"总统否决或未签署"
,
"完成立法"
];
const
stageNameMap
=
{
提案
:
"已提案"
,
众议院通过
:
"众议院通过"
,
众议院不通过
:
"众议院不通过"
,
分歧已解决
:
"解决分歧"
,
参议院通过
:
"参议院通过"
,
"总统否决或未签署"
:
"总统否决"
,
完成立法
:
"已立法"
};
try
{
const
res
=
await
getMemberProposal
({
year
:
box8selectetedTime
.
value
}
);
console
.
log
(
"关键议员提案"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
box8Data
.
value
=
res
.
data
.
map
(
item
=>
({
memberId
:
item
.
memberId
,
name
:
item
.
memberName
,
zhiwei
:
item
.
position
,
img
:
item
.
imageUrl
,
num
:
item
.
countProposal
,
dangpai
:
Cyy
,
yuan
:
item
.
position
===
"Democratic"
?
Mzd
:
Ghd
const
res
=
await
getBillProcess
({
year
:
box8selectetedTime
.
value
});
console
.
log
(
"涉华法案进展分布"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
&&
res
.
data
.
length
>
0
)
{
const
countMap
=
new
Map
(
res
.
data
.
map
(
item
=>
[
item
.
progressName
,
item
.
countBill
]));
const
stages
=
stageOrder
.
map
(
name
=>
({
name
:
stageNameMap
[
name
],
count
:
countMap
.
get
(
name
)
||
0
}));
box8HasData
.
value
=
true
;
box8Summary
.
value
=
countMap
.
get
(
"完成立法"
)
||
0
;
await
nextTick
();
const
box8Chart
=
getBox8ChartOption
(
stages
);
box8ChartInstance
=
setChart
(
box8Chart
,
"box8Chart"
);
}
else
{
// 接口异常(如500)时,清空图表数据以避免报错或显示错误信息
box8Data
.
value
=
[];
const
data
=
box8MockDataByYear
[
box8selectetedTime
.
value
];
if
(
data
&&
data
.
stages
&&
data
.
stages
.
length
>
0
)
{
box8HasData
.
value
=
true
;
box8Summary
.
value
=
data
.
passCount
||
0
;
await
nextTick
();
const
box8Chart
=
getBox8ChartOption
(
data
.
stages
);
box8ChartInstance
=
setChart
(
box8Chart
,
"box8Chart"
);
}
else
{
box8HasData
.
value
=
false
;
box8Summary
.
value
=
0
;
setChart
({},
"box8Chart"
);
}
}
}
catch
(
error
)
{
console
.
error
(
"获取关键议员提案失败"
,
error
);
box8Data
.
value
=
[];
console
.
error
(
"获取涉华法案进展分布失败"
,
error
);
const
data
=
box8MockDataByYear
[
box8selectetedTime
.
value
];
if
(
data
&&
data
.
stages
&&
data
.
stages
.
length
>
0
)
{
box8HasData
.
value
=
true
;
box8Summary
.
value
=
data
.
passCount
||
0
;
await
nextTick
();
const
box8Chart
=
getBox8ChartOption
(
data
.
stages
);
box8ChartInstance
=
setChart
(
box8Chart
,
"box8Chart"
);
}
else
{
box8HasData
.
value
=
false
;
box8Summary
.
value
=
0
;
setChart
({},
"box8Chart"
);
}
}
};
...
...
@@ -1337,6 +1219,7 @@ const footerSelect2 = ref("全部提出议员");
// ]);
const
handleResize
=
()
=>
{
box8ChartInstance
&&
box8ChartInstance
.
resize
();
box9ChartInstance
&&
box9ChartInstance
.
resize
();
};
...
...
@@ -2449,510 +2332,65 @@ onUnmounted(() => {
margin-bottom
:
36px
;
}
$overview-card-gap
:
16px
;
$overview-single-width
:
calc
((
100%
-
#{
$overview-card-gap
}
*
2
)
/
3
);
.center-footer
{
margin-top
:
21px
;
height
:
450
px
;
display
:
flex
;
.
box5
{
width
:
1059
px
;
height
:
450
px
;
border
-
radius
:
10
px
;
box
-
shadow
:
0
px
0
px
15
px
0
px
rgba
(
22
,
119
,
255
,
0.1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
position
:
relative
;
.
box5
-
header
{
height
:
53
px
;
border
-
bottom
:
1
px
solid
rgba
(
240
,
242
,
244
,
1
);
margin
:
0
auto
;
display
:
flex
;
justify
-
content
:
space
-
between
;
padding
:
0
27
px
0
22
px
;
.
box5
-
header
-
left
{
display
:
flex
;
.
box5
-
header
-
icon
{
margin
-
top
:
16
px
;
width
:
19
px
;
height
:
19
px
;
img
{
width
:
100
%
;
height
:
100
%
;
}
}
.
box5
-
header
-
title
{
margin
-
top
:
11
px
;
margin
-
left
:
19
px
;
height
:
26
px
;
color
:
rgba
(
20
,
89
,
187
,
1
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
20
px
;
font
-
weight
:
700
;
line
-
height
:
26
px
;
}
}
.
box5
-
header
-
right
{
display
:
flex
;
justify
-
content
:
flex
-
end
;
gap
:
8
px
;
height
:
24
px
;
margin
-
top
:
12
px
;
.
header
-
right
-
icon
{
margin
-
top
:
4
px
;
width
:
14
px
;
height
:
16
px
;
img
{
width
:
100
%
;
height
:
100
%
;
}
}
.
header
-
right
-
text
{
color
:
rgba
(
132
,
136
,
142
,
1
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
16
px
;
font
-
weight
:
400
;
line
-
height
:
24
px
;
}
}
}
.
box5
-
main
{
height
:
397
px
;
padding
:
8
px
16
px
8
px
16
px
;
}
}
.
box6
{
margin
-
left
:
20
px
;
width
:
521
px
;
height
:
450
px
;
border
-
radius
:
10
px
;
box
-
shadow
:
0
px
0
px
15
px
0
px
rgba
(
22
,
119
,
255
,
0.1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
.
box6
-
header
{
width
:
521
px
;
height
:
53
px
;
border
-
bottom
:
1
px
solid
rgba
(
240
,
242
,
244
,
1
);
display
:
flex
;
box
-
sizing
:
border
-
box
;
padding
-
left
:
22
px
;
.
header
-
icon
{
margin
-
top
:
15
px
;
width
:
20
px
;
height
:
20
px
;
img
{
width
:
100
%
;
height
:
100
%
;
}
}
.
header
-
title
{
margin
-
top
:
11
px
;
margin
-
left
:
18
px
;
height
:
26
px
;
color
:
var
(
--
color
-
main
-
active
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
20
px
;
font
-
weight
:
700
;
line
-
height
:
26
px
;
}
.
box6
-
header
-
right
{
margin
-
left
:
130
px
;
display
:
flex
;
justify
-
content
:
flex
-
end
;
gap
:
8
px
;
height
:
24
px
;
margin
-
top
:
12
px
;
.
header
-
right
-
icon
{
margin
-
top
:
4
px
;
width
:
14
px
;
height
:
16
px
;
img
{
width
:
100
%
;
height
:
100
%
;
}
}
.
header
-
right
-
text
{
color
:
rgba
(
132
,
136
,
142
,
1
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
16
px
;
font
-
weight
:
400
;
line
-
height
:
24
px
;
}
}
}
.
box6
-
main
{
width
:
100
%
;
height
:
calc
(
100
%
-
53
px
);
}
}
gap
:
$overview-card-gap
;
width
:
100%
;
}
.center-footer1
{
display
:
flex
;
gap
:
16
px
;
gap
:
$overview-card-gap
;
margin-top
:
16px
;
width
:
100%
;
}
.
box7
{
width
:
520
px
;
height
:
450
px
;
box
-
sizing
:
border
-
box
;
border
:
1
px
solid
rgba
(
234
,
236
,
238
,
1
);
border
-
radius
:
10
px
;
box
-
shadow
:
0
px
0
px
20
px
0
px
rgba
(
25
,
69
,
130
,
0.1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
.
box7
-
header
{
height
:
53
px
;
border
-
bottom
:
1
px
solid
rgba
(
240
,
242
,
244
,
1
);
margin
:
0
auto
;
display
:
flex
;
justify
-
content
:
space
-
between
;
padding
:
0
27
px
0
22
px
;
.
box7
-
header
-
left
{
display
:
flex
;
.
box7
-
header
-
icon
{
margin
-
top
:
16
px
;
width
:
19
px
;
height
:
19
px
;
img
{
width
:
100
%
;
height
:
100
%
;
}
}
.
box7
-
header
-
title
{
margin
-
top
:
11
px
;
margin
-
left
:
19
px
;
height
:
26
px
;
color
:
rgba
(
20
,
89
,
187
,
1
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
20
px
;
font
-
weight
:
700
;
line
-
height
:
26
px
;
}
}
.
box7
-
header
-
right
{
display
:
flex
;
justify
-
content
:
flex
-
end
;
gap
:
8
px
;
height
:
24
px
;
margin
-
top
:
12
px
;
.
header
-
right
-
icon
{
margin
-
top
:
4
px
;
width
:
14
px
;
height
:
16
px
;
.overview-card--single
{
width
:
$overview-single-width
;
}
img
{
width
:
100
%
;
height
:
100
%
;
}
}
.overview-card--double
{
width
:
calc
(
#{
$overview-single-width
}
*
2
+
#{
$overview-card-gap
}
);
}
.box5-main
,
.box6-main
,
.box7-main
,
.box9-main
{
height
:
100%
;
box-sizing
:
border-box
;
}
.
header
-
right
-
text
{
color
:
rgba
(
132
,
136
,
142
,
1
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
16
px
;
font
-
weight
:
400
;
line
-
height
:
24
px
;
}
}
}
.box5-main
{
padding
:
8px
16px
;
}
.
box
-
center
{
height
:
45
px
;
padding
-
right
:
20
px
;
display
:
flex
;
align
-
items
:
center
;
justify
-
content
:
flex
-
end
;
}
.box8-main
{
height
:
100%
;
box-sizing
:
border-box
;
padding
:
12px
20px
18px
;
.
box7
-
main
{
height
:
390
px
;
}
.box8-desc
{
height
:
24px
;
line-height
:
24px
;
color
:
rgb
(
206
,
79
,
81
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
700
;
}
.
box8
{
width
:
527
px
;
height
:
450
px
;
box
-
sizing
:
border
-
box
;
border
:
1
px
solid
rgba
(
234
,
236
,
238
,
1
);
border
-
radius
:
10
px
;
box
-
shadow
:
0
px
0
px
20
px
0
px
rgba
(
25
,
69
,
130
,
0.1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
.
box8
-
header
{
height
:
53
px
;
border
-
bottom
:
1
px
solid
rgba
(
240
,
242
,
244
,
1
);
margin
:
0
auto
;
display
:
flex
;
justify
-
content
:
space
-
between
;
padding
:
0
27
px
0
22
px
;
.
box8
-
header
-
left
{
display
:
flex
;
.
box8
-
header
-
icon
{
margin
-
top
:
16
px
;
width
:
19
px
;
height
:
19
px
;
img
{
width
:
100
%
;
height
:
100
%
;
}
}
.
box8
-
header
-
title
{
margin
-
top
:
11
px
;
margin
-
left
:
19
px
;
height
:
26
px
;
color
:
rgba
(
20
,
89
,
187
,
1
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
20
px
;
font
-
weight
:
700
;
line
-
height
:
26
px
;
}
}
.
box8
-
header
-
right
{
display
:
flex
;
justify
-
content
:
flex
-
end
;
gap
:
8
px
;
height
:
24
px
;
margin
-
top
:
12
px
;
.
header
-
right
-
icon
{
margin
-
top
:
4
px
;
width
:
14
px
;
height
:
16
px
;
img
{
width
:
100
%
;
height
:
100
%
;
}
}
.
header
-
right
-
text
{
color
:
rgba
(
132
,
136
,
142
,
1
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
16
px
;
font
-
weight
:
400
;
line
-
height
:
24
px
;
}
}
}
.
box8
-
main
{
height
:
380
px
;
overflow
:
hidden
;
padding
:
20
px
;
.
box8
-
main
-
item
{
// margin: 0 auto;
width
:
478
px
;
height
:
51
px
;
margin
-
bottom
:
20
px
;
display
:
flex
;
align
-
items
:
center
;
position
:
relative
;
// padding: 0 10px;
cursor
:
pointer
;
&
:
hover
{
background
:
var
(
--
color
-
bg
-
hover
);
}
.
box8
-
main
-
item
-
left
{
position
:
relative
;
width
:
42
px
;
height
:
42
px
;
.
left
-
img
{
width
:
42
px
;
height
:
42
px
;
border
-
radius
:
50
%
;
}
.
left
-
icon1
{
position
:
absolute
;
left
:
2
px
;
bottom
:
-
6
px
;
width
:
20
px
;
height
:
20
px
;
border
-
radius
:
10
px
;
background
:
(
255
,
255
,
255
,
0.8
);
box
-
sizing
:
border
-
box
;
padding
:
2
px
;
img
{
width
:
100
%
;
height
:
100
%
;
}
}
.
left
-
icon2
{
position
:
absolute
;
right
:
2
px
;
bottom
:
-
6
px
;
width
:
20
px
;
height
:
20
px
;
border
-
radius
:
10
px
;
background
:
(
255
,
255
,
255
,
0.8
);
box
-
sizing
:
border
-
box
;
padding
:
2
px
;
img
{
width
:
100
%
;
height
:
100
%
;
}
}
}
.
box8
-
main
-
item
-
center
{
height
:
48
px
;
margin
-
left
:
12
px
;
.
box8
-
main
-
item
-
center
-
top
{
height
:
24
px
;
color
:
rgba
(
59
,
65
,
75
,
1
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
16
px
;
font
-
weight
:
700
;
line
-
height
:
24
px
;
}
.
box8
-
main
-
item
-
center
-
footer
{
height
:
24
px
;
color
:
rgba
(
95
,
101
,
108
,
1
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
16
px
;
font
-
weight
:
400
;
line
-
height
:
24
px
;
}
}
.
box8
-
main
-
item
-
right
{
position
:
absolute
;
top
:
0
;
right
:
10
px
;
height
:
51
px
;
text
-
align
:
right
;
color
:
rgba
(
95
,
101
,
108
,
1
);
font
-
family
:
"Microsoft YaHei"
;
font
-
size
:
16
px
;
font
-
weight
:
400
;
line
-
height
:
51
px
;
}
}
}
.box8-chart
{
width
:
100%
;
height
:
calc
(
100%
-
30px
);
cursor
:
pointer
;
}
}
.
box9
{
width
:
521
px
;
height
:
450
px
;
box
-
sizing
:
border
-
box
;
border
:
1
px
solid
rgba
(
234
,
236
,
238
,
1
);
border
-
radius
:
10
px
;
box
-
shadow
:
0
px
0
px
20
px
0
px
rgba
(
25
,
69
,
130
,
0.1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
.
box9
-
header
{
height
:
53
px
;
border
-
bottom
:
1
px
solid
rgba
(
240
,
242
,
244
,
1
);
margin
:
0
auto
;
display
:
flex
;
justify
-
content
:
space
-
between
;
padding
:
0
27
px
0
22
px
;
.
box9
-
header
-
left
{
display
:
flex
;
.
box9
-
header
-
icon
{
margin
-
top
:
16
px
;
width
:
19
px
;
height
:
19
px
;
img
{
width
:
100
%
;
height
:
100
%
;
}
}
.
box9
-
header
-
title
{
margin
-
top
:
11
px
;
margin
-
left
:
19
px
;
height
:
26
px
;
color
:
rgba
(
20
,
89
,
187
,
1
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
20
px
;
font
-
weight
:
700
;
line
-
height
:
26
px
;
}
}
.
box9
-
header
-
right
{
display
:
flex
;
justify
-
content
:
flex
-
end
;
gap
:
8
px
;
height
:
24
px
;
margin
-
top
:
12
px
;
.
header
-
right
-
icon
{
margin
-
top
:
4
px
;
width
:
14
px
;
height
:
16
px
;
img
{
width
:
100
%
;
height
:
100
%
;
}
}
.
header
-
right
-
text
{
color
:
rgba
(
132
,
136
,
142
,
1
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
16
px
;
font
-
weight
:
400
;
line
-
height
:
24
px
;
}
}
}
.
box
-
center
{
height
:
45
px
;
padding
-
right
:
20
px
;
display
:
flex
;
align
-
items
:
center
;
justify
-
content
:
flex
-
end
;
}
.
box9
-
main
{
height
:
380
px
;
padding
:
10
px
20
px
;
}
}
.box9-main
{
padding
:
10px
20px
;
}
}
}
...
...
vite.config.js
浏览文件 @
a4b931c9
...
...
@@ -89,8 +89,13 @@ export default defineConfig({
changeOrigin
:
true
,
rewrite
:
(
path
)
=>
path
.
replace
(
/^
\/
temporarySearch/
,
''
)
},
'^/bill(?:/|$)'
:
{
target
:
'http://172.20.10.3:28080/'
,
changeOrigin
:
true
,
rewrite
:
(
path
)
=>
path
.
replace
(
/^
\/
bill/
,
''
)
},
'/pdfSse'
:
{
target
:
'http://8.140.26.4:10020/'
,
target
:
'http://8.140.26.4:10020/'
,
changeOrigin
:
true
,
rewrite
:
(
path
)
=>
path
.
replace
(
/^
\/
pdfSse/
,
''
),
configure
:
(
proxy
)
=>
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论