Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
R
risk-monitor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蔡建
risk-monitor
Commits
8d534f1e
提交
8d534f1e
authored
4月 02, 2026
作者:
coderBryanFu
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'pre' of
http://8.140.26.4:10003/caijian/risk-monitor
into fk-dev
上级
3f2140f0
3261b013
流水线
#315
已通过 于阶段
in 1 分 37 秒
变更
39
流水线
1
显示空白字符变更
内嵌
并排
正在显示
39 个修改的文件
包含
3028 行增加
和
2197 行删除
+3028
-2197
package-lock.json
package-lock.json
+232
-169
index.js
src/api/marketAccessRestrictions/index.js
+10
-2
overview.js
src/api/scientificFunding/overview.js
+15
-1
newOriginal.vue
src/components/base/DecreeOriginal/newOriginal.vue
+463
-0
index.js
src/router/index.js
+3
-1
decree.js
src/router/modules/decree.js
+2
-1
bill-tokens.scss
src/styles/bill-tokens.scss
+35
-0
BILL_LAYOUT_UNIFICATION_PLAN.md
src/views/bill/BILL_LAYOUT_UNIFICATION_PLAN.md
+201
-0
index.vue
src/views/bill/background/index.vue
+36
-10
BillHeader.vue
src/views/bill/billLayout/components/BillHeader.vue
+6
-4
index.vue
src/views/bill/billLayout/index.vue
+34
-5
BillPageShell.vue
src/views/bill/components/layout/BillPageShell.vue
+51
-0
BillPanel.vue
src/views/bill/components/layout/BillPanel.vue
+117
-0
BillTwoColumn.vue
src/views/bill/components/layout/BillTwoColumn.vue
+108
-0
index.js
src/views/bill/components/layout/index.js
+9
-0
index.vue
src/views/bill/deepDig/processAnalysis/index.vue
+9
-6
index.vue
src/views/bill/deepDig/processOverview/index.vue
+6
-11
index.vue
src/views/bill/introdoction/index.vue
+18
-7
index.vue
src/views/bill/template/index.vue
+112
-112
index.vue
src/views/decree/decreeOriginal/index.vue
+6
-16
RelatedEvent.vue
src/views/marketAccessRestrictions/com/RelatedEvent.vue
+60
-7
SurveyAffiche.vue
src/views/marketAccessRestrictions/com/SurveyAffiche.vue
+71
-0
SurveyHistory.vue
src/views/marketAccessRestrictions/com/SurveyHistory.vue
+4
-6
index.vue
...views/marketAccessRestrictions/marketAccessHome/index.vue
+161
-399
index.vue
...tAccessRestrictions/marketAccessLayout/case/232/index.vue
+82
-123
index.vue
...tAccessRestrictions/marketAccessLayout/case/301/index.vue
+86
-151
index.vue
...tAccessRestrictions/marketAccessLayout/case/337/index.vue
+104
-159
index.vue
...ccessRestrictions/singleCaseLayout/overview/232/index.vue
+18
-18
index.vue
...ccessRestrictions/singleCaseLayout/overview/301/index.vue
+75
-430
index.vue
...ccessRestrictions/singleCaseLayout/overview/337/index.vue
+19
-164
index.vue
src/views/scientificFunding/components/askPage/index.vue
+8
-3
icon-black.png
...cientificFunding/components/dataNew/assets/icon-black.png
+0
-0
index.vue
src/views/scientificFunding/components/dataNew/index.vue
+28
-47
index.vue
src/views/scientificFunding/components/dataSub/index.vue
+582
-73
index.vue
src/views/scientificFunding/components/resLib/index.vue
+186
-243
index.vue
src/views/scientificFunding/index.vue
+25
-15
index.vue
src/views/thinkTank/CongressHearingView/index.vue
+2
-1
index.vue
...k/ThinkTankDetail/thinkDynamics/CongressHearing/index.vue
+29
-7
ThinkTankCongressHearingOverview.vue
...thinkTank/components/ThinkTankCongressHearingOverview.vue
+15
-6
没有找到文件。
package-lock.json
浏览文件 @
8d534f1e
...
...
@@ -1750,9 +1750,9 @@
}
},
"node_modules/@rollup/rollup-android-arm-eabi"
:
{
"version"
:
"4.
50.2
"
,
"resolved"
:
"https://registry.npm
mirror.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.50.2
.tgz"
,
"integrity"
:
"sha512-
uLN8NAiFVIRKX9ZQha8wy6UUs06UNSZ32xj6giK/rmMXAgKahwExvK6SsmgU5/brh4w/nSgj8e0k3c1HBQpa0
A=="
,
"version"
:
"4.
60.1
"
,
"resolved"
:
"https://registry.npm
js.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.1
.tgz"
,
"integrity"
:
"sha512-
d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOow
A=="
,
"cpu"
:
[
"arm"
],
...
...
@@ -1764,9 +1764,9 @@
]
},
"node_modules/@rollup/rollup-android-arm64"
:
{
"version"
:
"4.
50.2
"
,
"resolved"
:
"https://registry.npm
mirror.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.50.2
.tgz"
,
"integrity"
:
"sha512-
oEouqQk2/zxxj22PNcGSskya+3kV0ZKH+nQxuCCOGJ4oTXBdNTbv+f/E3c74cNLeMO1S5wVWacSws10TTSB77g
=="
,
"version"
:
"4.
60.1
"
,
"resolved"
:
"https://registry.npm
js.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.1
.tgz"
,
"integrity"
:
"sha512-
YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA
=="
,
"cpu"
:
[
"arm64"
],
...
...
@@ -1778,9 +1778,9 @@
]
},
"node_modules/@rollup/rollup-darwin-arm64"
:
{
"version"
:
"4.
50.2
"
,
"resolved"
:
"https://registry.npm
mirror.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.50.2
.tgz"
,
"integrity"
:
"sha512-
OZuTVTpj3CDSIxmPgGH8en/XtirV5nfljHZ3wrNwvgkT5DQLhIKAeuFSiwtbMto6oVexV0k1F1zqURPKf5rI1Q
=="
,
"version"
:
"4.
60.1
"
,
"resolved"
:
"https://registry.npm
js.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.1
.tgz"
,
"integrity"
:
"sha512-
mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw
=="
,
"cpu"
:
[
"arm64"
],
...
...
@@ -1792,9 +1792,9 @@
]
},
"node_modules/@rollup/rollup-darwin-x64"
:
{
"version"
:
"4.
50.2
"
,
"resolved"
:
"https://registry.npm
mirror.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.50.2
.tgz"
,
"integrity"
:
"sha512-
Wa/Wn8RFkIkr1vy1k1PB//VYhLnlnn5eaJkfTQKivirOvzu5uVd2It01ukeQstMursuz7S1bU+8WW+1UPXpa8A
=="
,
"version"
:
"4.
60.1
"
,
"resolved"
:
"https://registry.npm
js.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.1
.tgz"
,
"integrity"
:
"sha512-
haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew
=="
,
"cpu"
:
[
"x64"
],
...
...
@@ -1806,9 +1806,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-arm64"
:
{
"version"
:
"4.
50.2
"
,
"resolved"
:
"https://registry.npm
mirror.com/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.50.2
.tgz"
,
"integrity"
:
"sha512-
QkzxvH3kYN9J1w7D1A+yIMdI1pPekD+pWx7G5rXgnIlQ1TVYVC6hLl7SOV9pi5q9uIDF9AuIGkuzcbF7+fAho
w=="
,
"version"
:
"4.
60.1
"
,
"resolved"
:
"https://registry.npm
js.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.1
.tgz"
,
"integrity"
:
"sha512-
czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6
w=="
,
"cpu"
:
[
"arm64"
],
...
...
@@ -1820,9 +1820,9 @@
]
},
"node_modules/@rollup/rollup-freebsd-x64"
:
{
"version"
:
"4.
50.2
"
,
"resolved"
:
"https://registry.npm
mirror.com/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.50.2
.tgz"
,
"integrity"
:
"sha512-
dkYXB0c2XAS3a3jmyDkX4Jk0m7gWLFzq1C3qUnJJ38AyxIF5G/dyS4N9B30nvFseCfgtCEdbYFhk0ChoCGxPo
g=="
,
"version"
:
"4.
60.1
"
,
"resolved"
:
"https://registry.npm
js.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.1
.tgz"
,
"integrity"
:
"sha512-
KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+
g=="
,
"cpu"
:
[
"x64"
],
...
...
@@ -1834,9 +1834,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-gnueabihf"
:
{
"version"
:
"4.
50.2
"
,
"resolved"
:
"https://registry.npm
mirror.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.50.2
.tgz"
,
"integrity"
:
"sha512-
9VlPY/BN3AgbukfVHAB8zNFWB/lKEuvzRo1NKev0Po8sYFKx0i+AQlCYftgEjcL43F2h9Ui1ZSdVBc4En/sP2w
=="
,
"version"
:
"4.
60.1
"
,
"resolved"
:
"https://registry.npm
js.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.1
.tgz"
,
"integrity"
:
"sha512-
L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g
=="
,
"cpu"
:
[
"arm"
],
...
...
@@ -1848,9 +1848,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm-musleabihf"
:
{
"version"
:
"4.
50.2
"
,
"resolved"
:
"https://registry.npm
mirror.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.50.2
.tgz"
,
"integrity"
:
"sha512-
+GdKWOvsifaYNlIVf07QYan1J5F141+vGm5/Y8b9uCZnG/nxoGqgCmR24mv0koIWWuqvFYnbURRqw1lv7IBINw
=="
,
"version"
:
"4.
60.1
"
,
"resolved"
:
"https://registry.npm
js.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.1
.tgz"
,
"integrity"
:
"sha512-
n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg
=="
,
"cpu"
:
[
"arm"
],
...
...
@@ -1862,9 +1862,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-gnu"
:
{
"version"
:
"4.
50.2
"
,
"resolved"
:
"https://registry.npm
mirror.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.50.2
.tgz"
,
"integrity"
:
"sha512-
df0Eou14ojtUdLQdPFnymEQteENwSJAdLf5KCDrmZNsy1c3YaCNaJvYsEUHnrg+/DLBH612/R0xd3dD03uz2dg
=="
,
"version"
:
"4.
60.1
"
,
"resolved"
:
"https://registry.npm
js.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.1
.tgz"
,
"integrity"
:
"sha512-
Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ
=="
,
"cpu"
:
[
"arm64"
],
...
...
@@ -1876,9 +1876,9 @@
]
},
"node_modules/@rollup/rollup-linux-arm64-musl"
:
{
"version"
:
"4.
50.2
"
,
"resolved"
:
"https://registry.npm
mirror.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.50.2
.tgz"
,
"integrity"
:
"sha512-
iPeouV0UIDtz8j1YFR4OJ/zf7evjauqv7jQ/EFs0ClIyL+by++hiaDAfFipjOgyz6y6xbDvJuiU4HwpVMpRFDQ
=="
,
"version"
:
"4.
60.1
"
,
"resolved"
:
"https://registry.npm
js.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.1
.tgz"
,
"integrity"
:
"sha512-
+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA
=="
,
"cpu"
:
[
"arm64"
],
...
...
@@ -1890,9 +1890,23 @@
]
},
"node_modules/@rollup/rollup-linux-loong64-gnu"
:
{
"version"
:
"4.50.2"
,
"resolved"
:
"https://registry.npmmirror.com/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.50.2.tgz"
,
"integrity"
:
"sha512-OL6KaNvBopLlj5fTa5D5bau4W82f+1TyTZRr2BdnfsrnQnmdxh4okMxR2DcDkJuh4KeoQZVuvHvzuD/lyLn2Kw=="
,
"version"
:
"4.60.1"
,
"resolved"
:
"https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.1.tgz"
,
"integrity"
:
"sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ=="
,
"cpu"
:
[
"loong64"
],
"dev"
:
true
,
"license"
:
"MIT"
,
"optional"
:
true
,
"os"
:
[
"linux"
]
},
"node_modules/@rollup/rollup-linux-loong64-musl"
:
{
"version"
:
"4.60.1"
,
"resolved"
:
"https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.1.tgz"
,
"integrity"
:
"sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw=="
,
"cpu"
:
[
"loong64"
],
...
...
@@ -1904,9 +1918,23 @@
]
},
"node_modules/@rollup/rollup-linux-ppc64-gnu"
:
{
"version"
:
"4.50.2"
,
"resolved"
:
"https://registry.npmmirror.com/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.50.2.tgz"
,
"integrity"
:
"sha512-I21VJl1w6z/K5OTRl6aS9DDsqezEZ/yKpbqlvfHbW0CEF5IL8ATBMuUx6/mp683rKTK8thjs/0BaNrZLXetLag=="
,
"version"
:
"4.60.1"
,
"resolved"
:
"https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.1.tgz"
,
"integrity"
:
"sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw=="
,
"cpu"
:
[
"ppc64"
],
"dev"
:
true
,
"license"
:
"MIT"
,
"optional"
:
true
,
"os"
:
[
"linux"
]
},
"node_modules/@rollup/rollup-linux-ppc64-musl"
:
{
"version"
:
"4.60.1"
,
"resolved"
:
"https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.1.tgz"
,
"integrity"
:
"sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg=="
,
"cpu"
:
[
"ppc64"
],
...
...
@@ -1918,9 +1946,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-gnu"
:
{
"version"
:
"4.
50.2
"
,
"resolved"
:
"https://registry.npm
mirror.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.50.2
.tgz"
,
"integrity"
:
"sha512-
Hq6aQJT/qFFHrYMjS20nV+9SKrXL2lvFBENZoKfoTH2kKDOJqff5OSJr4x72ZaG/uUn+XmBnGhfr4lwMRrmqCQ
=="
,
"version"
:
"4.
60.1
"
,
"resolved"
:
"https://registry.npm
js.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.1
.tgz"
,
"integrity"
:
"sha512-
QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg
=="
,
"cpu"
:
[
"riscv64"
],
...
...
@@ -1932,9 +1960,9 @@
]
},
"node_modules/@rollup/rollup-linux-riscv64-musl"
:
{
"version"
:
"4.
50.2
"
,
"resolved"
:
"https://registry.npm
mirror.com/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.50.2
.tgz"
,
"integrity"
:
"sha512-
82rBSEXRv5qtKyr0xZ/YMF531oj2AIpLZkeNYxmKNN6I2sVE9PGegN99tYDLK2fYHJITL1P2Lgb4ZXnv0PjQvw
=="
,
"version"
:
"4.
60.1
"
,
"resolved"
:
"https://registry.npm
js.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.1
.tgz"
,
"integrity"
:
"sha512-
RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg
=="
,
"cpu"
:
[
"riscv64"
],
...
...
@@ -1946,9 +1974,9 @@
]
},
"node_modules/@rollup/rollup-linux-s390x-gnu"
:
{
"version"
:
"4.
50.2
"
,
"resolved"
:
"https://registry.npm
mirror.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.50.2
.tgz"
,
"integrity"
:
"sha512-
4Q3S3Hy7pC6uaRo9gtXUTJ+EKo9AKs3BXKc2jYypEcMQ49gDPFU2P1ariX9SEtBzE5egIX6fSUmbmGazwBVF9w
=="
,
"version"
:
"4.
60.1
"
,
"resolved"
:
"https://registry.npm
js.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.1
.tgz"
,
"integrity"
:
"sha512-
wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ
=="
,
"cpu"
:
[
"s390x"
],
...
...
@@ -1960,9 +1988,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-gnu"
:
{
"version"
:
"4.
50.2
"
,
"resolved"
:
"https://registry.npm
mirror.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.50.2
.tgz"
,
"integrity"
:
"sha512-
9Jie/At6qk70dNIcopcL4p+1UirusEtznpNtcq/u/C5cC4HBX7qSGsYIcG6bdxj15EYWhHiu02YvmdPzylIZlA
=="
,
"version"
:
"4.
60.1
"
,
"resolved"
:
"https://registry.npm
js.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.1
.tgz"
,
"integrity"
:
"sha512-
77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg
=="
,
"cpu"
:
[
"x64"
],
...
...
@@ -1974,9 +2002,9 @@
]
},
"node_modules/@rollup/rollup-linux-x64-musl"
:
{
"version"
:
"4.
50.2
"
,
"resolved"
:
"https://registry.npm
mirror.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.50.2
.tgz"
,
"integrity"
:
"sha512-
HPNJwxPL3EmhzeAnsWQCM3DcoqOz3/IC6de9rWfGR8ZCuEHETi9km66bH/wG3YH0V3nyzyFEGUZeL5PKyy4xv
w=="
,
"version"
:
"4.
60.1
"
,
"resolved"
:
"https://registry.npm
js.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.1
.tgz"
,
"integrity"
:
"sha512-
5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9
w=="
,
"cpu"
:
[
"x64"
],
...
...
@@ -1987,10 +2015,24 @@
"linux"
]
},
"node_modules/@rollup/rollup-openbsd-x64"
:
{
"version"
:
"4.60.1"
,
"resolved"
:
"https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.1.tgz"
,
"integrity"
:
"sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw=="
,
"cpu"
:
[
"x64"
],
"dev"
:
true
,
"license"
:
"MIT"
,
"optional"
:
true
,
"os"
:
[
"openbsd"
]
},
"node_modules/@rollup/rollup-openharmony-arm64"
:
{
"version"
:
"4.
50.2
"
,
"resolved"
:
"https://registry.npm
mirror.com/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.50.2
.tgz"
,
"integrity"
:
"sha512-
nMKvq6FRHSzYfKLHZ+cChowlEkR2lj/V0jYj9JnGUVPL2/mIeFGmVM2mLaFeNa5Jev7W7TovXqXIG2d39y1KY
A=="
,
"version"
:
"4.
60.1
"
,
"resolved"
:
"https://registry.npm
js.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.1
.tgz"
,
"integrity"
:
"sha512-
4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iC
A=="
,
"cpu"
:
[
"arm64"
],
...
...
@@ -2002,9 +2044,9 @@
]
},
"node_modules/@rollup/rollup-win32-arm64-msvc"
:
{
"version"
:
"4.
50.2
"
,
"resolved"
:
"https://registry.npm
mirror.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.50.2
.tgz"
,
"integrity"
:
"sha512-
eFUvvnTYEKeTyHEijQKz81bLrUQOXKZqECeiWH6tb8eXXbZk+CXSG2aFrig2BQ/pjiVRj36zysjgILkqarS2YA
=="
,
"version"
:
"4.
60.1
"
,
"resolved"
:
"https://registry.npm
js.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.1
.tgz"
,
"integrity"
:
"sha512-
i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g
=="
,
"cpu"
:
[
"arm64"
],
...
...
@@ -2016,9 +2058,9 @@
]
},
"node_modules/@rollup/rollup-win32-ia32-msvc"
:
{
"version"
:
"4.
50.2
"
,
"resolved"
:
"https://registry.npm
mirror.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.50.2
.tgz"
,
"integrity"
:
"sha512-
cBaWmXqyfRhH8zmUxK3d3sAhEWLrtMjWBRwdMMHJIXSjvjLKvv49adxiEz+FJ8AP90apSDDBx2Tyd/WylV6ikA
=="
,
"version"
:
"4.
60.1
"
,
"resolved"
:
"https://registry.npm
js.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.1
.tgz"
,
"integrity"
:
"sha512-
u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg
=="
,
"cpu"
:
[
"ia32"
],
...
...
@@ -2029,10 +2071,24 @@
"win32"
]
},
"node_modules/@rollup/rollup-win32-x64-gnu"
:
{
"version"
:
"4.60.1"
,
"resolved"
:
"https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.1.tgz"
,
"integrity"
:
"sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg=="
,
"cpu"
:
[
"x64"
],
"dev"
:
true
,
"license"
:
"MIT"
,
"optional"
:
true
,
"os"
:
[
"win32"
]
},
"node_modules/@rollup/rollup-win32-x64-msvc"
:
{
"version"
:
"4.
50.2
"
,
"resolved"
:
"https://registry.npm
mirror.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.50.2
.tgz"
,
"integrity"
:
"sha512-
APwKy6YUhvZaEoHyM+9xqmTpviEI+9eL7LoCH+aLcvWYHJ663qG5zx7WzWZY+a9qkg5JtzcMyJ9z0WtQBMDmgA
=="
,
"version"
:
"4.
60.1
"
,
"resolved"
:
"https://registry.npm
js.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.1
.tgz"
,
"integrity"
:
"sha512-
lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ
=="
,
"cpu"
:
[
"x64"
],
...
...
@@ -2551,9 +2607,9 @@
}
},
"node_modules/anymatch/node_modules/picomatch"
:
{
"version"
:
"2.3.
1
"
,
"resolved"
:
"https://registry.npm
mirror.com/picomatch/-/picomatch-2.3.1
.tgz"
,
"integrity"
:
"sha512-
JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUV
A=="
,
"version"
:
"2.3.
2
"
,
"resolved"
:
"https://registry.npm
js.org/picomatch/-/picomatch-2.3.2
.tgz"
,
"integrity"
:
"sha512-
V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0o
A=="
,
"dev"
:
true
,
"license"
:
"MIT"
,
"engines"
:
{
...
...
@@ -2650,7 +2706,7 @@
},
"node_modules/asynckit"
:
{
"version"
:
"0.4.0"
,
"resolved"
:
"https://registry.npm
mirror.com
/asynckit/-/asynckit-0.4.0.tgz"
,
"resolved"
:
"https://registry.npm
js.org
/asynckit/-/asynckit-0.4.0.tgz"
,
"integrity"
:
"sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
,
"license"
:
"MIT"
},
...
...
@@ -2704,14 +2760,14 @@
}
},
"node_modules/axios"
:
{
"version"
:
"1.1
2.2
"
,
"resolved"
:
"https://registry.npm
mirror.com/axios/-/axios-1.12.2
.tgz"
,
"integrity"
:
"sha512-
vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw
=="
,
"version"
:
"1.1
4.0
"
,
"resolved"
:
"https://registry.npm
js.org/axios/-/axios-1.14.0
.tgz"
,
"integrity"
:
"sha512-
3Y8yrqLSwjuzpXuZ0oIYZ/XGgLwUIBU3uLvbcpb0pidD9ctpShJd43KSlEEkVQg6DS0G9NKyzOvBfUtDKEyHvQ
=="
,
"license"
:
"MIT"
,
"dependencies"
:
{
"follow-redirects"
:
"^1.15.
6
"
,
"form-data"
:
"^4.0.
4
"
,
"proxy-from-env"
:
"^
1
.1.0"
"follow-redirects"
:
"^1.15.
11
"
,
"form-data"
:
"^4.0.
5
"
,
"proxy-from-env"
:
"^
2
.1.0"
}
},
"node_modules/balanced-match"
:
{
...
...
@@ -2795,9 +2851,9 @@
}
},
"node_modules/brace-expansion"
:
{
"version"
:
"2.0.
2
"
,
"resolved"
:
"https://registry.npm
mirror.com/brace-expansion/-/brace-expansion-2.0.2
.tgz"
,
"integrity"
:
"sha512-
Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ
=="
,
"version"
:
"2.0.
3
"
,
"resolved"
:
"https://registry.npm
js.org/brace-expansion/-/brace-expansion-2.0.3
.tgz"
,
"integrity"
:
"sha512-
MCV/fYJEbqx68aE58kv2cA/kiky1G8vux3OR6/jbS+jIMe/6fJWa0DTzJU7dqijOWYwHi1t29FlfYI9uytqlpA
=="
,
"dev"
:
true
,
"license"
:
"MIT"
,
"dependencies"
:
{
...
...
@@ -2873,7 +2929,7 @@
},
"node_modules/call-bind-apply-helpers"
:
{
"version"
:
"1.0.2"
,
"resolved"
:
"https://registry.npm
mirror.com
/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz"
,
"resolved"
:
"https://registry.npm
js.org
/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz"
,
"integrity"
:
"sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="
,
"license"
:
"MIT"
,
"dependencies"
:
{
...
...
@@ -3073,7 +3129,7 @@
},
"node_modules/combined-stream"
:
{
"version"
:
"1.0.8"
,
"resolved"
:
"https://registry.npm
mirror.com
/combined-stream/-/combined-stream-1.0.8.tgz"
,
"resolved"
:
"https://registry.npm
js.org
/combined-stream/-/combined-stream-1.0.8.tgz"
,
"integrity"
:
"sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="
,
"license"
:
"MIT"
,
"dependencies"
:
{
...
...
@@ -3789,7 +3845,7 @@
},
"node_modules/delayed-stream"
:
{
"version"
:
"1.0.0"
,
"resolved"
:
"https://registry.npm
mirror.com
/delayed-stream/-/delayed-stream-1.0.0.tgz"
,
"resolved"
:
"https://registry.npm
js.org
/delayed-stream/-/delayed-stream-1.0.0.tgz"
,
"integrity"
:
"sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
,
"license"
:
"MIT"
,
"engines"
:
{
...
...
@@ -3832,9 +3888,9 @@
"license"
:
"Apache-2.0"
},
"node_modules/diff"
:
{
"version"
:
"5.2.
0
"
,
"resolved"
:
"https://registry.npm
mirror.com/diff/-/diff-5.2.0
.tgz"
,
"integrity"
:
"sha512-
uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5
A=="
,
"version"
:
"5.2.
2
"
,
"resolved"
:
"https://registry.npm
js.org/diff/-/diff-5.2.2
.tgz"
,
"integrity"
:
"sha512-
vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+
A=="
,
"license"
:
"BSD-3-Clause"
,
"engines"
:
{
"node"
:
">=0.3.1"
...
...
@@ -3860,9 +3916,9 @@
"license"
:
"MIT"
},
"node_modules/dompurify"
:
{
"version"
:
"3.3.
0
"
,
"resolved"
:
"https://registry.npm
mirror.com/dompurify/-/dompurify-3.3.0
.tgz"
,
"integrity"
:
"sha512-
r+f6MYR1gGN1eJv0TVQbhA7if/U7P87cdPl3HN5rikqaBSBxLiCb/b9O+2eG0cxz0ghyU+mU1QkbsOwERMYlWQ
=="
,
"version"
:
"3.3.
3
"
,
"resolved"
:
"https://registry.npm
js.org/dompurify/-/dompurify-3.3.3
.tgz"
,
"integrity"
:
"sha512-
Oj6pzI2+RqBfFG+qOaOLbFXLQ90ARpcGG6UePL82bJLtdsa6CYJD7nmiU8MW9nQNOtCHV3lZ/Bzq1X0QYbBZCA
=="
,
"license"
:
"(MPL-2.0 OR Apache-2.0)"
,
"optionalDependencies"
:
{
"@types/trusted-types"
:
"^2.0.7"
...
...
@@ -3870,7 +3926,7 @@
},
"node_modules/dunder-proto"
:
{
"version"
:
"1.0.1"
,
"resolved"
:
"https://registry.npm
mirror.com
/dunder-proto/-/dunder-proto-1.0.1.tgz"
,
"resolved"
:
"https://registry.npm
js.org
/dunder-proto/-/dunder-proto-1.0.1.tgz"
,
"integrity"
:
"sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="
,
"license"
:
"MIT"
,
"dependencies"
:
{
...
...
@@ -3963,7 +4019,7 @@
},
"node_modules/es-define-property"
:
{
"version"
:
"1.0.1"
,
"resolved"
:
"https://registry.npm
mirror.com
/es-define-property/-/es-define-property-1.0.1.tgz"
,
"resolved"
:
"https://registry.npm
js.org
/es-define-property/-/es-define-property-1.0.1.tgz"
,
"integrity"
:
"sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="
,
"license"
:
"MIT"
,
"engines"
:
{
...
...
@@ -3972,7 +4028,7 @@
},
"node_modules/es-errors"
:
{
"version"
:
"1.3.0"
,
"resolved"
:
"https://registry.npm
mirror.com
/es-errors/-/es-errors-1.3.0.tgz"
,
"resolved"
:
"https://registry.npm
js.org
/es-errors/-/es-errors-1.3.0.tgz"
,
"integrity"
:
"sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="
,
"license"
:
"MIT"
,
"engines"
:
{
...
...
@@ -3981,7 +4037,7 @@
},
"node_modules/es-object-atoms"
:
{
"version"
:
"1.1.1"
,
"resolved"
:
"https://registry.npm
mirror.com
/es-object-atoms/-/es-object-atoms-1.1.1.tgz"
,
"resolved"
:
"https://registry.npm
js.org
/es-object-atoms/-/es-object-atoms-1.1.1.tgz"
,
"integrity"
:
"sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="
,
"license"
:
"MIT"
,
"dependencies"
:
{
...
...
@@ -3993,7 +4049,7 @@
},
"node_modules/es-set-tostringtag"
:
{
"version"
:
"2.1.0"
,
"resolved"
:
"https://registry.npm
mirror.com
/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz"
,
"resolved"
:
"https://registry.npm
js.org
/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz"
,
"integrity"
:
"sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="
,
"license"
:
"MIT"
,
"dependencies"
:
{
...
...
@@ -4304,9 +4360,9 @@
}
},
"node_modules/form-data"
:
{
"version"
:
"4.0.
4
"
,
"resolved"
:
"https://registry.npm
mirror.com/form-data/-/form-data-4.0.4
.tgz"
,
"integrity"
:
"sha512-
KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0O
w=="
,
"version"
:
"4.0.
5
"
,
"resolved"
:
"https://registry.npm
js.org/form-data/-/form-data-4.0.5
.tgz"
,
"integrity"
:
"sha512-
8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82
w=="
,
"license"
:
"MIT"
,
"dependencies"
:
{
"asynckit"
:
"^0.4.0"
,
...
...
@@ -4391,7 +4447,7 @@
},
"node_modules/get-intrinsic"
:
{
"version"
:
"1.3.0"
,
"resolved"
:
"https://registry.npm
mirror.com
/get-intrinsic/-/get-intrinsic-1.3.0.tgz"
,
"resolved"
:
"https://registry.npm
js.org
/get-intrinsic/-/get-intrinsic-1.3.0.tgz"
,
"integrity"
:
"sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="
,
"license"
:
"MIT"
,
"dependencies"
:
{
...
...
@@ -4415,7 +4471,7 @@
},
"node_modules/get-proto"
:
{
"version"
:
"1.0.1"
,
"resolved"
:
"https://registry.npm
mirror.com
/get-proto/-/get-proto-1.0.1.tgz"
,
"resolved"
:
"https://registry.npm
js.org
/get-proto/-/get-proto-1.0.1.tgz"
,
"integrity"
:
"sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="
,
"license"
:
"MIT"
,
"dependencies"
:
{
...
...
@@ -4486,9 +4542,9 @@
"license"
:
"BSD"
},
"node_modules/glob/node_modules/brace-expansion"
:
{
"version"
:
"1.1.1
2
"
,
"resolved"
:
"https://registry.npm
mirror.com/brace-expansion/-/brace-expansion-1.1.12
.tgz"
,
"integrity"
:
"sha512-9
T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg
=="
,
"version"
:
"1.1.1
3
"
,
"resolved"
:
"https://registry.npm
js.org/brace-expansion/-/brace-expansion-1.1.13
.tgz"
,
"integrity"
:
"sha512-9
ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w
=="
,
"license"
:
"MIT"
,
"dependencies"
:
{
"balanced-match"
:
"^1.0.0"
,
...
...
@@ -4496,9 +4552,9 @@
}
},
"node_modules/glob/node_modules/minimatch"
:
{
"version"
:
"3.1.
2
"
,
"resolved"
:
"https://registry.npm
mirror.com/minimatch/-/minimatch-3.1.2
.tgz"
,
"integrity"
:
"sha512-
J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIH
w=="
,
"version"
:
"3.1.
5
"
,
"resolved"
:
"https://registry.npm
js.org/minimatch/-/minimatch-3.1.5
.tgz"
,
"integrity"
:
"sha512-
VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4
w=="
,
"license"
:
"ISC"
,
"dependencies"
:
{
"brace-expansion"
:
"^1.1.7"
...
...
@@ -4698,7 +4754,7 @@
},
"node_modules/gopd"
:
{
"version"
:
"1.2.0"
,
"resolved"
:
"https://registry.npm
mirror.com
/gopd/-/gopd-1.2.0.tgz"
,
"resolved"
:
"https://registry.npm
js.org
/gopd/-/gopd-1.2.0.tgz"
,
"integrity"
:
"sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="
,
"license"
:
"MIT"
,
"engines"
:
{
...
...
@@ -4748,7 +4804,7 @@
},
"node_modules/has-symbols"
:
{
"version"
:
"1.1.0"
,
"resolved"
:
"https://registry.npm
mirror.com
/has-symbols/-/has-symbols-1.1.0.tgz"
,
"resolved"
:
"https://registry.npm
js.org
/has-symbols/-/has-symbols-1.1.0.tgz"
,
"integrity"
:
"sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="
,
"license"
:
"MIT"
,
"engines"
:
{
...
...
@@ -4760,7 +4816,7 @@
},
"node_modules/has-tostringtag"
:
{
"version"
:
"1.0.2"
,
"resolved"
:
"https://registry.npm
mirror.com
/has-tostringtag/-/has-tostringtag-1.0.2.tgz"
,
"resolved"
:
"https://registry.npm
js.org
/has-tostringtag/-/has-tostringtag-1.0.2.tgz"
,
"integrity"
:
"sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="
,
"license"
:
"MIT"
,
"dependencies"
:
{
...
...
@@ -4904,9 +4960,9 @@
}
},
"node_modules/immutable"
:
{
"version"
:
"5.1.
3
"
,
"resolved"
:
"https://registry.npm
mirror.com/immutable/-/immutable-5.1.3
.tgz"
,
"integrity"
:
"sha512-
+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg
=="
,
"version"
:
"5.1.
5
"
,
"resolved"
:
"https://registry.npm
js.org/immutable/-/immutable-5.1.5
.tgz"
,
"integrity"
:
"sha512-
t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A
=="
,
"dev"
:
true
,
"license"
:
"MIT"
},
...
...
@@ -5141,9 +5197,9 @@
"license"
:
"MIT"
},
"node_modules/js-yaml"
:
{
"version"
:
"3.14.
1
"
,
"resolved"
:
"https://registry.npm
mirror.com/js-yaml/-/js-yaml-3.14.1
.tgz"
,
"integrity"
:
"sha512-
okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9
g=="
,
"version"
:
"3.14.
2
"
,
"resolved"
:
"https://registry.npm
js.org/js-yaml/-/js-yaml-3.14.2
.tgz"
,
"integrity"
:
"sha512-
PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVp
g=="
,
"license"
:
"MIT"
,
"dependencies"
:
{
"argparse"
:
"^1.0.7"
,
...
...
@@ -5275,15 +5331,15 @@
}
},
"node_modules/lodash"
:
{
"version"
:
"4.1
7.2
1"
,
"resolved"
:
"https://registry.npmjs.org/lodash/-/lodash-4.1
7.2
1.tgz"
,
"integrity"
:
"sha512-
v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg
=="
,
"version"
:
"4.1
8.
1"
,
"resolved"
:
"https://registry.npmjs.org/lodash/-/lodash-4.1
8.
1.tgz"
,
"integrity"
:
"sha512-
dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q
=="
,
"license"
:
"MIT"
},
"node_modules/lodash-es"
:
{
"version"
:
"4.1
7.2
1"
,
"resolved"
:
"https://registry.npm
mirror.com/lodash-es/-/lodash-es-4.17.2
1.tgz"
,
"integrity"
:
"sha512-
mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw
=="
,
"version"
:
"4.1
8.
1"
,
"resolved"
:
"https://registry.npm
js.org/lodash-es/-/lodash-es-4.18.
1.tgz"
,
"integrity"
:
"sha512-
J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A
=="
,
"license"
:
"MIT"
},
"node_modules/lodash-unified"
:
{
...
...
@@ -5328,9 +5384,9 @@
}
},
"node_modules/markdown-it"
:
{
"version"
:
"14.1.
0
"
,
"resolved"
:
"https://registry.npm
mirror.com/markdown-it/-/markdown-it-14.1.0
.tgz"
,
"integrity"
:
"sha512-
a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg
=="
,
"version"
:
"14.1.
1
"
,
"resolved"
:
"https://registry.npm
js.org/markdown-it/-/markdown-it-14.1.1
.tgz"
,
"integrity"
:
"sha512-
BuU2qnTti9YKgK5N+IeMubp14ZUKUUw7yeJbkjtosvHiP0AZ5c8IAgEMk79D0eC8F23r4Ac/q8cAIFdm2FtyoA
=="
,
"license"
:
"MIT"
,
"dependencies"
:
{
"argparse"
:
"^2.0.1"
,
...
...
@@ -5403,7 +5459,7 @@
},
"node_modules/math-intrinsics"
:
{
"version"
:
"1.1.0"
,
"resolved"
:
"https://registry.npm
mirror.com
/math-intrinsics/-/math-intrinsics-1.1.0.tgz"
,
"resolved"
:
"https://registry.npm
js.org
/math-intrinsics/-/math-intrinsics-1.1.0.tgz"
,
"integrity"
:
"sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="
,
"license"
:
"MIT"
,
"engines"
:
{
...
...
@@ -5953,9 +6009,9 @@
}
},
"node_modules/micromatch/node_modules/picomatch"
:
{
"version"
:
"2.3.
1
"
,
"resolved"
:
"https://registry.npm
mirror.com/picomatch/-/picomatch-2.3.1
.tgz"
,
"integrity"
:
"sha512-
JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUV
A=="
,
"version"
:
"2.3.
2
"
,
"resolved"
:
"https://registry.npm
js.org/picomatch/-/picomatch-2.3.2
.tgz"
,
"integrity"
:
"sha512-
V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0o
A=="
,
"dev"
:
true
,
"license"
:
"MIT"
,
"engines"
:
{
...
...
@@ -5967,7 +6023,7 @@
},
"node_modules/mime-db"
:
{
"version"
:
"1.52.0"
,
"resolved"
:
"https://registry.npm
mirror.com
/mime-db/-/mime-db-1.52.0.tgz"
,
"resolved"
:
"https://registry.npm
js.org
/mime-db/-/mime-db-1.52.0.tgz"
,
"integrity"
:
"sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
,
"license"
:
"MIT"
,
"engines"
:
{
...
...
@@ -5976,7 +6032,7 @@
},
"node_modules/mime-types"
:
{
"version"
:
"2.1.35"
,
"resolved"
:
"https://registry.npm
mirror.com
/mime-types/-/mime-types-2.1.35.tgz"
,
"resolved"
:
"https://registry.npm
js.org
/mime-types/-/mime-types-2.1.35.tgz"
,
"integrity"
:
"sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="
,
"license"
:
"MIT"
,
"dependencies"
:
{
...
...
@@ -5987,13 +6043,13 @@
}
},
"node_modules/minimatch"
:
{
"version"
:
"9.0.
5
"
,
"resolved"
:
"https://registry.npm
mirror.com/minimatch/-/minimatch-9.0.5
.tgz"
,
"integrity"
:
"sha512-
G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow
=="
,
"version"
:
"9.0.
9
"
,
"resolved"
:
"https://registry.npm
js.org/minimatch/-/minimatch-9.0.9
.tgz"
,
"integrity"
:
"sha512-
OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg
=="
,
"dev"
:
true
,
"license"
:
"ISC"
,
"dependencies"
:
{
"brace-expansion"
:
"^2.0.
1
"
"brace-expansion"
:
"^2.0.
2
"
},
"engines"
:
{
"node"
:
">=16 || 14 >=14.17"
...
...
@@ -6406,9 +6462,9 @@
"license"
:
"ISC"
},
"node_modules/picomatch"
:
{
"version"
:
"4.0.
3
"
,
"resolved"
:
"https://registry.npm
mirror.com/picomatch/-/picomatch-4.0.3
.tgz"
,
"integrity"
:
"sha512-
5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q
=="
,
"version"
:
"4.0.
4
"
,
"resolved"
:
"https://registry.npm
js.org/picomatch/-/picomatch-4.0.4
.tgz"
,
"integrity"
:
"sha512-
QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A
=="
,
"dev"
:
true
,
"license"
:
"MIT"
,
"engines"
:
{
...
...
@@ -6664,10 +6720,13 @@
}
},
"node_modules/proxy-from-env"
:
{
"version"
:
"1.1.0"
,
"resolved"
:
"https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz"
,
"integrity"
:
"sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
,
"license"
:
"MIT"
"version"
:
"2.1.0"
,
"resolved"
:
"https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz"
,
"integrity"
:
"sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA=="
,
"license"
:
"MIT"
,
"engines"
:
{
"node"
:
">=10"
}
},
"node_modules/punycode.js"
:
{
"version"
:
"2.3.1"
,
...
...
@@ -6750,9 +6809,9 @@
}
},
"node_modules/readdirp/node_modules/picomatch"
:
{
"version"
:
"2.3.
1
"
,
"resolved"
:
"https://registry.npm
mirror.com/picomatch/-/picomatch-2.3.1
.tgz"
,
"integrity"
:
"sha512-
JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUV
A=="
,
"version"
:
"2.3.
2
"
,
"resolved"
:
"https://registry.npm
js.org/picomatch/-/picomatch-2.3.2
.tgz"
,
"integrity"
:
"sha512-
V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0o
A=="
,
"dev"
:
true
,
"license"
:
"MIT"
,
"engines"
:
{
...
...
@@ -6900,9 +6959,9 @@
"license"
:
"Unlicense"
},
"node_modules/rollup"
:
{
"version"
:
"4.
50.2
"
,
"resolved"
:
"https://registry.npm
mirror.com/rollup/-/rollup-4.50.2
.tgz"
,
"integrity"
:
"sha512-
BgLRGy7tNS9H66aIMASq1qSYbAAJV6Z6WR4QYTvj5FgF15rZ/ympT1uixHXwzbZUBDbkvqUI1KR0fH1FhMaQ9
w=="
,
"version"
:
"4.
60.1
"
,
"resolved"
:
"https://registry.npm
js.org/rollup/-/rollup-4.60.1
.tgz"
,
"integrity"
:
"sha512-
VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0
w=="
,
"dev"
:
true
,
"license"
:
"MIT"
,
"dependencies"
:
{
...
...
@@ -6916,27 +6975,31 @@
"npm"
:
">=8.0.0"
},
"optionalDependencies"
:
{
"@rollup/rollup-android-arm-eabi"
:
"4.50.2"
,
"@rollup/rollup-android-arm64"
:
"4.50.2"
,
"@rollup/rollup-darwin-arm64"
:
"4.50.2"
,
"@rollup/rollup-darwin-x64"
:
"4.50.2"
,
"@rollup/rollup-freebsd-arm64"
:
"4.50.2"
,
"@rollup/rollup-freebsd-x64"
:
"4.50.2"
,
"@rollup/rollup-linux-arm-gnueabihf"
:
"4.50.2"
,
"@rollup/rollup-linux-arm-musleabihf"
:
"4.50.2"
,
"@rollup/rollup-linux-arm64-gnu"
:
"4.50.2"
,
"@rollup/rollup-linux-arm64-musl"
:
"4.50.2"
,
"@rollup/rollup-linux-loong64-gnu"
:
"4.50.2"
,
"@rollup/rollup-linux-ppc64-gnu"
:
"4.50.2"
,
"@rollup/rollup-linux-riscv64-gnu"
:
"4.50.2"
,
"@rollup/rollup-linux-riscv64-musl"
:
"4.50.2"
,
"@rollup/rollup-linux-s390x-gnu"
:
"4.50.2"
,
"@rollup/rollup-linux-x64-gnu"
:
"4.50.2"
,
"@rollup/rollup-linux-x64-musl"
:
"4.50.2"
,
"@rollup/rollup-openharmony-arm64"
:
"4.50.2"
,
"@rollup/rollup-win32-arm64-msvc"
:
"4.50.2"
,
"@rollup/rollup-win32-ia32-msvc"
:
"4.50.2"
,
"@rollup/rollup-win32-x64-msvc"
:
"4.50.2"
,
"@rollup/rollup-android-arm-eabi"
:
"4.60.1"
,
"@rollup/rollup-android-arm64"
:
"4.60.1"
,
"@rollup/rollup-darwin-arm64"
:
"4.60.1"
,
"@rollup/rollup-darwin-x64"
:
"4.60.1"
,
"@rollup/rollup-freebsd-arm64"
:
"4.60.1"
,
"@rollup/rollup-freebsd-x64"
:
"4.60.1"
,
"@rollup/rollup-linux-arm-gnueabihf"
:
"4.60.1"
,
"@rollup/rollup-linux-arm-musleabihf"
:
"4.60.1"
,
"@rollup/rollup-linux-arm64-gnu"
:
"4.60.1"
,
"@rollup/rollup-linux-arm64-musl"
:
"4.60.1"
,
"@rollup/rollup-linux-loong64-gnu"
:
"4.60.1"
,
"@rollup/rollup-linux-loong64-musl"
:
"4.60.1"
,
"@rollup/rollup-linux-ppc64-gnu"
:
"4.60.1"
,
"@rollup/rollup-linux-ppc64-musl"
:
"4.60.1"
,
"@rollup/rollup-linux-riscv64-gnu"
:
"4.60.1"
,
"@rollup/rollup-linux-riscv64-musl"
:
"4.60.1"
,
"@rollup/rollup-linux-s390x-gnu"
:
"4.60.1"
,
"@rollup/rollup-linux-x64-gnu"
:
"4.60.1"
,
"@rollup/rollup-linux-x64-musl"
:
"4.60.1"
,
"@rollup/rollup-openbsd-x64"
:
"4.60.1"
,
"@rollup/rollup-openharmony-arm64"
:
"4.60.1"
,
"@rollup/rollup-win32-arm64-msvc"
:
"4.60.1"
,
"@rollup/rollup-win32-ia32-msvc"
:
"4.60.1"
,
"@rollup/rollup-win32-x64-gnu"
:
"4.60.1"
,
"@rollup/rollup-win32-x64-msvc"
:
"4.60.1"
,
"fsevents"
:
"~2.3.2"
}
},
...
...
@@ -8066,9 +8129,9 @@
}
},
"node_modules/vite"
:
{
"version"
:
"5.4.2
0
"
,
"resolved"
:
"https://registry.npm
mirror.com/vite/-/vite-5.4.20
.tgz"
,
"integrity"
:
"sha512-
j3lYzGC3P+B5Yfy/pfKNgVEg4+UtcIJcVRt2cDjIOmhLourAqPqf8P7acgxeiSgUB7E3p2P8/3gNIgDLpwzs4g
=="
,
"version"
:
"5.4.2
1
"
,
"resolved"
:
"https://registry.npm
js.org/vite/-/vite-5.4.21
.tgz"
,
"integrity"
:
"sha512-
o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw
=="
,
"dev"
:
true
,
"license"
:
"MIT"
,
"dependencies"
:
{
...
...
@@ -8214,9 +8277,9 @@
"license"
:
"MIT"
},
"node_modules/yaml"
:
{
"version"
:
"2.8.
2
"
,
"resolved"
:
"https://registry.npm
mirror.com/yaml/-/yaml-2.8.2
.tgz"
,
"integrity"
:
"sha512-
mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A
=="
,
"version"
:
"2.8.
3
"
,
"resolved"
:
"https://registry.npm
js.org/yaml/-/yaml-2.8.3
.tgz"
,
"integrity"
:
"sha512-
AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg
=="
,
"dev"
:
true
,
"license"
:
"ISC"
,
"bin"
:
{
...
...
src/api/marketAccessRestrictions/index.js
浏览文件 @
8d534f1e
...
...
@@ -178,7 +178,7 @@ export function getSearchBlurb(params) {
})
}
// 获取相关事件
getRelatedEvents
// 获取相关事件
export
function
getRelatedEvents
(
params
)
{
return
request
({
method
:
'GET'
,
...
...
@@ -186,8 +186,16 @@ export function getRelatedEvents(params) {
params
})
}
// 获取相关行政举措
export
function
getSearchAOMeasures
(
params
)
{
return
request
({
method
:
'GET'
,
url
:
`/api/marketsearchDetails/getSearchAOMeasures`
,
params
})
}
// 获取事件脉络
getSearchContext
// 获取事件脉络
export
function
getSearchContext
(
params
)
{
return
request
({
method
:
'GET'
,
...
...
src/api/scientificFunding/overview.js
浏览文件 @
8d534f1e
...
...
@@ -126,11 +126,25 @@ export function getAreaType() {
})
}
/**
* 资助项目列表:领域、年份用逗号拼接为一个查询参数(arealist=1,2,3&yearlist=2025,2024)
*/
function
normalizeProjectListQueryParams
(
params
)
{
const
next
=
{
...(
params
||
{})
}
if
(
Array
.
isArray
(
next
.
arealist
))
{
next
.
arealist
=
next
.
arealist
.
filter
((
v
)
=>
v
!==
undefined
&&
v
!==
null
&&
v
!==
""
).
join
(
","
)
}
if
(
Array
.
isArray
(
next
.
yearlist
))
{
next
.
yearlist
=
next
.
yearlist
.
filter
((
v
)
=>
v
!==
undefined
&&
v
!==
null
&&
v
!==
""
).
join
(
","
)
}
return
next
}
//资助体系v2.0:资助项目列表分页
export
function
getProjectListNew
(
params
)
{
return
request
({
method
:
'GET'
,
url
:
`/api/fund/getProjectListNew`
,
params
params
:
normalizeProjectListQueryParams
(
params
)
})
}
src/components/base/DecreeOriginal/newOriginal.vue
0 → 100644
浏览文件 @
8d534f1e
<
template
>
<div
class=
"layout-container"
>
<div
class=
"layout-main"
>
<div
class=
"layout-main-center"
>
<div
class=
"report-header"
>
<div
class=
"report-title"
>
政令原文
</div>
<el-switch
v-model=
"isHighlight"
@
change=
"handleHighlight"
/>
<div
class=
"switch-label switch-label-left"
>
高亮实体
</div>
<el-switch
v-model=
"isTranslate"
@
change=
"handleTranslate"
/>
<div
class=
"switch-label"
>
译文显示
</div>
<div
class=
"btn"
@
click=
"emits('download')"
>
<div
class=
"icon icon-gap-4"
>
<img
src=
"./assets/icons/download.png"
alt=
""
/>
</div>
<div
class=
"text"
>
下载
</div>
</div>
<div
class=
"btn"
@
click=
"handleFindWord('open')"
>
<div
class=
"icon icon-gap-6"
>
<img
src=
"./assets/icons/search.png"
alt=
""
/>
</div>
<div
class=
"text"
>
查找
</div>
</div>
<div
class=
"find-word-box"
v-if=
"findWordBox"
>
<div
class=
"find-word-input"
>
<el-input
v-model=
"findWordTxt"
placeholder=
"查找原文内容"
@
input=
"handleUpdateWord"
/>
</div>
<div
class=
"find-word-limit"
>
{{
findWordNum
}}
/
{{
findWordMax
}}
</div>
<div
class=
"find-word-icon"
@
click=
"handleFindWord('last')"
>
<el-icon><ArrowUp
/></el-icon>
</div>
<div
class=
"find-word-icon"
@
click=
"handleFindWord('next')"
>
<el-icon><ArrowDown
/></el-icon>
</div>
<div
class=
"find-word-icon"
@
click=
"handleFindWord('close')"
>
<el-icon><Close
/></el-icon>
</div>
</div>
</div>
<div
:class=
"['report-main',
{'is-highlight': isHighlight}]">
<div
v-if=
"!formatData.length"
class=
"no-content"
>
暂无数据
</div>
<el-scrollbar
v-else
height=
"100%"
>
<div
v-for=
"(item, index) in formatData"
:key=
"index"
class=
"content-row"
>
<div
class=
"content-en"
:class=
"
{ 'only-show': !isTranslate }">
<template
v-for=
"(node, num) in item.contentEn"
:key=
"num"
>
<el-icon
v-if=
"node.icon && isHighlight"
color=
"#508fd4"
size=
"14"
><Search
/></el-icon>
<span
v-else-if=
"node.point"
class=
"find-light-point"
></span>
<span
v-else-if=
"node.fill"
:class=
"node.class"
@
click=
"handleHighLight(node)"
>
{{
node
.
txt
}}
</span>
<span
v-else
:class=
"node.class"
>
{{
node
.
txt
}}
</span>
</
template
>
</div>
<div
class=
"content-ch"
v-if=
"isTranslate"
>
<
template
v-for=
"(node, num) in item.contentCh"
:key=
"num"
>
<el-icon
v-if=
"node.icon && isHighlight"
color=
"#508fd4"
size=
"14"
><Search
/></el-icon>
<span
v-else-if=
"node.point"
class=
"find-light-point"
></span>
<span
v-else-if=
"node.fill"
:class=
"node.class"
@
click=
"handleHighLight(node)"
>
{{
node
.
txt
}}
</span>
<span
v-else
:class=
"node.class"
>
{{
node
.
txt
}}
</span>
</
template
>
</div>
</div>
</el-scrollbar>
</div>
</div>
</div>
</div>
</template>
<
script
setup
>
import
{
nextTick
,
ref
}
from
"vue"
;
import
{
debounce
}
from
"lodash"
;
import
{
extractTextEntity
}
from
"@/api/intelligent"
;
const
emits
=
defineEmits
([
"download"
]);
const
isHighlight
=
ref
(
true
);
// 是否高亮实体
const
isTranslate
=
ref
(
true
);
// 是否显示译文
const
handleTranslate
=
()
=>
{
if
(
findWordTxt
.
value
?.
trim
())
handleUpdateWord
()
}
const
findWordTxt
=
ref
(
""
);
const
findWordBox
=
ref
(
false
);
const
findWordNum
=
ref
(
0
);
const
findWordMax
=
ref
(
0
);
const
formatData
=
ref
([])
const
handleUpdateWord
=
debounce
(()
=>
{
findWordNum
.
value
=
0
;
findWordMax
.
value
=
0
;
formatData
.
value
=
originData
.
map
(
item
=>
{
return
{
contentEn
:
onHighlightedText
(
item
.
contentEn
,
keywordEn
),
contentCh
:
isTranslate
.
value
?
onHighlightedText
(
item
.
contentCh
,
keywordCh
)
:
[],
}
})
if
(
findWordMax
.
value
)
{
findWordNum
.
value
=
1
;
nextTick
(
updateActiveHighlight
)
}
},
300
);
function
handleFindWord
(
event
)
{
switch
(
event
)
{
case
"open"
:
findWordBox
.
value
=
true
;
break
;
case
"last"
:
if
(
findWordMax
.
value
>
1
)
{
findWordNum
.
value
=
findWordNum
.
value
===
1
?
findWordMax
.
value
:
findWordNum
.
value
-
1
;
updateActiveHighlight
();
}
break
;
case
"next"
:
if
(
findWordMax
.
value
>
1
)
{
findWordNum
.
value
=
findWordNum
.
value
===
findWordMax
.
value
?
1
:
findWordNum
.
value
+
1
;
updateActiveHighlight
();
}
break
;
case
"close"
:
findWordBox
.
value
=
false
;
findWordTxt
.
value
=
""
;
handleUpdateWord
();
break
;
}
}
const
updateActiveHighlight
=
()
=>
{
if
(
!
findWordNum
.
value
)
return
const
spans
=
document
.
querySelectorAll
(
"span.find-light-point"
);
spans
.
forEach
((
span
,
index
)
=>
{
if
(
index
+
1
===
findWordNum
.
value
)
span
.
scrollIntoView
({});
});
}
// 政令原文信息
let
originData
=
[]
let
keywordCh
=
[]
let
keywordEn
=
[]
const
setOriginalData
=
(
data
)
=>
{
originData
=
[]
let
num
=
Math
.
max
(
data
.
content
.
length
,
data
.
contentEn
.
length
)
for
(
let
i
=
0
;
i
<
num
;
i
++
)
{
let
obj
=
{
contentCh
:
data
.
content
[
i
]
||
""
,
contentEn
:
data
.
contentEn
[
i
]
||
""
,
}
originData
.
push
(
obj
);
}
let
allEn
=
""
let
allCh
=
""
formatData
.
value
=
originData
.
map
(
item
=>
{
allEn
+=
item
.
contentEn
+
"。"
allCh
+=
item
.
contentCh
+
"。"
return
{
contentEn
:
[{
txt
:
item
.
contentEn
,
class
:
""
}],
contentCh
:
[{
txt
:
item
.
contentCh
,
class
:
""
}]
}
})
extractTextEntity
(
allEn
||
""
).
then
(
res
=>
{
if
(
res
?.
result
?.
length
)
keywordEn
=
res
.
result
||
[]
originData
.
forEach
((
item
,
index
)
=>
{
formatData
.
value
[
index
].
contentEn
=
onHighlightedText
(
item
.
contentEn
,
keywordEn
);
})
})
extractTextEntity
(
allCh
||
""
).
then
(
res
=>
{
if
(
res
?.
result
?.
length
)
keywordCh
=
res
.
result
||
[]
if
(
isTranslate
.
value
)
{
originData
.
forEach
((
item
,
index
)
=>
{
formatData
.
value
[
index
].
contentCh
=
onHighlightedText
(
item
.
contentCh
,
keywordCh
);
})
}
})
}
defineExpose
({
setOriginalData
})
// 文本分割
const
onHighlightedText
=
(
text
,
nounList
)
=>
{
if
(
text
===
""
)
return
[]
// 获取区间(合并相邻/重叠),并自动过滤空关键词
const
getIntervals
=
(
str
,
keywords
)
=>
{
const
intervals
=
[];
for
(
const
kw
of
keywords
)
{
if
(
!
kw
)
continue
;
// 跳过空字符串,防止无限循环
let
idx
=
0
;
while
((
idx
=
str
.
indexOf
(
kw
,
idx
))
!==
-
1
)
{
intervals
.
push
({
start
:
idx
,
end
:
idx
+
kw
.
length
});
idx
+=
kw
.
length
;
}
}
if
(
!
intervals
.
length
)
return
[];
intervals
.
sort
((
a
,
b
)
=>
a
.
start
-
b
.
start
);
const
merged
=
[
intervals
[
0
]];
for
(
let
i
=
1
;
i
<
intervals
.
length
;
i
++
)
{
const
prev
=
merged
[
merged
.
length
-
1
];
const
curr
=
intervals
[
i
];
if
(
curr
.
start
<=
prev
.
end
)
{
prev
.
end
=
Math
.
max
(
prev
.
end
,
curr
.
end
);
}
else
{
merged
.
push
(
curr
);
}
}
return
merged
;
};
// 处理空搜索文本
let
textTrim
=
findWordTxt
.
value
.
trim
()
||
""
;
const
searchIntervals
=
textTrim
?
getIntervals
(
text
,
[
textTrim
])
:
[];
const
nounIntervals
=
getIntervals
(
text
,
nounList
.
map
(
n
=>
n
.
text_span
));
// 收集分割点
const
points
=
new
Set
([
0
,
text
.
length
]);
[...
searchIntervals
,
...
nounIntervals
].
forEach
(({
start
,
end
})
=>
{
points
.
add
(
start
);
points
.
add
(
end
);
});
const
sortedPoints
=
Array
.
from
(
points
).
sort
((
a
,
b
)
=>
a
-
b
);
const
list
=
[];
for
(
let
i
=
0
;
i
<
sortedPoints
.
length
-
1
;
i
++
)
{
const
start
=
sortedPoints
[
i
];
const
end
=
sortedPoints
[
i
+
1
];
if
(
start
===
end
)
continue
;
const
fragment
=
text
.
slice
(
start
,
end
);
const
findLight
=
searchIntervals
.
some
(
s
=>
start
>=
s
.
start
&&
end
<=
s
.
end
);
const
highLight
=
nounIntervals
.
some
(
n
=>
start
>=
n
.
start
&&
end
<=
n
.
end
);
const
classes
=
[];
if
(
findLight
)
classes
.
push
(
"find-light"
);
if
(
highLight
)
classes
.
push
(
"high-light"
);
const
textItem
=
{
txt
:
fragment
,
class
:
classes
.
join
(
" "
)
};
if
(
highLight
)
{
const
nounInterval
=
nounIntervals
.
find
(
n
=>
start
>=
n
.
start
&&
end
<=
n
.
end
);
if
(
nounInterval
)
{
textItem
.
fill
=
text
.
slice
(
nounInterval
.
start
,
nounInterval
.
end
);
}
}
list
.
push
(
textItem
);
// 实体区间结束后添加图标
const
iconAdded
=
new
Set
();
for
(
const
nounInterval
of
nounIntervals
)
{
const
key
=
`
${
nounInterval
.
start
}
-
${
nounInterval
.
end
}
`
;
if
(
end
===
nounInterval
.
end
&&
!
iconAdded
.
has
(
key
))
{
list
.
push
({
icon
:
true
,
class
:
""
});
iconAdded
.
add
(
key
);
break
;
}
}
// 搜索区间结束后添加锚点
const
pointAdded
=
new
Set
();
for
(
const
searchInterval
of
searchIntervals
)
{
const
key
=
`
${
searchInterval
.
start
}
-
${
searchInterval
.
end
}
`
;
if
(
end
===
searchInterval
.
end
&&
!
pointAdded
.
has
(
key
))
{
findWordMax
.
value
++
;
list
.
push
({
point
:
true
,
class
:
""
});
pointAdded
.
add
(
key
);
break
;
}
}
}
return
list
;
};
// 点击高亮实体
import
{
useGotoSearchResults
}
from
"@/router/modules/comprehensiveSearch"
;
const
gotoSearchResults
=
useGotoSearchResults
();
const
handleHighLight
=
(
node
)
=>
{
gotoSearchResults
(
node
.
fill
,
''
)
}
</
script
>
<
style
lang=
"scss"
scoped
>
.is-highlight
.high-light
{
color
:
var
(
--
color-primary-100
);
cursor
:
pointer
;
}
.find-light
{
background-color
:
#ffff00
;
}
.layout-container
{
width
:
100%
;
height
:
100%
;
background-color
:
#f7f8f9
;
.layout-main
{
height
:
100%
;
display
:
flex
;
flex-direction
:
column
;
align-items
:
center
;
.layout-main-center
{
width
:
1600px
;
background-color
:
white
;
padding
:
0
60px
;
flex
:
auto
;
height
:
100%
;
min-height
:
0
;
display
:
flex
;
flex-direction
:
column
;
.report-header
{
height
:
80px
;
display
:
flex
;
align-items
:
center
;
border-bottom
:
solid
1px
rgba
(
234
,
236
,
238
,
1
);
margin
:
0
20px
10px
;
position
:
relative
;
.find-word-box
{
position
:
absolute
;
top
:
-50px
;
right
:
0px
;
width
:
430px
;
height
:
60px
;
border
:
1px
solid
rgba
(
230
,
231
,
232
,
1
);
background-color
:
white
;
border-radius
:
6px
;
display
:
flex
;
align-items
:
center
;
.find-word-input
{
flex
:
auto
;
}
.find-word-limit
{
border-right
:
solid
1px
rgba
(
230
,
231
,
232
,
1
);
color
:
#5f656c
;
padding-right
:
16px
;
}
.find-word-icon
{
padding
:
10px
12px
;
margin
:
0
2px
;
cursor
:
pointer
;
}
}
.report-title
{
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
20px
;
line-height
:
20px
;
font-weight
:
700
;
flex
:
1
;
}
.btn
{
margin-left
:
10px
;
width
:
88px
;
height
:
32px
;
box-sizing
:
border-box
;
border
:
1px
solid
rgba
(
230
,
231
,
232
,
1
);
border-radius
:
6px
;
background
:
rgba
(
255
,
255
,
255
,
1
);
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
cursor
:
pointer
;
.text
{
height
:
24px
;
color
:
rgba
(
95
,
101
,
108
,
1
);
font-family
:
Microsoft
YaHei
;
font-style
:
Regular
;
font-size
:
14px
;
font-weight
:
400
;
line-height
:
24px
;
letter-spacing
:
0px
;
text-align
:
left
;
}
.icon
{
width
:
16px
;
height
:
16px
;
font-size
:
0px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.icon-gap-4
{
margin-right
:
4px
;
}
.icon-gap-6
{
margin-right
:
6px
;
}
}
}
.report-main
{
flex
:
auto
;
height
:
20px
;
padding
:
10px
0
;
:deep
(
.el-scrollbar
)
{
height
:
100%
;
}
.no-content
{
height
:
100%
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
Microsoft
YaHei
;
font-style
:
Regular
;
font-size
:
20px
;
font-weight
:
400
;
}
.content-row
{
display
:
flex
;
width
:
100%
;
padding
:
0
20px
;
min-height
:
100px
;
gap
:
80px
;
.content-en
,
.content-ch
{
width
:
50%
;
flex
:
auto
;
padding-bottom
:
40px
;
box-sizing
:
border-box
;
font-size
:
16px
;
line-height
:
1
.8
;
color
:
#3b414b
;
font-family
:
Microsoft
YaHei
;
text-align
:
justify
;
white-space
:
pre-wrap
;
}
.only-show
{
padding-bottom
:
10px
;
}
}
}
}
}
}
.switch-label
{
margin-left
:
6px
;
}
.switch-label-left
{
margin-right
:
10px
;
}
:deep
(
.el-scrollbar__bar.is-vertical
)
{
right
:
0px
;
width
:
4px
;
background
:
transparent
;
border-radius
:
2px
;
&
>
div
{
background
:
#c5c7c9
;
opacity
:
1
;
}
&
>
div
:hover
{
background
:
#505357
;
}
}
</
style
>
src/router/index.js
浏览文件 @
8d534f1e
...
...
@@ -70,7 +70,9 @@ router.beforeEach((to, from, next) => {
if
(
to
.
meta
.
dynamicTitle
)
{
console
.
log
(
'to'
,
to
);
const
storageKey
=
to
.
meta
.
titleStorageKey
||
"curTabName"
;
document
.
title
=
window
.
sessionStorage
.
getItem
(
storageKey
)
||
to
.
meta
.
title
;
// 新开页签时 sessionStorage 不共享,优先用 query 带过来的 title/name
const
queryTitle
=
(
to
.
query
&&
(
to
.
query
.
title
||
to
.
query
.
name
))
?
String
(
to
.
query
.
title
||
to
.
query
.
name
)
:
""
;
document
.
title
=
queryTitle
||
window
.
sessionStorage
.
getItem
(
storageKey
)
||
to
.
meta
.
title
;
}
else
{
document
.
title
=
to
.
meta
.
title
...
...
src/router/modules/decree.js
浏览文件 @
8d534f1e
...
...
@@ -88,7 +88,8 @@ const decreeRoutes = [
component
:
Institution
,
meta
:
{
title
:
"行政机构主页"
,
dynamicTitle
:
true
dynamicTitle
:
true
,
titleStorageKey
:
"institutionTabName"
}
},
{
...
...
src/styles/bill-tokens.scss
0 → 100644
浏览文件 @
8d534f1e
// Bill layout & visual tokens
// 统一用于 bill 板块布局改造,后续可并入全局设计变量体系
// spacing
$bill-space-8
:
8px
;
$bill-space-12
:
12px
;
$bill-space-16
:
16px
;
$bill-space-24
:
24px
;
$bill-space-30
:
30px
;
// layout
$bill-column-gap
:
16px
;
$bill-left-column-width
:
1064px
;
$bill-right-column-width
:
520px
;
// typography
$bill-title-font-size
:
16px
;
$bill-title-font-weight
:
600
;
$bill-body-font-size
:
14px
;
$bill-body-font-weight
:
400
;
// surface
$bill-panel-radius
:
8px
;
$bill-panel-border-color
:
#e8ecf3
;
$bill-panel-shadow
:
0
2px
8px
rgba
(
15
,
35
,
95
,
0
.06
);
$bill-panel-bg
:
#ffffff
;
// text & color
$bill-text-primary
:
#1f2a44
;
$bill-text-secondary
:
#5b6b88
;
$bill-text-muted
:
#8b97ad
;
$bill-color-accent
:
#2f66ff
;
$bill-color-success
:
#19be6b
;
$bill-color-warning
:
#ff9f43
;
$bill-color-danger
:
#f56c6c
;
src/views/bill/BILL_LAYOUT_UNIFICATION_PLAN.md
0 → 100644
浏览文件 @
8d534f1e
# Bill 板块布局统一改造计划
> 目标:统一 `@src/views/bill` 下页面布局与视觉风格,解决“底部 30px 留白不稳定”问题,并沉淀可复用布局组件,便于后续新会话直接接续执行。
## 1. 背景与问题
当前
`bill`
板块存在以下共性问题:
1.
页面布局实现不统一(外层滚动、内层滚动、固定高度混用)。
2.
多数页面为“左右两列 + 多卡片”结构,但容器命名、间距、宽高策略不一致。
3.
`30px`
底部留白在不同页面生效机制不同,容易出现:
-
某页不生效
-
增加占位后挤压布局
-
Header(Tab/操作按钮)受影响
4.
样式硬编码较多(固定宽高、局部 margin/padding),复用性低。
## 2. 总体改造策略
采用“
**分层统一 + 渐进迁移**
”策略,避免一次性大改风险:
-
**第一层:板块承载层统一**
-
统一滚动、内容宽度、底部安全留白机制。
-
**第二层:页面布局骨架统一**
-
抽象“页面壳 + 双列布局 + 卡片容器”组件。
-
**第三层:业务页迁移**
-
先迁移典型页,再批量替换。
## 3. 分阶段计划
### 阶段 A:基线确认与止血(进行中)
-
修复当前试错引入的结构问题(例如模板闭合错误、布局挤压)。
-
保证关键页面可用:
-
`background`
-
`processAnalysis`
-
`introdoction`
### 阶段 B:新增通用布局组件(进行中)
#### 完成备注(2026-04-02)
-
[
x
]
第一步已完成并通过验收:完成布局组件目录与基础文件脚手架
-
`src/views/bill/components/layout/BillPageShell.vue`
-
`src/views/bill/components/layout/BillTwoColumn.vue`
-
`src/views/bill/components/layout/BillPanel.vue`
-
`src/views/bill/components/layout/index.js`
-
[
x
]
第二步已完成并通过验收:实现
`BillPageShell`
滚动容器与底部
`30px`
安全留白机制
-
[
x
]
第三步已完成并通过验收:实现
`BillTwoColumn`
统一双列布局(1064/520 + gap 16 + 响应式堆叠)
-
[
x
]
第四步已完成并通过验收:实现
`BillPanel`
统一卡片结构与基础样式(header/body/footer + 可配置边框/圆角/阴影)
-
[
x
]
第五步已完成并通过验收:
`bill-tokens.scss`
接入
`BillPageShell/BillTwoColumn/BillPanel`
并替换关键样式硬编码
-
[
x
]
第六步已完成并通过验收:试点页
`background/index.vue`
已迁移到统一布局骨架(
`BillPageShell + BillTwoColumn`
)
-
[
x
]
第六步修正项(验收反馈已落实):
-
修正 1:移除
`.right-panel`
的
`margin-left/margin-right`
,避免右列偏移与原样式不一致
-
修正 2:
`BillPageShell`
不再使用内部滚动容器;页面滚动回到外层
`layout-main`
,确保 Header 与内容一起滚动
-
[
x
]
第七步已完成并通过验收:
`introdoction/index.vue`
迁移到统一布局骨架(
`BillPageShell + BillTwoColumn`
)
-
[
x
]
第七步修正项(验收反馈已落实):
-
修正 1:移除
`.introduction-wrap-right`
的
`margin-left/margin-right`
,消除右列偏移
-
修正 2:在
`.introduction-wrap-content`
增加
`margin-bottom: 30px`
,确保外层滚动时可见底部留白
-
[
x
]
第八步已完成并通过验收:
`template/index.vue`
迁移到统一布局骨架(
`BillPageShell + BillTwoColumn`
)
-
[
x
]
第八步注意点(已沉淀):
-
删除
`page-bottom-gap`
占位节点,避免与统一留白策略重复
-
在双列容器
`.content-row`
增加
`margin-bottom: 30px`
,适配“外层
`layout-main`
滚动”模式
-
迁移后需检查未使用变量并清理,避免 lint 噪音影响后续页面迁移
-
[
x
]
第九步已完成并通过验收:
`deepDig/processOverview/index.vue`
迁移到统一页面壳(
`BillPageShell`
)
-
[
x
]
第九步注意点(已沉淀):
-
保留页面内部横向滚动容器(
`.main`
),仅替换页面根壳,避免时间轴布局回归风险
-
删除
`page-bottom-gap`
,改用页面容器底部留白(
`margin-bottom: 30px`
)适配外层滚动
-
[
x
]
第十步已完成并通过验收:
`deepDig/processAnalysis/index.vue`
迁移到统一页面壳(
`BillPageShell`
)
-
[
x
]
第十步注意点(已沉淀):
-
保持原双列业务结构与内部滚动策略不变,仅替换页面根壳
-
页面底部留白统一为容器
`margin-bottom: 30px`
,与外层
`layout-main`
滚动机制一致
新增组件建议放在:
`src/views/bill/components/layout/`
#### 计划新增组件索引
1.
`src/views/bill/components/layout/BillPageShell.vue`
-
作用:统一页面根容器、内容区、底部留白(30px)机制。
2.
`src/views/bill/components/layout/BillTwoColumn.vue`
-
作用:统一左右列布局(默认 1064 / 520)、列间距、响应式策略。
3.
`src/views/bill/components/layout/BillPanel.vue`
-
作用:统一卡片容器(header/body/footer)结构、间距、基础样式。
4.
`src/views/bill/components/layout/index.js`
-
作用:导出布局组件,便于页面统一引入。
> 可选(后续):
> - `BillPanelGroup.vue`(同列多卡片统一间距)
> - `BillPageSection.vue`(统一页面内 section 标题与辅助动作区)
### 阶段 C:样式 Token 统一(计划)
新增:
`src/styles/bill-tokens.scss`
(或接入现有变量体系)
-
间距:
`8/12/16/24/30`
-
列间距:
`16`
-
标题字号/字重
-
卡片边框、阴影、圆角
-
统一颜色 token(主文字、次文字、强调色)
### 阶段 D:页面迁移(计划)
按“先典型、后批量”执行:
1.
试点页(先迁移)
-
`background/index.vue`
(典型双列 + 卡片 + 多交互)
2.
法案概况组
-
`introdoction/index.vue`
-
`template/index.vue`
-
`background/index.vue`
3.
深度挖掘组
-
`deepDig/processOverview/index.vue`
-
`deepDig/processAnalysis/index.vue`
-
`deepDig/poliContribution/index.vue`
4.
影响分析组
-
`influence/industry/index.vue`
-
`influence/scientificResearch/index.vue`
-
`influence/index.vue`
(承载层)
### 阶段 E:收口与回归(计划)
-
清理临时样式补丁(历史试错
`gap/margin-bottom`
等)。
-
回归检查:
1.
所有页面底部留白可见
2.
无横向滚动条
3.
Header 不丢失
4.
双列不挤压
## 4. 现有页面索引(改造范围)
### 4.1 板块承载与导航层
-
`src/views/bill/billLayout/index.vue`
-
`src/views/bill/billLayout/components/BillHeader.vue`
-
`src/views/bill/index.vue`
-
`src/views/bill/deepDig/index.vue`
-
`src/views/bill/influence/index.vue`
### 4.2 法案概况(Bill)
-
`src/views/bill/introdoction/index.vue`
-
`src/views/bill/background/index.vue`
-
`src/views/bill/template/index.vue`
-
`src/views/bill/billOriginalText/index.vue`
### 4.3 深度挖掘(DeepDig)
-
`src/views/bill/deepDig/processOverview/index.vue`
-
`src/views/bill/deepDig/processAnalysis/index.vue`
-
`src/views/bill/deepDig/poliContribution/index.vue`
### 4.4 影响分析(Influence)
-
`src/views/bill/influence/industry/index.vue`
-
`src/views/bill/influence/scientificResearch/index.vue`
-
`src/views/bill/influence/ProgressForecast/index.vue`
### 4.5 其他相关页面
-
`src/views/bill/relevantCircumstance/index.vue`
-
`src/views/bill/versionCompare/index.vue`
-
`src/views/bill/billHome/index.vue`
## 5. 迁移原则(执行时必须遵守)
1.
不改变业务逻辑(API、状态、路由行为)
2.
先替换布局骨架,再替换样式细节
3.
每次只迁移少量页面,保证可回滚
4.
对“固定高度 + 内部滚动”页面优先保守改造
5.
若页面是横向 flex 主体,禁止直接插入会改变横向布局的占位节点
## 6. 验收标准
1.
`@bill`
目标页面滚动到底统一可见
`30px`
留白
2.
页面核心布局(左右列、卡片)不变形
3.
`BillHeader`
的 Tab 与功能按钮稳定显示
4.
不新增横向滚动条
5.
关键路由刷新后视觉一致
## 7. 新会话接续建议
新会话可直接按以下顺序继续:
1.
先读取本文件:
-
`src/views/bill/BILL_LAYOUT_UNIFICATION_PLAN.md`
2.
先完成组件脚手架:
-
`BillPageShell.vue`
-
`BillTwoColumn.vue`
-
`BillPanel.vue`
3.
首个迁移页:
-
`src/views/bill/background/index.vue`
4.
迁移完成后逐页扩展到
`introdoction/template/processOverview/processAnalysis`
---
最后更新:2026-04-02
src/views/bill/background/index.vue
浏览文件 @
8d534f1e
<
template
>
<div
class=
"background-wrap"
>
<BillPageShell
class=
"background-page"
>
<BillTwoColumn
class=
"background-content"
:stack-on-narrow=
"false"
>
<template
#
left
>
<div
class=
"background-wrap-left"
>
<AnalysisBox
class=
"left-box left-box--background"
title=
"立法背景"
:showAllBtn=
"false"
:devTip=
"true"
>
<template
#
header-btn
>
...
...
@@ -22,8 +24,13 @@
<div
class=
"info"
>
{{ totalText }}
</div>
<el-pagination
background
layout=
"prev, pager, next"
:total=
"total"
v-model:current-page=
"currentPage"
@
current-change=
"handleGetBillBackground"
/>
<el-pagination
background
layout=
"prev, pager, next"
:total=
"total"
v-model:current-page=
"currentPage"
@
current-change=
"handleGetBillBackground"
/>
</div>
</div>
</AnalysisBox>
...
...
@@ -47,6 +54,9 @@
</div>
</AnalysisBox>
</div>
</template>
<
template
#
right
>
<AnalysisBox
class=
"right-panel"
title=
"议员相关性分析"
:showAllBtn=
"false"
:devTip=
"true"
>
<template
#
header-btn
>
<div
class=
"header-btn-box"
>
...
...
@@ -83,8 +93,7 @@
</el-icon>
</div>
<div
class=
"right-box1-main-bottom"
>
<WordCloudMap
:data=
"wordCloudData"
:selectedName=
"selectedIndustryName"
shape=
"circle"
@
wordClick=
"handleWordClick"
/>
<WordCloudMap
:data=
"wordCloudData"
:selectedName=
"selectedIndustryName"
shape=
"circle"
@
wordClick=
"handleWordClick"
/>
</div>
</div>
<div
class=
"right-box2"
>
...
...
@@ -111,7 +120,9 @@
</div>
</div>
</AnalysisBox>
</div>
</template>
</BillTwoColumn>
</BillPageShell>
</template>
<
script
setup
>
...
...
@@ -119,6 +130,7 @@ import { computed, onMounted, ref } from "vue";
import
{
useRoute
,
useRouter
}
from
"vue-router"
;
import
WordCloudMap
from
"./WordCloudMap.vue"
;
import
CommonPrompt
from
"../commonPrompt/index.vue"
;
import
{
BillPageShell
,
BillTwoColumn
}
from
"../components/layout"
;
import
userIcon
from
"./assets/icons/user-icon.png"
;
import
userIcon1
from
"./assets/icons/user-icon1.png"
;
import
userIcon2
from
"./assets/icons/user-icon2.png"
;
...
...
@@ -400,16 +412,31 @@ onMounted(() => {
}
}
.background-
wrap
{
.background-
page
{
width
:
100%
;
height
:
100%
;
box-sizing
:
border-box
;
display
:
flex
;
}
.background-content
{
width
:
100%
;
height
:
auto
;
box-sizing
:
border-box
;
align-items
:
flex-start
;
:deep
(
.bill-two-column__left
)
{
width
:
1064px
;
}
:deep
(
.bill-two-column__right
)
{
width
:
520px
;
margin-right
:
18px
;
}
.background-wrap-left
{
width
:
1064px
;
margin-top
:
16px
;
margin-bottom
:
30px
;
.left-box
{
width
:
1064px
;
...
...
@@ -600,9 +627,8 @@ onMounted(() => {
}
}
.right-panel
{
margin-right
:
18px
;
margin-left
:
16px
;
margin-top
:
16px
;
width
:
520px
;
max-height
:
824px
;
...
...
src/views/bill/billLayout/components/BillHeader.vue
浏览文件 @
8d534f1e
...
...
@@ -61,7 +61,7 @@
</div>
<div
class=
"right-box-bottom"
v-if=
"showActions"
>
<div
class=
"btn2"
@
click=
"emit('open-analysis', 'forsee')"
>
<div
class=
"btn2"
v-if=
"showForsee"
@
click=
"emit('open-analysis', 'forsee')"
>
<div
class=
"icon"
>
<img
:src=
"btnIconForsee"
alt=
""
/>
</div>
...
...
@@ -108,6 +108,10 @@ const props = defineProps({
showActions
:
{
type
:
Boolean
,
default
:
true
},
showForsee
:
{
type
:
Boolean
,
default
:
true
}
});
...
...
@@ -154,9 +158,7 @@ const emit = defineEmits(["tab-click", "open-analysis"]);
}
.header-main
{
position
:
sticky
;
top
:
0
;
z-index
:
1000
;
position
:
relative
;
width
:
100%
;
background-color
:
#fff
;
box-shadow
:
0px
4px
10px
0px
rgba
(
0
,
0
,
0
,
0
.05
);
...
...
src/views/bill/billLayout/index.vue
浏览文件 @
8d534f1e
...
...
@@ -4,7 +4,8 @@
<div
class=
"layout-main"
>
<BillHeader
:billInfo=
"billInfoGlobal"
:defaultLogo=
"USALogo"
:tabs=
"mainHeaderBtnList"
:activeTitle=
"activeTitle"
:showTabs=
"showHeaderTabs"
:showActions=
"showHeaderActions"
@
tab-click=
"handleClickMainHeaderBtn"
@
open-analysis=
"handleAnalysisClick"
/>
:showForsee=
"showForseeAction"
@
tab-click=
"handleClickMainHeaderBtn"
@
open-analysis=
"handleAnalysisClick"
/>
<div
class=
"layout-main-center"
>
<router-view
/>
...
...
@@ -14,10 +15,10 @@
</
template
>
<
script
setup
>
import
{
ref
,
onMounted
,
watch
}
from
"vue"
;
import
{
ref
,
onMounted
,
watch
,
computed
}
from
"vue"
;
import
router
from
"@/router"
;
import
{
useRoute
}
from
"vue-router"
;
import
{
getBillInfoGlobal
}
from
"@/api/bill"
;
import
{
getBillInfoGlobal
,
getBillInfo
}
from
"@/api/bill"
;
import
BillHeader
from
"./components/BillHeader.vue"
;
const
route
=
useRoute
();
...
...
@@ -77,6 +78,25 @@ const activeTitle = ref("法案概况");
const
showHeaderTabs
=
ref
(
true
);
const
showHeaderActions
=
ref
(
true
);
const
billBasicInfo
=
ref
({});
const
getBillBasicInfoFn
=
async
()
=>
{
const
billId
=
route
.
query
.
billId
;
if
(
!
billId
)
return
;
try
{
const
res
=
await
getBillInfo
({
id
:
billId
});
billBasicInfo
.
value
=
res
?.
data
||
{};
}
catch
(
error
)
{
console
.
error
(
error
);
billBasicInfo
.
value
=
{};
}
};
const
showForseeAction
=
computed
(()
=>
{
const
stageList
=
Array
.
isArray
(
billBasicInfo
.
value
?.
stageList
)
?
billBasicInfo
.
value
.
stageList
:
[];
const
latestStage
=
stageList
.
length
?
String
(
stageList
[
stageList
.
length
-
1
]
||
""
).
trim
()
:
""
;
return
!
latestStage
.
includes
(
"完成立法"
);
});
const
getActiveTitleByRoutePath
=
path
=>
{
if
(
path
.
startsWith
(
"/billLayout/deepDig"
))
return
"深度挖掘"
;
if
(
path
.
startsWith
(
"/billLayout/influence"
))
return
"影响分析"
;
...
...
@@ -132,6 +152,7 @@ const handleAnalysisClick = analysisType => {
onMounted
(()
=>
{
getBillInfoGlobalFn
();
getBillBasicInfoFn
();
// 以当前路由为准,避免 sessionStorage 造成高亮错乱
syncHeaderStateFromRoute
();
// 兜底:如果未来出现未知路由且有缓存,再用缓存
...
...
@@ -143,6 +164,14 @@ watch(
()
=>
route
.
path
,
()
=>
{
syncHeaderStateFromRoute
();
}
);
watch
(
()
=>
route
.
query
.
billId
,
()
=>
{
getBillInfoGlobalFn
();
getBillBasicInfoFn
();
},
{
immediate
:
true
}
);
...
...
@@ -160,12 +189,12 @@ watch(
width
:
100%
;
height
:
100vh
;
overflow-y
:
auto
;
overflow-x
:
hidden
;
.layout-main-center
{
// height: calc(100% - 137px);
width
:
1600px
;
max-width
:
100%
;
margin
:
0
auto
;
padding-bottom
:
20px
;
}
}
}
...
...
src/views/bill/components/layout/BillPageShell.vue
0 → 100644
浏览文件 @
8d534f1e
<
template
>
<div
class=
"bill-page-shell"
:class=
"shellClass"
:style=
"shellStyle"
>
<div
class=
"bill-page-shell__content"
:class=
"contentClass"
>
<slot
/>
</div>
</div>
</
template
>
<
script
>
const
BILL_DEFAULT_BOTTOM_SAFE_SPACE
=
30
export
default
{
name
:
'BillPageShell'
,
props
:
{
bottomSafeSpace
:
{
type
:
Number
,
default
:
BILL_DEFAULT_BOTTOM_SAFE_SPACE
},
shellClass
:
{
type
:
[
String
,
Array
,
Object
],
default
:
''
},
contentClass
:
{
type
:
[
String
,
Array
,
Object
],
default
:
''
}
},
computed
:
{
shellStyle
()
{
return
{
paddingBottom
:
`
${
this
.
bottomSafeSpace
}
px`
}
}
}
}
</
script
>
<
style
scoped
lang=
"scss"
>
@import
'@/styles/bill-tokens.scss'
;
.bill-page-shell
{
width
:
100%
;
min-height
:
0
;
box-sizing
:
border-box
;
}
.bill-page-shell__content
{
width
:
100%
;
color
:
$bill-text-primary
;
}
</
style
>
src/views/bill/components/layout/BillPanel.vue
0 → 100644
浏览文件 @
8d534f1e
<
template
>
<section
class=
"bill-panel"
:class=
"panelClass"
:style=
"panelStyle"
>
<header
v-if=
"$slots.header"
class=
"bill-panel__header"
:class=
"headerClass"
:style=
"sectionStyle"
>
<slot
name=
"header"
/>
</header>
<div
class=
"bill-panel__body"
:class=
"bodyClass"
:style=
"sectionStyle"
>
<slot
/>
</div>
<footer
v-if=
"$slots.footer"
class=
"bill-panel__footer"
:class=
"footerClass"
:style=
"sectionStyle"
>
<slot
name=
"footer"
/>
</footer>
</section>
</
template
>
<
script
>
const
BILL_DEFAULT_PANEL_PADDING
=
16
const
BILL_DEFAULT_PANEL_RADIUS
=
8
export
default
{
name
:
'BillPanel'
,
props
:
{
panelClass
:
{
type
:
[
String
,
Array
,
Object
],
default
:
''
},
headerClass
:
{
type
:
[
String
,
Array
,
Object
],
default
:
''
},
bodyClass
:
{
type
:
[
String
,
Array
,
Object
],
default
:
''
},
footerClass
:
{
type
:
[
String
,
Array
,
Object
],
default
:
''
},
padding
:
{
type
:
Number
,
default
:
BILL_DEFAULT_PANEL_PADDING
},
borderRadius
:
{
type
:
Number
,
default
:
BILL_DEFAULT_PANEL_RADIUS
},
bordered
:
{
type
:
Boolean
,
default
:
true
},
shadow
:
{
type
:
Boolean
,
default
:
false
},
background
:
{
type
:
String
,
default
:
'#fff'
}
},
computed
:
{
panelStyle
()
{
return
{
background
:
this
.
background
,
borderRadius
:
`
${
this
.
borderRadius
}
px`
,
border
:
this
.
bordered
?
'1px solid #e8ecf3'
:
'none'
,
boxShadow
:
this
.
shadow
?
'0 2px 8px rgba(15, 35, 95, 0.06)'
:
'none'
}
},
sectionStyle
()
{
return
{
padding
:
`
${
this
.
padding
}
px`
}
}
}
}
</
script
>
<
style
scoped
lang=
"scss"
>
@import
'@/styles/bill-tokens.scss'
;
.bill-panel
{
width
:
100%
;
box-sizing
:
border-box
;
color
:
$bill-text-primary
;
}
.bill-panel__header
,
.bill-panel__body
,
.bill-panel__footer
{
width
:
100%
;
box-sizing
:
border-box
;
}
.bill-panel__header
{
padding-bottom
:
$bill-space-12
;
}
.bill-panel__footer
{
padding-top
:
$bill-space-12
;
}
.bill-panel__header
:empty
,
.bill-panel__footer
:empty
{
display
:
none
;
}
</
style
>
src/views/bill/components/layout/BillTwoColumn.vue
0 → 100644
浏览文件 @
8d534f1e
<
template
>
<div
class=
"bill-two-column"
:class=
"wrapperClass"
:style=
"wrapperStyle"
>
<div
class=
"bill-two-column__left"
:style=
"leftStyle"
>
<slot
name=
"left"
/>
</div>
<div
class=
"bill-two-column__right"
:style=
"rightStyle"
>
<slot
name=
"right"
/>
</div>
</div>
</
template
>
<
script
>
const
BILL_DEFAULT_LEFT_WIDTH
=
1064
const
BILL_DEFAULT_RIGHT_WIDTH
=
520
const
BILL_DEFAULT_COLUMN_GAP
=
16
const
BILL_DEFAULT_MIN_STACK_WIDTH
=
1660
export
default
{
name
:
'BillTwoColumn'
,
props
:
{
leftWidth
:
{
type
:
Number
,
default
:
BILL_DEFAULT_LEFT_WIDTH
},
rightWidth
:
{
type
:
Number
,
default
:
BILL_DEFAULT_RIGHT_WIDTH
},
gap
:
{
type
:
Number
,
default
:
BILL_DEFAULT_COLUMN_GAP
},
minStackWidth
:
{
type
:
Number
,
default
:
BILL_DEFAULT_MIN_STACK_WIDTH
},
stackOnNarrow
:
{
type
:
Boolean
,
default
:
true
},
wrapperClass
:
{
type
:
[
String
,
Array
,
Object
],
default
:
''
}
},
computed
:
{
shouldStack
()
{
if
(
!
this
.
stackOnNarrow
||
typeof
window
===
'undefined'
)
{
return
false
}
return
window
.
innerWidth
<
this
.
minStackWidth
},
wrapperStyle
()
{
if
(
this
.
shouldStack
)
{
return
{
display
:
'flex'
,
flexDirection
:
'column'
,
gap
:
`
${
this
.
gap
}
px`
}
}
return
{
display
:
'grid'
,
gridTemplateColumns
:
`
${
this
.
leftWidth
}
px
${
this
.
rightWidth
}
px`
,
columnGap
:
`
${
this
.
gap
}
px`
,
alignItems
:
'start'
}
},
leftStyle
()
{
if
(
this
.
shouldStack
)
{
return
{
width
:
'100%'
}
}
return
{
minWidth
:
'0'
}
},
rightStyle
()
{
if
(
this
.
shouldStack
)
{
return
{
width
:
'100%'
}
}
return
{
minWidth
:
'0'
}
}
}
}
</
script
>
<
style
scoped
lang=
"scss"
>
@import
'@/styles/bill-tokens.scss'
;
.bill-two-column
{
width
:
100%
;
min-width
:
0
;
color
:
$bill-text-primary
;
}
.bill-two-column__left
,
.bill-two-column__right
{
min-width
:
0
;
}
</
style
>
src/views/bill/components/layout/index.js
0 → 100644
浏览文件 @
8d534f1e
import
BillPageShell
from
'./BillPageShell.vue'
import
BillTwoColumn
from
'./BillTwoColumn.vue'
import
BillPanel
from
'./BillPanel.vue'
export
{
BillPageShell
,
BillTwoColumn
,
BillPanel
}
src/views/bill/deepDig/processAnalysis/index.vue
浏览文件 @
8d534f1e
<
template
>
<
div
class=
"wrap"
>
<
BillPageShell
class=
"wrap"
>
<div
class=
"left"
>
<div
class=
"box1"
>
<!--
<div
class=
"box-header"
>
...
...
@@ -31,7 +31,7 @@
</div>
</div>
</div>
-->
<AnalysisBox
title=
"典型阶段耗时"
>
<AnalysisBox
title=
"典型阶段耗时
分析
"
>
<div
class=
"analysis-ai-wrapper analysis-ai-wrapper--box1"
>
<div
class=
"box1-main"
:class=
"
{ 'box1-main--full': !timeFooterText }">
<div
class=
"box1-main-center"
id=
"chart1"
></div>
...
...
@@ -48,7 +48,7 @@
</div>
</div>
<div
v-if=
"!aiPaneVisible.box1"
class=
"analysis-ai-tip-row"
>
<TipTab
class=
"analysis-ai-tip"
/>
<TipTab
class=
"analysis-ai-tip"
:text=
"'与历史同类法案的典型阶段耗时对比分析,数据来源:美国国会官网'"
/>
<AiButton
class=
"analysis-ai-tip-action"
@
mouseenter=
"handleShowAiPane('box1')"
/>
</div>
<div
v-if=
"aiPaneVisible.box1"
class=
"analysis-ai-pane"
@
mouseleave=
"handleHideAiPane('box1')"
>
...
...
@@ -105,7 +105,7 @@
</div>
</div>
<div
v-if=
"!aiPaneVisible.box2"
class=
"analysis-ai-tip-row"
>
<TipTab
class=
"analysis-ai-tip"
/>
<TipTab
class=
"analysis-ai-tip"
:text=
"'与历史同类法案的修正案次数对比分析,数据来源:美国国会官网'"
/>
<AiButton
class=
"analysis-ai-tip-action"
@
mouseenter=
"handleShowAiPane('box2')"
/>
</div>
<div
v-if=
"aiPaneVisible.box2"
class=
"analysis-ai-pane"
@
mouseleave=
"handleHideAiPane('box2')"
>
...
...
@@ -716,7 +716,7 @@
<
/AnalysisBox
>
<
/div
>
<
/div
>
<
/
div
>
<
/
BillPageShell
>
<
/template
>
<
script
setup
>
...
...
@@ -728,6 +728,7 @@ import { getChartAnalysis } from "@/api/aiAnalysis/index";
import
TipTab
from
"@/components/base/TipTab/index.vue"
;
import
AiButton
from
"@/components/base/Ai/AiButton/index.vue"
;
import
AiPane
from
"@/components/base/Ai/AiPane/index.vue"
;
import
{
BillPageShell
}
from
"../../components/layout"
;
import
icon1
from
"./assets/images/icon1.png"
;
import
icon2
from
"./assets/images/icon2.png"
;
...
...
@@ -1160,7 +1161,7 @@ onMounted(async () => {
min
:
"最小次数"
,
current
:
"该法案修正案数量"
}
;
let
chart2
=
getBoxPlotChcart
(
chartData2
.
value
,
"
次
"
,
countLabels
);
let
chart2
=
getBoxPlotChcart
(
chartData2
.
value
,
"
项
"
,
countLabels
);
setChart
(
chart2
,
"chart2"
);
}
);
<
/script
>
...
...
@@ -1168,6 +1169,8 @@ onMounted(async () => {
<
style
lang
=
"scss"
scoped
>
.
wrap
{
display
:
flex
;
margin
-
bottom
:
30
px
;
.
box
-
header
{
height
:
56
px
;
...
...
src/views/bill/deepDig/processOverview/index.vue
浏览文件 @
8d534f1e
<
template
>
<
div
class=
"process-overview-wrap"
>
<
BillPageShell
class=
"process-overview-wrap"
>
<AnalysisBox
title=
"流程概要"
:showAllBtn=
"false"
>
<div
class=
"main"
>
<div
class=
"left"
:style=
"
{ width: boardWidth + 'px' }">
...
...
@@ -194,7 +194,7 @@
:position=
"dialogPos"
@
close=
"handleClickDetail(false)"
/>
</
div
>
</
BillPageShell
>
</
template
>
<
script
setup
>
...
...
@@ -202,6 +202,7 @@ import { ref, onMounted, computed, nextTick } from "vue";
import
{
getBillDyqkSummary
}
from
"@/api/bill"
;
import
CommonPrompt
from
"../../commonPrompt/index.vue"
;
import
ProcessOverviewDetailDialog
from
"../../ProcessOverviewDetailDialog.vue"
;
import
{
BillPageShell
}
from
"../../components/layout"
;
const
actionList
=
ref
([]);
const
isShowDetailDialog
=
ref
(
false
);
...
...
@@ -499,6 +500,7 @@ const updateRightTop = () => {
width
:
1600px
;
height
:
848px
;
margin-top
:
16px
;
margin-bottom
:
30px
;
position
:
relative
;
.main
{
...
...
@@ -799,20 +801,13 @@ const updateRightTop = () => {
.text
{
width
:
240px
;
max-width
:
100%
;
color
:
rgb
(
59
,
65
,
75
);
font-size
:
16px
;
line-height
:
24px
;
display
:
-
webkit-box
;
line-clamp
:
2
;
-webkit-line-clamp
:
2
;
-webkit-box-orient
:
vertical
;
white-space
:
nowrap
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
height
:
48px
;
}
:deep
(
.text-ellipsis
)
{
white-space
:
normal
!
important
;
}
}
}
...
...
src/views/bill/introdoction/index.vue
浏览文件 @
8d534f1e
<
template
>
<
div
class=
"introduction-wrap"
>
<
BillPageShell
class=
"introduction-wrap"
>
<WarningPane
v-if=
"riskSignal"
class=
"risk-signal-pane-top"
:warnningLevel=
"riskSignal.riskLevel"
:warnningContent=
"riskSignal.riskContent"
/>
<div
class=
"introduction-wrap-content"
>
<BillTwoColumn
class=
"introduction-wrap-content"
:stack-on-narrow=
"false"
>
<template
#
left
>
<div
class=
"introduction-wrap-left"
>
<div
class=
"introduction-wrap-left-box1"
>
...
...
@@ -70,6 +71,8 @@
<
/AnalysisBox
>
<
/div
>
<
/div
>
<
/template
>
<
template
#
right
>
<
div
class
=
"introduction-wrap-right"
>
<
AnalysisBox
title
=
"提出人"
:
showAllBtn
=
"false"
>
<
div
class
=
"introduction-wrap-right-main"
>
...
...
@@ -141,8 +144,9 @@
<
/div
>
<
/AnalysisBox
>
<
/div
>
<
/div
>
<
/div
>
<
/template
>
<
/BillTwoColumn
>
<
/BillPageShell
>
<
/template
>
<
script
setup
>
...
...
@@ -151,6 +155,7 @@ import { useRoute, useRouter } from "vue-router";
import
WordCloudMap
from
"./WordCloudMap.vue"
;
import
STimeline
from
"./STimeline.vue"
;
import
WarningPane
from
"@/components/base/WarningPane/index.vue"
;
import
{
BillPageShell
,
BillTwoColumn
}
from
"../components/layout"
;
import
{
getBillInfo
,
getBillPerson
,
getBillEvent
,
getBillDyqk
}
from
"@/api/bill"
;
import
{
getPersonSummaryInfo
}
from
"@/api/common/index"
;
import
defaultAvatar
from
"../assets/images/default-icon1.png"
;
...
...
@@ -338,6 +343,14 @@ onMounted(() => {
height
:
auto
;
display
:
flex
;
flex
-
direction
:
column
;
box
-
sizing
:
border
-
box
;
.
page
-
bottom
-
gap
{
height
:
30
px
;
width
:
100
%
;
flex
-
shrink
:
0
;
pointer
-
events
:
none
;
}
.
progress
-
header
-
btns
{
display
:
flex
;
...
...
@@ -432,6 +445,7 @@ onMounted(() => {
.
introduction
-
wrap
-
content
{
display
:
flex
;
margin
-
bottom
:
30
px
;
}
.
introduction
-
wrap
-
left
{
...
...
@@ -497,7 +511,6 @@ onMounted(() => {
flex
-
wrap
:
wrap
;
align
-
items
:
center
;
width
:
700
px
;
min
-
height
:
40
px
;
gap
:
8
px
;
.
right1
-
item
{
...
...
@@ -769,8 +782,6 @@ onMounted(() => {
.
introduction
-
wrap
-
right
{
margin
-
top
:
16
px
;
margin
-
left
:
16
px
;
margin
-
right
:
18
px
;
width
:
520
px
;
height
:
845
px
;
...
...
src/views/bill/template/index.vue
浏览文件 @
8d534f1e
<
template
>
<
div
class=
"temp-wrap"
>
<
BillPageShell
class=
"temp-wrap"
>
<div
class=
"tools-row"
>
<div
class=
"tools-row-left"
>
<el-select
v-model=
"curBill"
placeholder=
"请选择版本"
@
change=
"handleChangeBill"
...
...
@@ -39,7 +39,8 @@
</div>
</div>
</div>
<div
class=
"content-row"
>
<BillTwoColumn
class=
"content-row"
:left-width=
"520"
:right-width=
"1064"
:stack-on-narrow=
"false"
>
<
template
#
left
>
<div
class=
"side"
>
<div
class=
"side-box side-box-domain"
>
<AnalysisBox
title=
"涉及领域"
width=
"520px"
height=
"415px"
v-loading=
"domainLoading"
>
...
...
@@ -94,6 +95,8 @@
</AnalysisBox>
</div>
</div>
</
template
>
<
template
#
right
>
<div
class=
"terms"
>
<div
class=
"terms-switch"
>
<span
class=
"terms-switch-label"
>
高亮实体
</span>
...
...
@@ -103,6 +106,10 @@
active-text=
"开"
inactive-text=
"关"
/>
<span
v-if=
"termsEntityLoading"
class=
"terms-entity-loading"
>
<el-icon
class=
"is-loading"
><Loading
/></el-icon>
实体识别中(剩余
{{
termsEntityPendingCount
}}
条)
</span>
<span
class=
"terms-switch-divider"
></span>
<span
class=
"terms-switch-label"
>
显示原文
</span>
<el-switch
...
...
@@ -112,7 +119,7 @@
inactive-text=
"关"
/>
</div>
<AnalysisBox
title=
"主要条款"
:showAllBtn=
"false"
v-loading=
"termsLoading"
>
<AnalysisBox
title=
"主要条款"
:showAllBtn=
"false"
height=
"auto"
v-loading=
"termsLoading"
>
<div
class=
"left-main"
>
<div
class=
"left-main-item"
v-for=
"(term, index) in displayTermsList"
:key=
"getTermKey(term, index)"
>
<div
class=
"term-body"
>
...
...
@@ -120,11 +127,23 @@
<div
class=
"term-main"
>
<div
class=
"term-row term-row-cn"
>
<div
class=
"term-no-cn"
>
第
{{
term
.
tkxh
}}
条.
</div>
<div
class=
"term-content-cn"
v-html=
"getTermContentHtml(term, 'cn')"
></div>
<div
class=
"term-content-cn"
>
<IntelligentEntityText
:text=
"term?.fynr || ''"
:entities=
"termsHighlight ? getTermEntities(term, 'cn') : []"
@
on-entity-click=
"e => gotoSearchResults(e.text_span, '')"
/>
</div>
</div>
<div
class=
"term-row term-row-en"
v-if=
"termsShowOriginal"
>
<div
class=
"term-no-en"
>
Sec.
{{
term
.
tkxh
}}
</div>
<div
class=
"term-content-en"
v-html=
"getTermContentHtml(term, 'en')"
></div>
<div
class=
"term-content-en"
>
<IntelligentEntityText
:text=
"term?.ywnr || ''"
:entities=
"termsHighlight ? getTermEntities(term, 'en') : []"
@
on-entity-click=
"e => gotoSearchResults(e.text_span, '')"
/>
</div>
</div>
</div>
</div>
...
...
@@ -145,15 +164,16 @@
<
/div
>
<
/AnalysisBox
>
<
/div
>
</div>
</div>
<
/template
>
<
/BillTwoColumn
>
<
/BillPageShell
>
<
/template
>
<
script
setup
>
import
{
ref
,
onMounted
,
onBeforeUnmount
,
computed
,
watch
}
from
"vue"
;
import
{
useRoute
,
onBeforeRouteLeave
}
from
"vue-router"
;
import
*
as
echarts
from
"echarts"
;
import
{
Search
}
from
"@element-plus/icons-vue"
;
import
{
Search
,
Loading
}
from
"@element-plus/icons-vue"
;
import
getPieChart
from
"./utils/piechart"
;
import
{
getBillContentId
,
getBillContentTk
,
getBillContentXzfs
,
getBillHyly
}
from
"@/api/bill"
;
import
{
getChartAnalysis
}
from
"@/api/aiAnalysis/index"
;
...
...
@@ -162,9 +182,12 @@ import AiButton from "@/components/base/Ai/AiButton/index.vue";
import
AiPane
from
"@/components/base/Ai/AiPane/index.vue"
;
import
{
MUTICHARTCOLORS
}
from
"@/common/constant"
;
import
{
extractTextEntity
}
from
"@/api/intelligent/index"
;
import
{
useGotoSearchResults
}
from
"@/router/modules/comprehensiveSearch"
;
import
IntelligentEntityText
from
"@/components/base/texts/IntelligentEntityText.vue"
;
import
{
BillPageShell
,
BillTwoColumn
}
from
"../components/layout"
;
const
route
=
useRoute
();
const
gotoSearchResults
=
useGotoSearchResults
();
const
pageAbortController
=
new
AbortController
();
const
isRequestCanceled
=
error
=>
{
...
...
@@ -186,6 +209,8 @@ const stopCurrentPageRequests = () => {
hylyRequestToken
.
value
+=
1
;
entityRequestToken
.
value
+=
1
;
termsLoading
.
value
=
false
;
termsEntityLoading
.
value
=
false
;
termsEntityPendingCount
.
value
=
0
;
limitLoading
.
value
=
false
;
domainLoading
.
value
=
false
;
aiPaneLoading
.
value
=
{
domain
:
false
,
limit
:
false
}
;
...
...
@@ -214,16 +239,8 @@ const termsShowOriginal = ref(true);
const
entityRequestToken
=
ref
(
0
);
const
termEntityCache
=
ref
(
new
Map
());
const
escapeHtml
=
value
=>
{
const
str
=
String
(
value
??
""
);
return
str
.
replace
(
/&/g
,
"&"
)
.
replace
(
/</g
,
"<"
)
.
replace
(
/>/g
,
">"
)
.
replace
(
/"/g
,
"""
)
.
replace
(
/'/g
,
"'"
);
};
const
termsEntityLoading
=
ref
(
false
);
const
termsEntityPendingCount
=
ref
(
0
);
const
normalizeEntities
=
entities
=>
{
const
list
=
Array
.
isArray
(
entities
)
?
entities
:
[];
...
...
@@ -237,69 +254,23 @@ const normalizeEntities = entities => {
.
filter
(
item
=>
item
.
text_span
);
}
;
const
getEntityRanges
=
(
text
,
entities
)
=>
{
const
ranges
=
[];
const
rawText
=
String
(
text
??
""
);
if
(
!
rawText
)
return
ranges
;
const
list
=
normalizeEntities
(
entities
).
sort
((
a
,
b
)
=>
b
.
text_span
.
length
-
a
.
text_span
.
length
);
for
(
const
ent
of
list
)
{
let
startIndex
=
0
;
while
(
startIndex
<
rawText
.
length
)
{
const
idx
=
rawText
.
indexOf
(
ent
.
text_span
,
startIndex
);
if
(
idx
===
-
1
)
break
;
ranges
.
push
({
start
:
idx
,
end
:
idx
+
ent
.
text_span
.
length
,
ent
});
startIndex
=
idx
+
ent
.
text_span
.
length
;
}
}
ranges
.
sort
((
a
,
b
)
=>
a
.
start
-
b
.
start
||
b
.
end
-
a
.
end
);
const
merged
=
[];
let
lastEnd
=
0
;
for
(
const
r
of
ranges
)
{
if
(
r
.
start
<
lastEnd
)
continue
;
merged
.
push
(
r
);
lastEnd
=
r
.
end
;
}
return
merged
;
};
const
buildHighlightedHtml
=
(
text
,
entities
,
enableHighlight
)
=>
{
const
rawText
=
String
(
text
??
""
);
if
(
!
rawText
)
return
""
;
const
safeText
=
escapeHtml
(
rawText
).
replace
(
/
\n
/g
,
"<br />"
);
if
(
!
enableHighlight
)
return
safeText
;
const
ranges
=
getEntityRanges
(
rawText
,
entities
);
if
(
!
ranges
.
length
)
return
safeText
;
let
html
=
""
;
let
cursor
=
0
;
for
(
const
r
of
ranges
)
{
if
(
cursor
<
r
.
start
)
{
html
+=
escapeHtml
(
rawText
.
slice
(
cursor
,
r
.
start
));
}
const
spanText
=
rawText
.
slice
(
r
.
start
,
r
.
end
);
const
type
=
escapeHtml
(
r
.
ent
?.
type
??
""
);
html
+=
`<span class="term-entity" data-entity-type="
${
type
}
">
${
escapeHtml
(
spanText
)}
</span>`
;
cursor
=
r
.
end
;
}
if
(
cursor
<
rawText
.
length
)
{
html
+=
escapeHtml
(
rawText
.
slice
(
cursor
));
}
return
html
.
replace
(
/
\n
/g
,
"<br />"
);
};
const
getTermEntityKey
=
(
term
,
lang
)
=>
{
const
baseKey
=
getTermKey
(
term
,
-
1
);
return
`${baseKey
}
__${lang
}
`
;
}
;
const
ensureEntitiesForTerms
=
async
terms
=>
{
if
(
!
termsHighlight
.
value
)
return
;
if
(
!
termsHighlight
.
value
)
{
termsEntityLoading
.
value
=
false
;
termsEntityPendingCount
.
value
=
0
;
return
;
}
const
list
=
Array
.
isArray
(
terms
)
?
terms
:
[];
if
(
!
list
.
length
)
return
;
if
(
!
list
.
length
)
{
termsEntityLoading
.
value
=
false
;
termsEntityPendingCount
.
value
=
0
;
return
;
}
const
currentToken
=
++
entityRequestToken
.
value
;
...
...
@@ -314,30 +285,40 @@ const ensureEntitiesForTerms = async terms => {
tasks
.
push
({
key
:
enKey
,
text
:
term
.
ywnr
}
);
}
}
if
(
!
tasks
.
length
)
return
;
if
(
!
tasks
.
length
)
{
termsEntityLoading
.
value
=
false
;
termsEntityPendingCount
.
value
=
0
;
return
;
}
termsEntityLoading
.
value
=
true
;
termsEntityPendingCount
.
value
=
tasks
.
length
;
const
fetchOne
=
async
item
=>
{
try
{
const
results
=
await
Promise
.
all
(
tasks
.
map
(
async
item
=>
{
const
res
=
await
extractTextEntity
(
item
.
text
,
{
signal
:
getPageSignal
()
}
);
const
entities
=
normalizeEntities
(
res
?.
result
??
res
?.
data
?.
result
??
res
?.
data
??
res
);
return
{
key
:
item
.
key
,
entities
};
})
);
if
(
currentToken
!==
entityRequestToken
.
value
)
return
;
for
(
const
r
of
results
)
{
termEntityCache
.
value
.
set
(
r
.
key
,
r
.
entities
);
}
const
entities
=
normalizeEntities
(
res
?.
result
??
res
?.
data
?.
result
??
res
?.
data
??
res
);
const
nextCache
=
new
Map
(
termEntityCache
.
value
);
nextCache
.
set
(
item
.
key
,
entities
);
termEntityCache
.
value
=
nextCache
;
}
catch
(
error
)
{
if
(
currentToken
!==
entityRequestToken
.
value
)
return
;
}
finally
{
if
(
currentToken
!==
entityRequestToken
.
value
)
return
;
termsEntityPendingCount
.
value
=
Math
.
max
(
0
,
termsEntityPendingCount
.
value
-
1
);
if
(
termsEntityPendingCount
.
value
===
0
)
{
termsEntityLoading
.
value
=
false
;
}
}
}
;
await
Promise
.
all
(
tasks
.
map
(
item
=>
fetchOne
(
item
)));
}
;
const
getTermContentHtml
=
(
term
,
lang
)
=>
{
const
raw
=
lang
===
"en"
?
term
?.
ywnr
:
term
?.
fynr
;
const
getTermEntities
=
(
term
,
lang
)
=>
{
const
key
=
getTermEntityKey
(
term
,
lang
);
const
entities
=
termEntityCache
.
value
.
get
(
key
)
||
[];
return
buildHighlightedHtml
(
raw
,
entities
,
termsHighlight
.
value
);
return
termEntityCache
.
value
.
get
(
key
)
||
[];
}
;
const
tkRequestToken
=
ref
(
0
);
...
...
@@ -347,10 +328,6 @@ const hylyRequestToken = ref(0);
const
mainTermsList
=
ref
([]);
const
domainFooterText
=
ref
(
""
);
const
limitFooterText
=
ref
(
""
);
const
btnActiveIndex
=
ref
(
1
);
const
handleSelectBtn
=
index
=>
{
btnActiveIndex
.
value
=
index
;
};
const
getTermKey
=
(
term
,
index
)
=>
{
return
term
?.
ywid
??
term
?.
id
??
term
?.
tkxh
??
index
;
...
...
@@ -576,7 +553,16 @@ const handleChangeCheckbox = val => {
handleGetBillHyly
();
}
;
/** 法案布局主区域可滚动容器(.layout-main)滚回顶部 */
const
scrollBillLayoutMainToTop
=
()
=>
{
const
mainEl
=
document
.
querySelector
(
".layout-main"
);
if
(
mainEl
)
{
mainEl
.
scrollTo
({
top
:
0
,
behavior
:
"smooth"
}
);
}
}
;
const
handleCurrentChange
=
val
=>
{
scrollBillLayoutMainToTop
();
currentPage
.
value
=
val
;
handleGetBillContentTk
(
checkedValue
.
value
?
"Y"
:
"N"
);
}
;
...
...
@@ -925,8 +911,11 @@ onBeforeUnmount(() => {
.
content
-
row
{
display
:
flex
;
align
-
items
:
flex
-
start
;
margin
-
bottom
:
30
px
;
}
.
box
-
header
{
display
:
flex
;
position
:
relative
;
...
...
@@ -988,9 +977,7 @@ onBeforeUnmount(() => {
.
terms
{
margin
-
top
:
16
px
;
margin-left
:
16px
;
width
:
1064
px
;
height
:
1232px
;
position
:
relative
;
.
terms
-
switch
{
...
...
@@ -1007,6 +994,14 @@ onBeforeUnmount(() => {
color
:
var
(
--
text
-
primary
-
65
-
color
);
}
.
terms
-
entity
-
loading
{
display
:
inline
-
flex
;
align
-
items
:
center
;
gap
:
4
px
;
font
-
size
:
12
px
;
color
:
var
(
--
text
-
primary
-
65
-
color
);
}
.
terms
-
switch
-
divider
{
display
:
inline
-
block
;
width
:
1
px
;
...
...
@@ -1022,17 +1017,21 @@ onBeforeUnmount(() => {
}
}
:
deep
(.
analysis
-
box
-
wrapper
)
{
height
:
auto
;
}
:
deep
(.
wrapper
-
main
)
{
display
:
flex
;
flex
-
direction
:
column
;
height
:
calc
(
100%
-
45px
);
gap
:
16px
;
height
:
auto
;
min
-
height
:
0
;
overflow
:
visible
;
gap
:
16
px
;
}
.
left
-
main
{
flex
:
1
;
min-height
:
0
;
overflow-y
:
auto
;
flex
:
0
0
auto
;
display
:
flex
;
flex
-
direction
:
column
;
gap
:
12
px
;
...
...
@@ -1112,12 +1111,12 @@ onBeforeUnmount(() => {
line
-
height
:
24
px
;
color
:
var
(
--
text
-
primary
-
80
-
color
);
:deep
(
.
term-entity
)
{
display
:
inline
;
padding
:
0
2px
;
border-radius
:
4px
;
background
:
rgba
(
255
,
213
,
79
,
0
.35
);
box-shadow
:
inset
0
0
0
1px
rgba
(
255
,
193
,
7
,
0
.25
)
;
:
deep
(.
entity
-
link
)
{
color
:
var
(
--
color
-
primary
-
100
)
;
}
:
deep
(.
entity
-
link
:
hover
)
{
cursor
:
pointer
;
}
}
...
...
@@ -1128,12 +1127,12 @@ onBeforeUnmount(() => {
line
-
height
:
24
px
;
color
:
var
(
--
text
-
primary
-
65
-
color
);
:deep
(
.
term-entity
)
{
display
:
inline
;
padding
:
0
2px
;
border-radius
:
4px
;
background
:
rgba
(
255
,
213
,
79
,
0
.28
);
box-shadow
:
inset
0
0
0
1px
rgba
(
255
,
193
,
7
,
0
.2
)
;
:
deep
(.
entity
-
link
)
{
color
:
var
(
--
color
-
primary
-
100
)
;
}
:
deep
(.
entity
-
link
:
hover
)
{
cursor
:
pointer
;
}
}
...
...
@@ -1196,6 +1195,7 @@ onBeforeUnmount(() => {
display
:
flex
;
align
-
items
:
center
;
justify
-
content
:
center
;
padding
-
left
:
20
px
;
}
.
overview
-
tip
-
action
{
...
...
src/views/decree/decreeOriginal/index.vue
浏览文件 @
8d534f1e
...
...
@@ -26,7 +26,7 @@
</div>
<div
class=
"layout-main-center"
>
<
BaseDecreeOriginal
:report-data=
"reportData"
@
download=
"handleDownload"
/
>
<
newOriginal
ref=
"refNewOriginal"
@
download=
"handleDownload"
></newOriginal
>
</div>
</div>
</div>
...
...
@@ -38,7 +38,7 @@ import { useRoute } from "vue-router";
import
{
ElMessage
}
from
"element-plus"
;
import
{
getDecreeSummary
}
from
"@/api/decree/introduction"
;
import
{
getDecreeReport
}
from
"@/api/decree/introduction"
;
import
BaseDecreeOriginal
from
"@/components/base/DecreeOriginal/index
.vue"
;
import
newOriginal
from
"@/components/base/DecreeOriginal/newOriginal
.vue"
;
const
route
=
useRoute
();
let
pdfUrl
=
""
;
...
...
@@ -98,26 +98,16 @@ const handleGetSummary = async () => {
};
// 获取报告原文 - 修改为获取分段数组
const
re
portData
=
ref
([]
);
const
re
fNewOriginal
=
ref
(
null
);
const
handleGetReport
=
async
()
=>
{
try
{
const
res
=
await
getDecreeReport
({
id
:
route
.
query
.
id
});
console
.
log
(
"报告原文"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
if
(
res
.
code
===
200
)
{
pdfUrl
=
res
.
data
.
pdfUrl
;
const
originData
=
[];
let
num
=
Math
.
max
(
res
.
data
.
content
.
length
,
res
.
data
.
contentEn
.
length
)
for
(
let
i
=
0
;
i
<
num
;
i
++
)
{
let
obj
=
{
content
:
res
.
data
.
content
[
i
]
||
""
,
contentEn
:
res
.
data
.
contentEn
[
i
]
||
""
,
num
:
i
+
1
,
}
originData
.
push
(
obj
);
refNewOriginal
.
value
.
setOriginalData
({...
res
.
data
});
}
reportData
.
value
=
JSON
.
parse
(
JSON
.
stringify
(
originData
));
}
}
catch
(
error
)
{
}
}
catch
(
error
)
{}
};
onMounted
(()
=>
{
...
...
src/views/marketAccessRestrictions/com/RelatedEvent.vue
浏览文件 @
8d534f1e
<
template
>
<AnalysisBox
:title=
"props.title"
:showAllBtn=
"false"
height=
"auto"
>
<div
class=
"box-main"
>
<el-empty
v-if=
"!props.listData?.length"
description=
"暂无数据"
:image-size=
"200"
/>
<div
v-for=
"(item, index) in props.listData"
:key=
"index"
class=
"box-item"
>
<div
class=
"item-tag"
>
行政令
</div>
<div
class=
"item-right"
>
<div
class=
"item-tag"
:class=
"getClassName(item)"
>
{{
item
.
TYPE
}}
</div>
<div
class=
"item-right"
@
click=
"onNavigateTo(item)"
>
<div
class=
"item-head"
>
<div
class=
"item-name one-line-ellipsis
"
>
{{
item
.
name
}}
</div>
<div
class=
"item-time"
>
{{
item
.
time
}}
</div>
<div
class=
"item-name one-line-ellipsis
text-click-hover"
>
{{
item
.
NAME
}}
</div>
<div
class=
"item-time"
>
{{
item
.
DATE
}}
</div>
</div>
<div
class=
"item-text one-line-ellipsis"
>
{{
item
.
text
}}
</div>
<div
class=
"item-text one-line-ellipsis"
>
{{
item
.
SUMMARY
}}
</div>
</div>
</div>
</div>
...
...
@@ -16,6 +17,8 @@
</
template
>
<
script
setup
lang=
"ts"
name=
"RelatedEvent"
>
import
router
from
"@/router"
;
import
{
useGotoNewsDetail
}
from
'@/router/modules/news'
;
const
props
=
defineProps
({
listData
:
{
...
...
@@ -28,6 +31,43 @@ const props = defineProps({
}
})
const
getClassName
=
(
item
:
any
)
=>
{
switch
(
item
.
TYPE
)
{
case
"行政令"
:
return
"theme1"
case
"新闻"
:
return
"theme2"
case
"法案"
:
return
"theme3"
default
:
return
"theme1"
}
}
// 跳转相关事件
const
gotoNewsDetail
=
useGotoNewsDetail
()
const
onNavigateTo
=
(
item
:
any
)
=>
{
switch
(
item
.
TYPE
)
{
case
"行政令"
:
let
route1
=
router
.
resolve
({
path
:
"/decreeLayout"
,
query
:
{
id
:
item
.
ID
}
});
window
.
open
(
route1
.
href
,
"_blank"
);
break
;
case
"新闻"
:
gotoNewsDetail
(
item
.
ID
)
break
;
case
"法案"
:
let
route2
=
router
.
resolve
({
path
:
"/billLayout"
,
query
:
{
billId
:
item
.
ID
}
});
window
.
open
(
route2
.
href
,
"_blank"
);
break
;
}
}
</
script
>
<
style
scoped
lang=
"scss"
>
...
...
@@ -47,10 +87,9 @@ const props = defineProps({
text-align
:
center
;
margin-right
:
16px
;
margin-top
:
7px
;
color
:
var
(
--
color-yellow-100
);
background-color
:
var
(
--
color-yellow-10
);
}
.item-right
{
cursor
:
pointer
;
width
:
20px
;
flex
:
auto
;
line-height
:
30px
;
...
...
@@ -77,4 +116,17 @@ const props = defineProps({
border-bottom
:
1px
solid
var
(
--
bg-black-5
);
}
}
.theme1
{
background-color
:
var
(
--
color-yellow-10
);
color
:
var
(
--
color-yellow-100
);
}
.theme2
{
background-color
:
var
(
--
color-green-10
);
color
:
var
(
--
color-green-100
);
}
.theme3
{
background-color
:
var
(
--
color-orange-10
);
color
:
var
(
--
color-orange-100
);
}
</
style
>
\ No newline at end of file
src/views/marketAccessRestrictions/com/SurveyAffiche.vue
0 → 100644
浏览文件 @
8d534f1e
<
template
>
<AnalysisBox
:title=
"props.title"
:showAllBtn=
"false"
height=
"auto"
>
<div
class=
"box-main"
>
<el-empty
v-if=
"!props.listData?.length"
description=
"暂无数据"
:image-size=
"100"
/>
<div
v-for=
"(item, index) in props.listData"
:key=
"index"
class=
"box-item"
>
<div
class=
"item-icon"
>
<img
src=
"@/views/marketAccessRestrictions/singleCaseLayout/assets/images/icon_affiche.png"
alt=
""
>
</div>
<div
class=
"item-right"
>
<div
class=
"item-time"
>
{{
item
.
time
}}
</div>
<div
class=
"item-text"
>
{{
item
.
content
}}
</div>
</div>
</div>
</div>
</AnalysisBox>
</
template
>
<
script
setup
lang=
"ts"
name=
"SurveyAffiche"
>
const
props
=
defineProps
({
listData
:
{
type
:
Array
as
any
,
default
:
()
=>
([])
},
title
:
{
type
:
String
,
default
:
""
}
})
</
script
>
<
style
scoped
lang=
"scss"
>
.box-main
{
padding
:
0
16px
16px
;
.box-item
{
border-top
:
1px
solid
var
(
--
bg-black-5
);
padding
:
6px
;
display
:
flex
;
.item-icon
{
width
:
15px
;
height
:
15px
;
font-size
:
0px
;
margin-right
:
16px
;
margin-top
:
7px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.item-right
{
width
:
20px
;
flex
:
auto
;
font-family
:
Source
Han
Sans
CN
;
font-size
:
16px
;
line-height
:
30px
;
.item-time
{
font-weight
:
bold
;
color
:
var
(
--
text-primary-80-color
);
}
.item-text
{
color
:
var
(
--
text-primary-65-color
);
}
}
}
.box-item
:last-child
{
border-bottom
:
1px
solid
var
(
--
bg-black-5
);
}
}
</
style
>
\ No newline at end of file
src/views/marketAccessRestrictions/com/SurveyHistory.vue
浏览文件 @
8d534f1e
<
template
>
<div
class=
"view-box"
>
<el-empty
v-if=
"!props.surveyList?.length"
description=
"
当前条件下暂无数据"
:image-size=
"2
00"
/>
<el-empty
v-if=
"!props.surveyList?.length"
description=
"
暂无数据"
:image-size=
"1
00"
/>
<div
class=
"timeline-item"
v-for=
"(item, index) in props.surveyList"
:key=
"item.searchid"
@
click=
"onNavigateToDetail(item)"
>
<div
class=
"timeline-date"
>
<div
class=
"date-text"
>
{{
item
.
searchdatezh
.
slice
(
0
,
4
)
}}
</div>
...
...
@@ -16,14 +16,12 @@
<div
class=
"timeline-content-card"
>
<div
class=
"item-head"
>
<div
:class=
"`item-tag tag-$
{item.sortcode}`">
{{
item
.
sortcode
}}
</div>
<div
class=
"item-name"
>
{{
item
.
searchname
}}
</div>
<div
class=
"item-name
one-line-ellipsis
"
>
{{
item
.
searchname
}}
</div>
<div
class=
"item-state"
>
<span
class=
"dot"
>
•
</span>
{{
item
.
casestatus
}}
</div>
</div>
<div
class=
"card-body"
>
{{
item
.
content
}}
</div>
<div
class=
"card-body"
>
{{
item
.
content
}}
</div>
<div
class=
"card-footer"
>
<div
class=
"footer-left-tags"
>
<AreaTag
v-for=
"(name, num) in item.searchArea"
:key=
"num"
:tagName=
"name"
></AreaTag>
...
...
@@ -129,7 +127,7 @@ const onNavigateToDetail = item => {
.timeline-content-card
{
width
:
20px
;
flex
:
auto
;
padding
:
2
px
16px
0
;
padding
:
4
px
16px
0
;
margin-bottom
:
30px
;
&
:hover
.item-head
.item-name
{
...
...
src/views/marketAccessRestrictions/marketAccessHome/index.vue
浏览文件 @
8d534f1e
...
...
@@ -145,7 +145,7 @@
<
div
class
=
"box-header-right"
>
<
el
-
select
v
-
model
=
"box6SelectedYear"
@
change
=
"handleChangeBox6Year"
placeholder
=
"选择时间"
style
=
"width: 120px"
>
<
el
-
option
v
-
for
=
"item in box
6
YearList"
:
key
=
"item.value"
:
label
=
"item.label"
:
value
=
"item.value"
/>
<
el
-
option
v
-
for
=
"item in box
7
YearList"
:
key
=
"item.value"
:
label
=
"item.label"
:
value
=
"item.value"
/>
<
/el-select
>
<
/div
>
<
/template
>
...
...
@@ -168,12 +168,12 @@
<
template
#
header
-
right
>
<
div
class
=
"box-header-right"
>
<
div
class
=
"box7-header-right-select-box"
>
<
el
-
select
v
-
model
=
"box7SelectedSurvey"
@
change
=
"handle
ChangeBox7Survey
"
placeholder
=
"选择调查"
<
el
-
select
v
-
model
=
"box7SelectedSurvey"
@
change
=
"handle
Box7()
"
placeholder
=
"选择调查"
style
=
"width: 120px"
>
<
el
-
option
v
-
for
=
"item in box
7
SurveyList"
:
key
=
"item.value"
:
label
=
"item.label"
<
el
-
option
v
-
for
=
"item in box
8
SurveyList"
:
key
=
"item.value"
:
label
=
"item.label"
:
value
=
"item.value"
/>
<
/el-select
>
<
el
-
select
v
-
model
=
"box7SelectedYear"
@
change
=
"handle
ChangeBox7Year
"
placeholder
=
"选择时间"
<
el
-
select
v
-
model
=
"box7SelectedYear"
@
change
=
"handle
Box7()
"
placeholder
=
"选择时间"
style
=
"width: 120px"
>
<
el
-
option
v
-
for
=
"item in box7YearList"
:
key
=
"item.value"
:
label
=
"item.label"
:
value
=
"item.value"
/>
...
...
@@ -197,7 +197,7 @@
<
/template
>
<
template
#
header
-
right
>
<
div
class
=
"box-header-right"
>
<
el
-
select
v
-
model
=
"box8SelectedSurvey"
@
change
=
"handle
ChangeBox8Survey
"
placeholder
=
"选择调查"
<
el
-
select
v
-
model
=
"box8SelectedSurvey"
@
change
=
"handle
Box8()
"
placeholder
=
"选择调查"
style
=
"width: 120px"
>
<
el
-
option
v
-
for
=
"item in box8SurveyList"
:
key
=
"item.value"
:
label
=
"item.label"
:
value
=
"item.value"
/>
...
...
@@ -216,8 +216,7 @@
<
div
class
=
"home-main-footer"
>
<
DivideHeader
id
=
"position4"
class
=
"divide-header"
:
titleText
=
"'资源库'"
><
/DivideHeader
>
<
div
class
=
"home-main-footer-header"
>
<
SourceTabList
:
sourceTabList
=
"categoryList"
:
activeSouceTabId
=
"activeCateId"
@
clickTab
=
"handleClickCate"
>
<
/SourceTabList
>
<
SourceTabList
:
sourceTabList
=
"categoryList"
:
activeSouceTabId
=
"activeCateId"
@
clickTab
=
"handleClickCate"
><
/SourceTabList
>
<
div
class
=
"select-box"
>
<
el
-
select
v
-
model
=
"isSort"
placeholder
=
"发布时间"
style
=
"width: 166px"
@
change
=
"handlePxChange"
>
<
template
#
prefix
>
...
...
@@ -232,60 +231,52 @@
<
/div
>
<
div
class
=
"home-main-footer-main"
>
<
div
class
=
"left"
>
<
div
class
=
"left-box1"
>
<
div
class
=
"left-box1-header"
>
<
div
class
=
"icon"
><
/div
>
<
div
class
=
"title"
>
{{
"发布时间"
}}
<
/div
>
<
/div
>
<
div
class
=
"left-box1-main"
>
<
el
-
checkbox
-
group
class
=
"checkbox-group"
v
-
model
=
"checkedSurveyYears"
@
change
=
"handleChangeCheckedSurveyYears"
>
<
el
-
checkbox
class
=
"filter-checkbox"
label
=
"全部时间"
>
全部时间
<
/el-checkbox
>
<
el
-
checkbox
v
-
for
=
"year in surveyYearList"
:
key
=
"year.id"
:
label
=
"year.id"
class
=
"filter-checkbox"
>
{{
year
.
name
}}
<!--
科技领域
-->
<
div
class
=
"check-box"
>
<
div
class
=
"check-head"
>
<
div
class
=
"head-name"
>
{{
"科技领域"
}}
<
/div
>
<
/div
>
<
el
-
checkbox
-
group
class
=
"check-list"
v
-
model
=
"checkedAreaList"
@
change
=
"handleCheckedAreasChange"
>
<
el
-
checkbox
class
=
"check-item"
v
-
for
=
"item in surveyAreaList"
:
key
=
"item.id"
:
label
=
"item.id"
>
{{
item
.
name
}}
<
/el-checkbox
>
<
/el-checkbox-group
>
<
/div
>
<!--
发布时间
-->
<
div
class
=
"check-box"
>
<
div
class
=
"check-head"
>
<
div
class
=
"head-name"
>
{{
"发布时间"
}}
<
/div
>
<
/div
>
<
div
class
=
"left-box2"
>
<
div
class
=
"left-box2-header"
>
<
div
class
=
"icon"
><
/div
>
<
div
class
=
"title"
>
{{
"科技领域"
}}
<
/div
>
<
/div
>
<
div
class
=
"left-box2-main"
>
<
el
-
checkbox
-
group
class
=
"checkbox-group"
v
-
model
=
"checkedAreaList"
@
change
=
"handleChangeCheckedAreas"
>
<
el
-
checkbox
class
=
"filter-checkbox"
label
=
"全部领域"
>
全部领域
<
/el-checkbox
>
<
el
-
checkbox
v
-
for
=
"area in areaList"
:
key
=
"area.id"
:
label
=
"area.id"
class
=
"filter-checkbox"
>
{{
area
.
name
}}
<
div
class
=
"left-main"
>
<
el
-
checkbox
-
group
class
=
"check-list"
v
-
model
=
"checkedYearList"
@
change
=
"handleCheckedYearsChange"
>
<
el
-
checkbox
class
=
"check-item"
v
-
for
=
"item in surveyYearList"
:
key
=
"item.id"
:
label
=
"item.id"
>
{{
item
.
name
}}
<
/el-checkbox
>
<
/el-checkbox-group
>
<
/div
>
<
/div
>
<
div
class
=
"left-box2"
>
<
div
class
=
"left-box2-header
"
>
<
div
class
=
"icon"
><
/div
>
<
div
class
=
"
titl
e"
>
{{
"发布机构"
}}
<
/div
>
<
!--
发布机构
--
>
<
div
class
=
"check-box
"
>
<
div
class
=
"check-head"
>
<
div
class
=
"
head-nam
e"
>
{{
"发布机构"
}}
<
/div
>
<
/div
>
<
div
class
=
"left-box2-main"
>
<
el
-
checkbox
-
group
class
=
"checkbox-group"
v
-
model
=
"checkedInsList"
@
change
=
"handleChangeCheckedIns"
>
<
el
-
checkbox
class
=
"filter-checkbox"
label
=
"全部机构"
>
全部机构
<
/el-checkbox
>
<
el
-
checkbox
v
-
for
=
"area in insList"
:
key
=
"area.id"
:
label
=
"area.id"
class
=
"filter-checkbox"
>
{{
area
.
name
}}
<
div
class
=
"left-main"
>
<
el
-
checkbox
-
group
class
=
"check-list"
v
-
model
=
"checkedOrgList"
@
change
=
"handleChangeCheckedIns"
>
<
el
-
checkbox
class
=
"check-item"
v
-
for
=
"item in surveyOrgList"
:
key
=
"item.id"
:
label
=
"item.id"
>
{{
item
.
name
}}
<
/el-checkbox
>
<
/el-checkbox-group
>
<
/div
>
<
/div
>
<
div
class
=
"left-box2"
>
<
div
class
=
"left-box2-header"
>
<
div
class
=
"icon"
><
/div
>
<
div
class
=
"title"
>
{{
"受调查国家/地区"
}}
<
/div
>
<
/div
>
<
div
class
=
"left-box2-main"
>
<
el
-
checkbox
-
group
class
=
"checkbox-group"
v
-
model
=
"checkedCountryList"
@
change
=
"handleChangeCheckedCountry"
>
<
el
-
checkbox
class
=
"filter-checkbox"
label
=
"全部"
>
全部
<
/el-checkbox
>
<
el
-
checkbox
v
-
for
=
"area in countryList"
:
key
=
"area.id"
:
label
=
"area.id"
class
=
"filter-checkbox"
>
{{
area
.
name
}}
<!--
受调查国家
/
地区
-->
<
div
class
=
"check-box"
>
<
div
class
=
"check-head"
>
<
div
class
=
"head-name"
>
{{
"受调查国家/地区"
}}
<
/div
>
<
/div
>
<
div
class
=
"left-main"
>
<
el
-
checkbox
-
group
class
=
"check-list"
v
-
model
=
"checkedCountryList"
@
change
=
"handleCheckedCountriesChange"
>
<
el
-
checkbox
class
=
"check-item"
v
-
for
=
"item in surveyCountryList"
:
key
=
"item.id"
:
label
=
"item.id"
>
{{
item
.
name
}}
<
/el-checkbox
>
<
/el-checkbox-group
>
<
/div
>
...
...
@@ -316,7 +307,7 @@
<
/template
>
<
script
setup
>
import
{
onMounted
,
ref
,
nextTick
}
from
"vue"
;
import
{
onMounted
,
ref
,
nextTick
,
reactive
}
from
"vue"
;
import
LeftBtn
from
"@/components/base/pageBtn/LeftBtn.vue"
;
import
RightBtn
from
"@/components/base/pageBtn/RightBtn.vue"
;
...
...
@@ -347,8 +338,6 @@ import {
getSearchResult
,
getSearchAllOrg
,
getSearchAllCountry
,
getStatAreaCompanyList
,
getCompanyPlace
}
from
"@/api/marketAccessRestrictions/index"
;
import
{
getRiskSignal
,
getNews
,
getRemarks
}
from
"@/api/common/index"
;
import
{
ElMessage
}
from
"element-plus"
;
...
...
@@ -379,21 +368,6 @@ const handleToPosi = id => {
}
}
;
const
formatDate
=
(
dateStr
,
dateType
)
=>
{
if
(
!
dateStr
)
return
""
;
const
date
=
new
Date
(
dateStr
);
if
(
isNaN
(
date
.
getTime
()))
return
dateStr
;
const
year
=
date
.
getFullYear
();
const
month
=
date
.
getMonth
()
+
1
;
const
day
=
date
.
getDate
();
if
(
dateType
===
'year'
)
{
return
year
}
else
{
return
`${month.toString().padStart(2, "0")
}
月${day.toString().padStart(2, "0")
}
日`
}
// return `$
{
year
}年
$
{
month
.
toString
().
padStart
(
2
,
"0"
)
}月
$
{
day
.
toString
().
padStart
(
2
,
"0"
)
}日
`;
}
let
containerRef
=
ref
(
null
);
// 首页分类
const
sortInfo
=
ref
([{
}
]);
...
...
@@ -726,32 +700,6 @@ const handleBox5 = async () => {
// 制裁领域分布
const
box6SelectedYear
=
ref
(
"2025"
);
const box6YearList = ref([
{
label: "2025",
value: "2025"
}
,
{
label: "2024",
value: "2024"
}
,
{
label: "2023",
value: "2023"
}
,
{
label: "2022",
value: "2022"
}
,
{
label: "2021",
value: "2021"
}
,
{
label: "2020",
value: "2020"
}
]);
const
handleChangeBox6Year
=
()
=>
{
handleBox6
();
}
;
...
...
@@ -846,59 +794,18 @@ const handleBox6 = async () => {
}
;
// 受调查国家分布
const box7SurveyList = ref([
{
label: "337调查",
value: "337"
}
,
{
label: "301调查",
value: "301"
}
,
{
label: "232调查",
value: "232"
}
]);
const
box7SelectedSurvey
=
ref
(
"337"
);
const
box7YearList
=
ref
([
{
label: "2025",
value: "2025"
}
,
{
label: "2024",
value: "2024"
}
,
{
label: "2023",
value: "2023"
}
,
{
label: "2022",
value: "2022"
}
,
{
label: "2021",
value: "2021"
}
,
{
label: "2020",
value: "2020"
}
{
label
:
"2025"
,
value
:
"2025"
}
,
{
label
:
"2024"
,
value
:
"2024"
}
,
{
label
:
"2023"
,
value
:
"2023"
}
,
{
label
:
"2022"
,
value
:
"2022"
}
,
{
label
:
"2021"
,
value
:
"2021"
}
,
{
label
:
"2020"
,
value
:
"2020"
}
,
]);
const
box7SelectedYear
=
ref
(
"2025"
);
const handleChangeBox7Survey = () => {
handleBox7();
}
;
const handleChangeBox7Year = () => {
handleBox7();
}
;
const box7Data = ref({
title: [
],
const
box7Data
=
reactive
({
title
:
[],
data
:
[]
}
);
...
...
@@ -911,13 +818,13 @@ const handleGetBox7Data = async () => {
const
res
=
await
getSearchCountry
(
params
);
console
.
log
(
"受调查国家分布"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
box7Data.
value.
title = res.data.map(item => {
box7Data
.
title
=
res
.
data
.
map
(
item
=>
{
return
{
name
:
item
.
COUNTRY
,
img
:
item
.
COUNTRYIMAGE
}
;
}
);
box7Data.
value.
data = res.data.map(item => {
box7Data
.
data
=
res
.
data
.
map
(
item
=>
{
return
item
.
NUM
;
}
);
}
...
...
@@ -928,35 +835,21 @@ const handleGetBox7Data = async () => {
const
handleBox7
=
async
()
=>
{
await
handleGetBox7Data
();
const box7Chart = getBarChart(box7Data.
value.title, box7Data.value
.data);
const
box7Chart
=
getBarChart
(
box7Data
.
title
,
box7Data
.
data
);
setChart
(
box7Chart
,
"box7Chart"
);
}
;
const
box8SurveyList
=
ref
([
{
label: "337调查",
value: "337"
}
,
{
label: "301调查",
value: "301"
}
,
{
label: "232调查",
value: "232"
}
{
label
:
"337调查"
,
value
:
"337"
}
,
{
label
:
"301调查"
,
value
:
"301"
}
,
{
label
:
"232调查"
,
value
:
"232"
}
,
]);
const box8SelectedSurvey = ref("337");
// 调查结果分布
const box8
Data = ref([
]);
const
box8
SelectedSurvey
=
ref
(
"337"
);
const
box8Data
=
ref
([
]);
const
handleGetBox8Data
=
async
()
=>
{
const params = {
// searchId: '',
sortCode: box8SelectedSurvey.value
}
;
try
{
const res = await getSearchResult(
params
);
const
res
=
await
getSearchResult
(
{
sortCode
:
box8SelectedSurvey
.
value
}
);
console
.
log
(
"调查结果分布"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
box8Data
.
value
=
res
.
data
.
map
(
item
=>
{
...
...
@@ -968,23 +861,16 @@ const handleGetBox8Data = async () => {
}
else
{
box8Data
.
value
=
[]
}
}
catch
(
error
)
{
console
.
error
(
error
);
}
}
;
const
handleBox8
=
async
()
=>
{
await
handleGetBox8Data
()
const
box8Chart
=
getPieChart
(
box8Data
.
value
);
setChart
(
box8Chart
,
"box8Chart"
);
}
const handleChangeBox8Survey = () => {
handleBox8();
}
;
// 资源库
const
pageSize
=
ref
(
10
);
const
currentPage
=
ref
(
1
);
...
...
@@ -992,234 +878,132 @@ const totalDiscussNum = ref(0);
const
handleCurrentChange
=
page
=>
{
handleToPosi
(
"position4"
)
currentPage
.
value
=
page
;
handle
Get
SurveyList();
handle
Fetch
SurveyList
();
}
;
const
categoryList
=
ref
([
{
name: "全部调查",
id: ""
}
,
{
name: "301调查",
id: "301"
}
,
{
name: "232调查",
id: "232"
}
,
{
name: "337调查",
id: "337"
}
{
name
:
"全部调查"
,
id
:
""
}
,
{
name
:
"337调查"
,
id
:
"337"
}
,
{
name
:
"301调查"
,
id
:
"301"
}
,
{
name
:
"232调查"
,
id
:
"232"
}
,
]);
const
activeCateId
=
ref
(
""
);
const
handleClickCate
=
item
=>
{
activeCateId
.
value
=
item
.
id
;
handleGetInsList()
handle
Get
SurveyList();
currentPage
.
value
=
1
;
handle
Fetch
SurveyList
();
}
;
const
releaseTimeList
=
ref
([
{
label: "按发布时间倒序",
value: true
}
,
{
label: "按发布时间升序",
value: false
}
{
label
:
"按发布时间倒序"
,
value
:
true
}
,
{
label
:
"按发布时间升序"
,
value
:
false
}
]);
const isSort = ref(true); // true 倒序 false 升序
// const handleSwithSort = () => {
// isSort.value = !isSort.value;
//
}
;
const handlePxChange = val => {
handleGetSurveyList()
const
isSort
=
ref
(
true
);
const
handlePxChange
=
()
=>
{
currentPage
.
value
=
1
;
handleFetchSurveyList
();
}
;
const
surveyYearList
=
ref
([
{
name: "2025年",
id: "2025"
}
,
{
name: "2024年",
id: "2024"
}
,
{
name: "2023年",
id: "2023"
}
,
{
name: "2022年",
id: "2022"
}
,
{
name: "2021年",
id: "2021"
}
{
name
:
"全部时间"
,
id
:
""
}
,
{
name
:
"2025年"
,
id
:
"2025"
}
,
{
name
:
"2024年"
,
id
:
"2024"
}
,
{
name
:
"2023年"
,
id
:
"2023"
}
,
{
name
:
"2022年"
,
id
:
"2022"
}
,
{
name
:
"2021年"
,
id
:
"2021"
}
]);
const checkedSurveyYears = ref(['全部时间']);
const handleChangeCheckedSurveyYears = (val) => {
if (val.includes("全部时间") && val.length > 1) {
if (val[val.length - 1] === "全部时间") {
checkedSurveyYears.value = ["全部时间"];
const
checkedYearList
=
ref
([
''
]);
const
handleCheckedYearsChange
=
event
=>
{
if
(
event
.
length
&&
event
[
event
.
length
-
1
]
!==
""
)
{
checkedYearList
.
value
=
event
.
filter
(
item
=>
item
!==
""
);
}
else
{
checkedSurveyYears.value = val.filter(item => item !== "全部时间");
}
}
else if (val.length === 0) {
checkedSurveyYears.value = ["全部时间"];
checkedYearList
.
value
=
[
""
];
}
handleGetSurveyList();
currentPage
.
value
=
1
;
handleFetchSurveyList
();
}
;
const areaList = ref([
]);
const checkedAreaList = ref(['
全部领域
']);
const handleGet
AreaList
= async () => {
// 科技领域过滤
const
surveyAreaList
=
ref
([
]);
const
checkedAreaList
=
ref
([
''
]);
const
handleGet
SearchAllArea
=
async
()
=>
{
try
{
const
res
=
await
getHylyList
();
console.log("行业领域列表", res);
if (res.code === 200 && res.data) {
areaList.value = res.data.map(item => {
return {
name: item.name,
id: item.id
}
;
}
);
console.log("areaList", areaList.value);
if
(
res
.
code
===
200
)
{
surveyAreaList
.
value
=
res
.
data
.
map
(
item
=>
({
name
:
item
.
name
,
id
:
item
.
id
}
));
}
}
catch (error) {
}
}
catch
(
error
)
{
}
surveyAreaList
.
value
.
unshift
({
name
:
"全部领域"
,
id
:
""
}
);
}
;
const handleChangeCheckedAreas = (val) => {
// console.log('val',val);
if (val.includes("全部领域") && val.length > 1) {
if (val[val.length - 1] === "全部领域") {
checkedAreaList.value = ["全部领域"];
const
handleCheckedAreasChange
=
event
=>
{
if
(
event
.
length
&&
event
[
event
.
length
-
1
]
!==
""
)
{
checkedAreaList
.
value
=
event
.
filter
(
item
=>
item
!==
""
);
}
else
{
checkedAreaList.value = val.filter(item => item !== "全部领域")
;
checkedAreaList
.
value
=
[
""
]
;
}
}
else if (val.length === 0) {
checkedAreaList.value = ["全部领域"];
}
handleGetSurveyList();
currentPage
.
value
=
1
;
handleFetchSurveyList
();
}
;
// 发布机构
const insList = ref([
{
name: "商务部",
id: "54"
}
,
{
name: "国际贸易委员会",
id: "262"
}
,
{
name: "贸易代表办公室",
id: "491"
}
]);
const checkedInsList = ref(['全部机构']);
// 发布机构过滤
const
surveyOrgList
=
ref
([]);
const
checkedOrgList
=
ref
([
''
]);
const
handleGetInsList
=
async
()
=>
{
// const params = {
// sortCode: activeCateId.value
//
}
try
{
const
res
=
await
getSearchAllOrg
()
console.log('发布机构', res);
if (res.code === 200 && res.data) {
insList.value = res.data.map(item => {
return {
name: item.ORGNAME,
id: item.ORGID
}
}
)
// checkedInsList.value = [insList.value[0].id]
}
}
catch (error) {
if
(
res
.
code
===
200
)
{
surveyOrgList
.
value
=
res
.
data
.
map
(
item
=>
({
name
:
item
.
ORGNAME
,
id
:
item
.
ORGID
}
))
}
}
catch
(
error
)
{
}
surveyOrgList
.
value
.
unshift
({
name
:
"全部机构"
,
id
:
""
}
);
}
const handleChangeCheckedIns = (val) => {
// console.log(checkedAreaList.value);
if (val.includes("全部机构") && val.length > 1) {
if (val[val.length - 1] === "全部机构") {
checkedInsList.value = ["全部机构"];
const
handleChangeCheckedIns
=
(
event
)
=>
{
if
(
event
.
length
&&
event
[
event
.
length
-
1
]
!==
""
)
{
checkedOrgList
.
value
=
event
.
filter
(
item
=>
item
!==
""
);
}
else
{
checkedInsList.value = val.filter(item => item !== "全部机构");
}
}
else if (val.length === 0) {
checkedInsList.value = ["全部机构"];
checkedOrgList
.
value
=
[
""
];
}
handleGetSurveyList();
currentPage
.
value
=
1
;
handleFetchSurveyList
();
}
;
// 受调查国家/地区
const countryList = ref([
]);
const checkedCountryList = ref(['全部']);
const
surveyCountryList
=
ref
([]);
const
checkedCountryList
=
ref
([
''
]);
const
handleGetAllSearchCountry
=
async
()
=>
{
try
{
const
res
=
await
getSearchAllCountry
()
console.log('受调查国家/地区', res);
if (res.code && res.data) {
countryList.value = res.data.map(item => {
return {
name: item.COUNTRYNAME,
id: item.COUNTRYID
}
}
)
// checkedCountryList.value = [countryList.value[0].id]
}
}
catch (error) {
if
(
res
.
code
===
200
)
{
surveyCountryList
.
value
=
res
.
data
.
map
(
item
=>
({
name
:
item
.
COUNTRYNAME
,
id
:
item
.
COUNTRYID
}
))
}
}
catch
(
error
)
{
}
surveyCountryList
.
value
.
unshift
({
name
:
"全部"
,
id
:
""
}
);
}
handleGetAllSearchCountry()
const handleChangeCheckedCountry = (val) => {
if (val.includes("全部") && val.length > 1) {
if (val[val.length - 1] === "全部") {
checkedCountryList.value = ["全部"];
const
handleCheckedCountriesChange
=
event
=>
{
if
(
event
.
length
&&
event
[
event
.
length
-
1
]
!==
""
)
{
checkedCountryList
.
value
=
event
.
filter
(
item
=>
item
!==
""
);
}
else
{
checkedCountryList.value = val.filter(item => item !== "全部");
}
}
else if (val.length === 0) {
checkedCountryList.value = ["全部"];
checkedCountryList
.
value
=
[
""
];
}
handleGetSurveyList();
currentPage
.
value
=
1
;
handleFetchSurveyList
();
}
;
const
surveyInfoList
=
ref
([]);
const handle
Get
SurveyList = async () => {
const
handle
Fetch
SurveyList
=
async
()
=>
{
const
params
=
{
currentPage
:
currentPage
.
value
-
1
,
pageSize
:
pageSize
.
value
,
sortCode: activeCateId.value
? activeCateId.value :
null,
publishYear: checked
SurveyYears.value[0] === '全部时间' ? null : checkedSurveyYears.value.toString()
,
Area: checkedAreaList.value
[0] === '全部领域' ? null : checkedAreaList.value.toString()
,
publishOrg: checked
InsList.value[0] === '全部机构' ? null : checkedInsList.value.toString()
,
searchCountry: checkedCountryList.value
[0] === '全部' ? null : checkedCountryList.value.toString()
,
sortCode
:
activeCateId
.
value
||
null
,
publishYear
:
checked
YearList
.
value
.
join
(
','
)
||
null
,
Area
:
checkedAreaList
.
value
.
join
(
','
)
||
null
,
publishOrg
:
checked
OrgList
.
value
.
join
(
','
)
||
null
,
searchCountry
:
checkedCountryList
.
value
.
join
(
','
)
||
null
,
sortField
:
"date"
,
sortOrder
:
isSort
.
value
?
"desc"
:
"asc"
}
;
// console.log(params);
try
{
const
res
=
await
getSurveyList
(
params
);
console
.
log
(
"调查列表"
,
res
);
...
...
@@ -1254,9 +1038,10 @@ onMounted(async () => {
handleBox6
();
handleBox7
();
handleBox8
();
await handleGetInsList()
await handleGetAreaList();
handleGetSurveyList();
handleGetAllSearchCountry
()
handleGetInsList
()
handleGetSearchAllArea
();
handleFetchSurveyList
();
}
);
<
/script
>
...
...
@@ -2293,67 +2078,44 @@ onMounted(async () => {
box
-
shadow
:
0
px
0
px
15
px
0
px
rgba
(
60
,
87
,
126
,
0.2
);
background
:
rgba
(
255
,
255
,
255
,
1
);
.left-box1 {
margin-top: 17px;
// height: 220px;
.left-box1-header {
display: flex;
.icon {
.
check
-
box
{
margin
-
top
:
18
px
;
.
check
-
head
{
position
:
relative
;
margin
-
bottom
:
12
px
;
&
::
before
{
content
:
""
;
position
:
absolute
;
top
:
0
px
;
left
:
0
px
;
width
:
8
px
;
height: 16px;
margin-top: 4px;
border-radius: 2px 2px 0 0;
background: var(--color-main-active);
height
:
100
%
;
background
:
var
(
--
color
-
primary
-
100
);
border
-
radius
:
0
2
px
2
px
0
;
}
.title {
height: 2px;
margin-left: 17px;
color: var(--color-main-active);
font-family: Source Han Sans CN;
.
head
-
name
{
margin
-
left
:
25
px
;
color
:
var
(
--
color
-
primary
-
100
);
font
-
size
:
16
px
;
font-weight: 700;
line-height: 24px;
}
}
.left-box1-main {
margin-top: 10px;
padding-left: 20px;
}
line
-
height
:
16
px
;
font
-
family
:
Source
Han
Sans
CN
;
font
-
weight
:
bold
;
}
.left-box2 {
margin-top: 17px;
// height: 260px;
.left-box2-header {
display: flex;
.icon {
width: 8px;
height: 16px;
margin-top: 4px;
border-radius: 2px 2px 0 0;
background: var(--color-main-active);
}
.title {
height: 2px;
margin-left: 17px;
color: var(--color-main-active);
.
check
-
list
{
padding
:
0
10
px
0
25
px
;
display
:
grid
;
grid
-
template
-
columns
:
repeat
(
2
,
1
fr
);
grid
-
gap
:
0
12
px
;
.
check
-
item
{
width
:
100
%
;
height
:
32
px
;
:
deep
(.
el
-
checkbox__label
)
{
font
-
family
:
Source
Han
Sans
CN
;
font
-
size
:
16
px
;
font-weight: 700;
line-height: 24px;
color
:
var
(
--
text
-
primary
-
65
-
color
);
}
}
.left-box2-main {
margin-top: 10px;
padding-left: 20px;
}
}
}
...
...
src/views/marketAccessRestrictions/marketAccessLayout/case/232/index.vue
浏览文件 @
8d534f1e
...
...
@@ -32,39 +32,26 @@
<div
class=
"wrapper-main"
>
<div
class=
"left"
>
<!-- 科技领域 -->
<div
class=
"left-box"
>
<div
class=
"left-header"
>
<div
class=
"icon"
></div>
<div
class=
"title"
>
{{
"科技领域"
}}
</div>
<div
class=
"check-box"
>
<div
class=
"check-head"
>
<div
class=
"head-name"
>
{{
"科技领域"
}}
</div>
</div>
<div
class=
"left-main"
>
<el-checkbox-group
class=
"checkbox-group"
v-model=
"checkedAreaList"
@
change=
"handleCheckedAreasChange"
>
<el-checkbox
class=
"filter-checkbox"
label=
"全部领域"
>
全部领域
</el-checkbox>
<el-checkbox
v-for=
"area in surveyAreaList"
:key=
"area.id"
:label=
"area.id"
class=
"filter-checkbox"
>
{{
area
.
name
}}
<el-checkbox-group
class=
"check-list"
v-model=
"checkedAreaList"
@
change=
"handleCheckedAreasChange"
>
<el-checkbox
class=
"check-item"
v-for=
"item in surveyAreaList"
:key=
"item.id"
:label=
"item.id"
>
{{
item
.
name
}}
</el-checkbox>
</el-checkbox-group>
</div>
</div>
<!-- 发布时间 -->
<div
class=
"left-box"
>
<div
class=
"left-header"
>
<div
class=
"icon"
></div>
<div
class=
"title"
>
{{
"发布时间"
}}
</div>
<div
class=
"check-box"
>
<div
class=
"check-head"
>
<div
class=
"head-name"
>
{{
"发布时间"
}}
</div>
</div>
<div
class=
"left-main"
>
<el-checkbox-group
class=
"checkbox-group"
v-model=
"checkedSurveyYears"
@
change=
"handleCheckedYearsChange"
>
<el-checkbox
class=
"filter-checkbox"
label=
"全部时间"
>
全部时间
</el-checkbox>
<el-checkbox
v-for=
"year in displayedYearList"
:key=
"year.id"
:label=
"year.id"
class=
"filter-checkbox"
>
{{
year
.
name
}}
<el-checkbox-group
class=
"check-list"
v-model=
"checkedYearList"
@
change=
"handleCheckedYearsChange"
>
<el-checkbox
class=
"check-item"
v-for=
"item in surveyYearList"
:key=
"item.id"
:label=
"item.id"
>
{{
item
.
name
}}
</el-checkbox>
<div
v-if=
"surveyYearList.length > 6"
class=
"expand-btn"
@
click=
"isYearExpanded = !isYearExpanded"
>
{{
isYearExpanded
?
"收起"
:
"更早"
}}
<el-icon>
<ArrowUp
v-if=
"isYearExpanded"
/>
<ArrowDown
v-else
/>
</el-icon>
</div>
</el-checkbox-group>
</div>
</div>
...
...
@@ -98,8 +85,8 @@
<
/template
>
<
script
setup
>
import
{
ref
,
onMounted
,
watch
,
computed
}
from
"vue"
;
import
{
Search
,
ArrowDown
,
ArrowUp
}
from
"@element-plus/icons-vue"
;
import
{
ref
,
onMounted
,
watch
}
from
"vue"
;
import
{
Search
}
from
"@element-plus/icons-vue"
;
import
{
getSearchAllArea
,
getSearchAllYear
,
getSurveyList
}
from
"@/api/marketAccessRestrictions"
;
import
SurveyHistory
from
"@/views/marketAccessRestrictions/com/SurveyHistory.vue"
...
...
@@ -116,42 +103,49 @@ const handleSwithSort = () => {
// 科技领域过滤
const
surveyAreaList
=
ref
([]);
const
checkedAreaList
=
ref
([]);
const
checkAllAreas
=
ref
(
true
);
const
isIndeterminateAreas
=
ref
(
false
);
const
handleCheckAllAreasChange
=
val
=>
{
checkedAreaList
.
value
=
val
?
surveyAreaList
.
value
.
map
(
a
=>
a
.
id
)
:
[];
isIndeterminateAreas
.
value
=
false
;
const
checkedAreaList
=
ref
([
''
]);
const
handleGetSearchAllArea
=
async
()
=>
{
try
{
const
res
=
await
getSearchAllArea
({
sortCode
:
"232"
}
);
if
(
res
.
code
===
200
)
{
surveyAreaList
.
value
=
res
.
data
.
map
(
item
=>
({
name
:
item
.
AREANAME
,
id
:
item
.
AREACODE
}
));
}
}
catch
(
error
)
{
}
surveyAreaList
.
value
.
unshift
({
name
:
"全部领域"
,
id
:
""
}
);
}
;
const
handleCheckedAreasChange
=
value
=>
{
const
checkedCount
=
value
.
length
;
checkAllAreas
.
value
=
checkedCount
===
surveyAreaList
.
value
.
length
;
isIndeterminateAreas
.
value
=
checkedCount
>
0
&&
checkedCount
<
surveyAreaList
.
value
.
length
;
const
handleCheckedAreasChange
=
event
=>
{
if
(
event
.
length
&&
event
[
event
.
length
-
1
]
!==
""
)
{
checkedAreaList
.
value
=
event
.
filter
(
item
=>
item
!==
""
);
}
else
{
checkedAreaList
.
value
=
[
""
];
}
currentPage
.
value
=
1
;
handleFetchSurveyList
();
}
;
// 发布时间过滤
const
surveyYearList
=
ref
([]);
const
checkedSurveyYears
=
ref
([]);
const
checkAllYears
=
ref
(
true
);
const
isIndeterminateYears
=
ref
(
false
);
const
isYearExpanded
=
ref
(
false
);
const
displayedYearList
=
computed
(()
=>
{
if
(
isYearExpanded
.
value
)
return
surveyYearList
.
value
;
return
surveyYearList
.
value
.
slice
(
0
,
6
);
}
);
const
handleCheckAllYearsChange
=
val
=>
{
checkedSurveyYears
.
value
=
val
?
surveyYearList
.
value
.
map
(
y
=>
y
.
id
)
:
[];
isIndeterminateYears
.
value
=
false
;
const
checkedYearList
=
ref
([
''
]);
const
handleGetSearchAllYear
=
async
()
=>
{
try
{
const
res
=
await
getSearchAllYear
({
sortCode
:
"232"
}
);
if
(
res
.
code
===
200
)
{
let
allYear
=
res
.
data
.
sort
((
a
,
b
)
=>
(
b
-
a
));
let
beforeYear
=
allYear
.
slice
(
6
).
join
(
','
);
surveyYearList
.
value
=
allYear
.
slice
(
0
,
6
).
map
(
item
=>
({
name
:
item
+
"年"
,
id
:
item
}
));
if
(
beforeYear
)
surveyYearList
.
value
.
push
({
name
:
"更早"
,
id
:
beforeYear
}
);
}
}
catch
(
error
)
{
}
surveyYearList
.
value
.
unshift
({
name
:
"全部时间"
,
id
:
""
}
);
}
;
const
handleCheckedYearsChange
=
value
=>
{
const
checkedCount
=
value
.
length
;
checkAllYears
.
value
=
checkedCount
===
surveyYearList
.
value
.
length
;
isIndeterminateYears
.
value
=
checkedCount
>
0
&&
checkedCount
<
surveyYearList
.
value
.
length
;
const
handleCheckedYearsChange
=
event
=>
{
if
(
event
.
length
&&
event
[
event
.
length
-
1
]
!==
""
)
{
checkedYearList
.
value
=
event
.
filter
(
item
=>
item
!==
""
);
}
else
{
checkedYearList
.
value
=
[
""
];
}
currentPage
.
value
=
1
;
handleFetchSurveyList
();
}
;
// 数据列表
...
...
@@ -169,8 +163,8 @@ const handleFetchSurveyList = async () => {
currentPage
:
currentPage
.
value
-
1
,
pageSize
:
pageSize
.
value
,
sortCode
:
"232"
,
publishYear
:
check
AllYears
.
value
?
""
:
checkedSurveyYears
.
value
.
toString
()
,
Area
:
check
AllAreas
.
value
?
""
:
checkedAreaList
.
value
.
toString
()
,
publishYear
:
check
edYearList
.
value
.
join
(
','
)
||
null
,
Area
:
check
edAreaList
.
value
.
join
(
','
)
||
null
,
caseStatus
:
filterStage
.
value
,
keywords
:
searchText
.
value
,
sortField
:
"date"
,
...
...
@@ -199,39 +193,12 @@ const handleSearch = () => {
}
;
// 监听过滤条件
watch
([
checkedSurveyYears
,
checkedAreaList
,
isSort
,
filterStage
,
filterParty
,
filterReason
],
()
=>
{
watch
([
isSort
,
filterStage
,
filterParty
,
filterReason
],
()
=>
{
if
(
isInitializing
.
value
)
return
;
currentPage
.
value
=
1
;
handleFetchSurveyList
();
}
);
const
handleGetSearchAllArea
=
async
()
=>
{
try
{
const
res
=
await
getSearchAllArea
({
sortCode
:
"232"
}
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
surveyAreaList
.
value
=
res
.
data
.
map
(
item
=>
({
name
:
item
.
AREANAME
,
id
:
item
.
AREACODE
}
));
handleCheckAllAreasChange
(
true
);
}
}
catch
(
error
)
{
}
}
;
const
handleGetSearchAllYear
=
async
()
=>
{
try
{
const
res
=
await
getSearchAllYear
({
sortCode
:
"232"
}
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
const
sortedYears
=
res
.
data
.
sort
((
a
,
b
)
=>
b
-
a
);
surveyYearList
.
value
=
sortedYears
.
map
(
item
=>
({
name
:
item
+
"年"
,
id
:
item
}
));
handleCheckAllYearsChange
(
true
);
}
}
catch
(
error
)
{
}
}
;
onMounted
(
async
()
=>
{
await
Promise
.
all
([
handleGetSearchAllArea
(),
handleGetSearchAllYear
()]);
isInitializing
.
value
=
false
;
...
...
@@ -306,58 +273,50 @@ onMounted(async () => {
.
left
{
width
:
360
px
;
min
-
height
:
56
0
px
;
min
-
height
:
30
0
px
;
height
:
fit
-
content
;
padding
-
bottom
:
20
px
;
border
-
radius
:
10
px
;
box
-
shadow
:
0
px
0
px
15
px
0
px
rgba
(
60
,
87
,
126
,
0.2
);
background
:
#
fff
;
.
left
-
box
{
margin
-
top
:
17
px
;
.
left
-
header
{
display
:
flex
;
align
-
items
:
center
;
.
icon
{
.
check
-
box
{
margin
-
top
:
18
px
;
.
check
-
head
{
position
:
relative
;
margin
-
bottom
:
12
px
;
&
::
before
{
content
:
""
;
position
:
absolute
;
top
:
0
px
;
left
:
0
px
;
width
:
8
px
;
height
:
1
6
px
;
background
:
var
(
--
color
-
main
-
active
);
height
:
1
00
%
;
background
:
var
(
--
color
-
primary
-
100
);
border
-
radius
:
0
2
px
2
px
0
;
}
.
title
{
margin
-
left
:
17
px
;
color
:
var
(
--
color
-
main
-
active
);
.
head
-
name
{
margin
-
left
:
25
px
;
color
:
var
(
--
color
-
primary
-
100
);
font
-
size
:
16
px
;
font
-
weight
:
700
;
}
line
-
height
:
16
px
;
font
-
family
:
Source
Han
Sans
CN
;
font
-
weight
:
bold
;
}
}
.
checkbox
-
group
{
padding
:
10
px
0
0
25
px
;
.
filter
-
checkbox
{
width
:
130
px
;
margin
-
bottom
:
8
px
;
.
check
-
list
{
padding
:
0
10
px
0
25
px
;
display
:
grid
;
grid
-
template
-
columns
:
repeat
(
2
,
1
fr
);
grid
-
gap
:
0
12
px
;
.
check
-
item
{
width
:
100
%
;
height
:
32
px
;
:
deep
(.
el
-
checkbox__label
)
{
font
-
family
:
Source
Han
Sans
CN
;
font
-
size
:
16
px
;
color
:
#
5
f656c
;
}
color
:
var
(
--
text
-
primary
-
65
-
color
);
}
.
expand
-
btn
{
color
:
var
(
--
color
-
main
-
active
);
font
-
size
:
14
px
;
cursor
:
pointer
;
display
:
flex
;
align
-
items
:
center
;
margin
-
top
:
4
px
;
.
el
-
icon
{
margin
-
left
:
4
px
;
}
}
}
...
...
src/views/marketAccessRestrictions/marketAccessLayout/case/301/index.vue
浏览文件 @
8d534f1e
...
...
@@ -21,39 +21,26 @@
<div
class=
"wrapper-main"
>
<div
class=
"left"
>
<!-- 科技领域 -->
<div
class=
"left-box"
>
<div
class=
"left-header"
>
<div
class=
"icon"
></div>
<div
class=
"title"
>
{{
"科技领域"
}}
</div>
<div
class=
"check-box"
>
<div
class=
"check-head"
>
<div
class=
"head-name"
>
{{
"科技领域"
}}
</div>
</div>
<div
class=
"left-main"
>
<el-checkbox-group
class=
"checkbox-group"
v-model=
"checkedAreaList"
@
change=
"handleCheckedAreasChange"
>
<el-checkbox
class=
"filter-checkbox"
label=
"全部领域"
>
全部领域
</el-checkbox>
<el-checkbox
v-for=
"area in surveyAreaList"
:key=
"area.id"
:label=
"area.id"
class=
"filter-checkbox"
>
{{
area
.
name
}}
<el-checkbox-group
class=
"check-list"
v-model=
"checkedAreaList"
@
change=
"handleCheckedAreasChange"
>
<el-checkbox
class=
"check-item"
v-for=
"item in surveyAreaList"
:key=
"item.id"
:label=
"item.id"
>
{{
item
.
name
}}
</el-checkbox>
</el-checkbox-group>
</div>
</div>
<!-- 发布时间 -->
<div
class=
"left-box"
>
<div
class=
"left-header"
>
<div
class=
"icon"
></div>
<div
class=
"title"
>
{{
"发布时间"
}}
</div>
<div
class=
"check-box"
>
<div
class=
"check-head"
>
<div
class=
"head-name"
>
{{
"发布时间"
}}
</div>
</div>
<div
class=
"left-main"
>
<el-checkbox-group
class=
"checkbox-group"
v-model=
"checkedSurveyYears"
@
change=
"handleCheckedYearsChange"
>
<el-checkbox
class=
"filter-checkbox"
label=
"全部时间"
>
全部时间
</el-checkbox>
<el-checkbox
v-for=
"year in displayedYearList"
:key=
"year.id"
:label=
"year.id"
class=
"filter-checkbox"
>
{{
year
.
name
}}
<el-checkbox-group
class=
"check-list"
v-model=
"checkedYearList"
@
change=
"handleCheckedYearsChange"
>
<el-checkbox
class=
"check-item"
v-for=
"item in surveyYearList"
:key=
"item.id"
:label=
"item.id"
>
{{
item
.
name
}}
</el-checkbox>
<div
v-if=
"surveyYearList.length > 6"
class=
"expand-btn"
@
click=
"isYearExpanded = !isYearExpanded"
>
{{
isYearExpanded
?
"收起"
:
"更早"
}}
<el-icon>
<ArrowUp
v-if=
"isYearExpanded"
/>
<ArrowDown
v-else
/>
</el-icon>
</div>
</el-checkbox-group>
</div>
</div>
...
...
@@ -78,8 +65,8 @@
<
/template
>
<
script
setup
>
import
{
ref
,
onMounted
,
watch
,
computed
}
from
"vue"
;
import
{
Search
,
ArrowDown
,
ArrowUp
}
from
"@element-plus/icons-vue"
;
import
{
ref
,
onMounted
,
watch
}
from
"vue"
;
import
{
Search
}
from
"@element-plus/icons-vue"
;
import
{
getSearchAllArea
,
getSearchAllYear
,
getSurveyList
}
from
"@/api/marketAccessRestrictions"
;
import
SurveyHistory
from
"@/views/marketAccessRestrictions/com/SurveyHistory.vue"
...
...
@@ -88,46 +75,51 @@ const handleSwithSort = () => {
isSort
.
value
=
!
isSort
.
value
;
}
;
const
surveyYearList
=
ref
([]);
const
checkedSurveyYears
=
ref
([]);
const
isYearExpanded
=
ref
(
false
);
const
displayedYearList
=
computed
(()
=>
{
if
(
isYearExpanded
.
value
)
{
return
surveyYearList
.
value
;
// 科技领域过滤
const
surveyAreaList
=
ref
([]);
const
checkedAreaList
=
ref
([
''
]);
const
handleGetSearchAllArea
=
async
()
=>
{
try
{
const
res
=
await
getSearchAllArea
({
sortCode
:
"301"
}
);
if
(
res
.
code
===
200
)
{
surveyAreaList
.
value
=
res
.
data
.
map
(
item
=>
({
name
:
item
.
AREANAME
,
id
:
item
.
AREACODE
}
));
}
return
surveyYearList
.
value
.
slice
(
0
,
6
);
}
);
const
checkAllYears
=
ref
(
false
);
const
isIndeterminateYears
=
ref
(
false
);
const
handleCheckAllYearsChange
=
(
val
)
=>
{
checkedSurveyYears
.
value
=
val
?
surveyYearList
.
value
.
map
(
y
=>
y
.
id
)
:
[];
isIndeterminateYears
.
value
=
false
;
}
catch
(
error
)
{
}
surveyAreaList
.
value
.
unshift
({
name
:
"全部领域"
,
id
:
""
}
);
}
;
const
handleCheckedYearsChange
=
(
value
)
=>
{
const
checkedCount
=
value
.
length
;
checkAllYears
.
value
=
checkedCount
===
surveyYearList
.
value
.
length
;
isIndeterminateYears
.
value
=
checkedCount
>
0
&&
checkedCount
<
surveyYearList
.
value
.
length
;
const
handleCheckedAreasChange
=
event
=>
{
if
(
event
.
length
&&
event
[
event
.
length
-
1
]
!==
""
)
{
checkedAreaList
.
value
=
event
.
filter
(
item
=>
item
!==
""
);
}
else
{
checkedAreaList
.
value
=
[
""
];
}
currentPage
.
value
=
1
;
handleFetchSurveyList
();
}
;
const
surveyAreaList
=
ref
([]);
const
checkedAreaList
=
ref
([]);
const
checkAllAreas
=
ref
(
false
);
const
isIndeterminateAreas
=
ref
(
false
);
const
handleCheckAllAreasChange
=
(
val
)
=>
{
checkedAreaList
.
value
=
val
?
surveyAreaList
.
value
.
map
(
a
=>
a
.
id
)
:
[];
isIndeterminateAreas
.
value
=
false
;
// 发布时间过滤
const
surveyYearList
=
ref
([]);
const
checkedYearList
=
ref
([
''
]);
const
handleGetSearchAllYear
=
async
()
=>
{
try
{
const
res
=
await
getSearchAllYear
({
sortCode
:
"301"
}
);
if
(
res
.
code
===
200
)
{
let
allYear
=
res
.
data
.
sort
((
a
,
b
)
=>
(
b
-
a
));
let
beforeYear
=
allYear
.
slice
(
6
).
join
(
','
);
surveyYearList
.
value
=
allYear
.
slice
(
0
,
6
).
map
(
item
=>
({
name
:
item
+
"年"
,
id
:
item
}
));
if
(
beforeYear
)
surveyYearList
.
value
.
push
({
name
:
"更早"
,
id
:
beforeYear
}
);
}
}
catch
(
error
)
{
}
surveyYearList
.
value
.
unshift
({
name
:
"全部时间"
,
id
:
""
}
);
}
;
const
handleCheckedAreasChange
=
(
value
)
=>
{
const
checkedCount
=
value
.
length
;
checkAllAreas
.
value
=
checkedCount
===
surveyAreaList
.
value
.
length
;
isIndeterminateAreas
.
value
=
checkedCount
>
0
&&
checkedCount
<
surveyAreaList
.
value
.
length
;
const
handleCheckedYearsChange
=
event
=>
{
if
(
event
.
length
&&
event
[
event
.
length
-
1
]
!==
""
)
{
checkedYearList
.
value
=
event
.
filter
(
item
=>
item
!==
""
);
}
else
{
checkedYearList
.
value
=
[
""
];
}
currentPage
.
value
=
1
;
handleFetchSurveyList
();
}
;
const
totalDiscussNum
=
ref
(
0
);
...
...
@@ -145,8 +137,8 @@ const handleFetchSurveyList = async () => {
currentPage
:
currentPage
.
value
-
1
,
pageSize
:
pageSize
.
value
,
sortCode
:
"301"
,
publishYear
:
check
AllYears
.
value
?
""
:
checkedSurveyYears
.
value
.
toString
()
,
Area
:
check
AllAreas
.
value
?
""
:
checkedAreaList
.
value
.
toString
()
,
publishYear
:
check
edYearList
.
value
.
join
(
','
)
||
null
,
Area
:
check
edAreaList
.
value
.
join
(
','
)
||
null
,
// keywords: searchText.value,
sortField
:
"date"
,
sortOrder
:
isSort
.
value
?
"asc"
:
"desc"
...
...
@@ -173,60 +165,11 @@ const handleSearch = () => {
handleFetchSurveyList
();
}
;
watch
(
[
checkedSurveyYears
,
checkedAreaList
,
isSort
],
()
=>
{
watch
([
isSort
],
()
=>
{
if
(
isInitializing
.
value
)
return
;
currentPage
.
value
=
1
;
handleFetchSurveyList
();
}
,
{
deep
:
true
}
);
const
handleGetSearchAllArea
=
async
()
=>
{
try
{
const
res
=
await
getSearchAllArea
({
sortCode
:
'301'
}
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
surveyAreaList
.
value
=
res
.
data
.
map
(
item
=>
{
return
{
name
:
item
.
AREANAME
,
id
:
item
.
AREACODE
}
;
}
);
// 默认选中全部
checkAllAreas
.
value
=
true
;
handleCheckAllAreasChange
(
true
);
}
}
catch
(
error
)
{
}
}
const
handleGetSearchAllYear
=
async
()
=>
{
try
{
const
res
=
await
getSearchAllYear
({
sortCode
:
'301'
}
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
// 排序并格式化
const
sortedYears
=
res
.
data
.
sort
((
a
,
b
)
=>
b
-
a
);
surveyYearList
.
value
=
sortedYears
.
map
(
item
=>
{
return
{
name
:
item
+
'年'
,
id
:
item
}
;
}
);
// 默认选中全部
checkAllYears
.
value
=
true
;
handleCheckAllYearsChange
(
true
);
}
}
catch
(
error
)
{
}
}
}
);
onMounted
(
async
()
=>
{
await
Promise
.
all
([
handleGetSearchAllArea
(),
handleGetSearchAllYear
()]);
...
...
@@ -309,59 +252,51 @@ onMounted(async () => {
.
left
{
width
:
360
px
;
min
-
height
:
56
0
px
;
min
-
height
:
30
0
px
;
height
:
fit
-
content
;
padding
-
bottom
:
20
px
;
border
-
radius
:
10
px
;
box
-
shadow
:
0
px
0
px
15
px
0
px
rgba
(
60
,
87
,
126
,
0.2
);
background
:
#
fff
;
.
left
-
box
{
margin
-
top
:
17
px
;
.
left
-
header
{
display
:
flex
;
align
-
items
:
center
;
.
icon
{
.
check
-
box
{
margin
-
top
:
18
px
;
.
check
-
head
{
position
:
relative
;
margin
-
bottom
:
12
px
;
&
::
before
{
content
:
""
;
position
:
absolute
;
top
:
0
px
;
left
:
0
px
;
width
:
8
px
;
height
:
1
6
px
;
background
:
var
(
--
color
-
main
-
active
);
height
:
1
00
%
;
background
:
var
(
--
color
-
primary
-
100
);
border
-
radius
:
0
2
px
2
px
0
;
}
.
title
{
margin
-
left
:
17
px
;
color
:
var
(
--
color
-
main
-
active
);
.
head
-
name
{
margin
-
left
:
25
px
;
color
:
var
(
--
color
-
primary
-
100
);
font
-
size
:
16
px
;
font
-
weight
:
700
;
}
line
-
height
:
16
px
;
font
-
family
:
Source
Han
Sans
CN
;
font
-
weight
:
bold
;
}
}
.
checkbox
-
group
{
padding
:
10
px
0
0
25
px
;
.
filter
-
checkbox
{
width
:
130
px
;
margin
-
bottom
:
8
px
;
.
check
-
list
{
padding
:
0
10
px
0
25
px
;
display
:
grid
;
grid
-
template
-
columns
:
repeat
(
2
,
1
fr
);
grid
-
gap
:
0
12
px
;
.
check
-
item
{
width
:
100
%
;
height
:
32
px
;
:
deep
(.
el
-
checkbox__label
)
{
font
-
family
:
Source
Han
Sans
CN
;
font
-
size
:
16
px
;
color
:
#
5
f656c
;
color
:
var
(
--
text
-
primary
-
65
-
color
)
;
}
}
.
expand
-
btn
{
color
:
var
(
--
color
-
main
-
active
);
font
-
size
:
14
px
;
cursor
:
pointer
;
display
:
flex
;
align
-
items
:
center
;
margin
-
top
:
4
px
;
.
el
-
icon
{
margin
-
left
:
4
px
;
}
}
}
}
...
...
src/views/marketAccessRestrictions/marketAccessLayout/case/337/index.vue
浏览文件 @
8d534f1e
...
...
@@ -33,54 +33,38 @@
<div
class=
"wrapper-main"
>
<div
class=
"left"
>
<!-- 科技领域 -->
<div
class=
"left-box"
>
<div
class=
"left-header"
>
<div
class=
"icon"
></div>
<div
class=
"title"
>
{{ "科技领域" }}
</div>
<div
class=
"check-box"
>
<div
class=
"check-head"
>
<div
class=
"head-name"
>
{{ "科技领域" }}
</div>
</div>
<div
class=
"left-main"
>
<el-checkbox-group
class=
"checkbox-group"
v-model=
"checkedAreaList"
@
change=
"handleCheckedAreasChange"
>
<el-checkbox
class=
"filter-checkbox"
label=
"全部领域"
>
全部领域
</el-checkbox>
<el-checkbox
v-for=
"area in surveyAreaList"
:key=
"area.id"
:label=
"area.id"
class=
"filter-checkbox"
>
{{ area.name }}
<el-checkbox-group
class=
"check-list"
v-model=
"checkedAreaList"
@
change=
"handleCheckedAreasChange"
>
<el-checkbox
class=
"check-item"
v-for=
"item in surveyAreaList"
:key=
"item.id"
:label=
"item.id"
>
{{ item.name }}
</el-checkbox>
</el-checkbox-group>
</div>
</div>
<!-- 发布时间 -->
<div
class=
"left-box"
>
<div
class=
"left-header"
>
<div
class=
"icon"
></div>
<div
class=
"title"
>
{{ "发布时间" }}
</div>
<div
class=
"check-box"
>
<div
class=
"check-head"
>
<div
class=
"head-name"
>
{{ "发布时间" }}
</div>
</div>
<div
class=
"left-main"
>
<el-checkbox-group
class=
"checkbox-group"
v-model=
"checkedSurveyYears"
@
change=
"handleCheckedYearsChange"
>
<el-checkbox
class=
"filter-checkbox"
label=
"全部时间"
>
全部时间
</el-checkbox>
<el-checkbox
v-for=
"year in displayedYearList"
:key=
"year.id"
:label=
"year.id"
class=
"filter-checkbox"
>
{{ year.name }}
<el-checkbox-group
class=
"check-list"
v-model=
"checkedYearList"
@
change=
"handleCheckedYearsChange"
>
<el-checkbox
class=
"check-item"
v-for=
"item in surveyYearList"
:key=
"item.id"
:label=
"item.id"
>
{{ item.name }}
</el-checkbox>
<div
v-if=
"surveyYearList.length > 6"
class=
"expand-btn"
@
click=
"isYearExpanded = !isYearExpanded"
>
{{ isYearExpanded ? "收起" : "更早" }}
<el-icon>
<ArrowUp
v-if=
"isYearExpanded"
/>
<ArrowDown
v-else
/>
</el-icon>
</div>
</el-checkbox-group>
</div>
</div>
<!-- 受调查国家/地区 -->
<div
class=
"left-box"
>
<div
class=
"left-header"
>
<div
class=
"icon"
></div>
<div
class=
"title"
>
{{ "受调查国家/地区" }}
</div>
<div
class=
"check-box"
>
<div
class=
"check-head"
>
<div
class=
"head-name"
>
{{ "受调查国家/地区" }}
</div>
</div>
<div
class=
"left-main"
>
<el-checkbox-group
class=
"checkbox-group"
v-model=
"checkedCountryList"
@
change=
"handleCheckedCountriesChange"
>
<el-checkbox
class=
"filter-checkbox"
label=
"全部"
>
全部
</el-checkbox>
<el-checkbox
v-for=
"area in surveyCountryList"
:key=
"area.id"
:label=
"area.id"
class=
"filter-checkbox"
>
{{ area.name }}
<el-checkbox-group
class=
"check-list"
v-model=
"checkedCountryList"
@
change=
"handleCheckedCountriesChange"
>
<el-checkbox
class=
"check-item"
v-for=
"item in surveyCountryList"
:key=
"item.id"
:label=
"item.id"
>
{{ item.name }}
</el-checkbox>
</el-checkbox-group>
</div>
...
...
@@ -103,8 +87,8 @@
</template>
<
script
setup
>
import
{
ref
,
onMounted
,
watch
,
computed
}
from
"vue"
;
import
{
Search
,
ArrowDown
,
ArrowUp
}
from
"@element-plus/icons-vue"
;
import
{
ref
,
onMounted
,
watch
}
from
"vue"
;
import
{
Search
}
from
"@element-plus/icons-vue"
;
import
{
getSearchAllArea
,
getSearchAllYear
,
getSurveyList
,
getSearchAllCountry
}
from
"@/api/marketAccessRestrictions"
;
import
AnalysisBox
from
"@/components/base/boxBackground/analysisBox.vue"
...
...
@@ -131,61 +115,71 @@ const releaseTimeList = ref([
// 科技领域过滤
const
surveyAreaList
=
ref
([]);
const
checkedAreaList
=
ref
([
'全部领域'
]);
const
handleCheckedAreasChange
=
val
=>
{
if
(
val
.
includes
(
"全部领域"
)
&&
val
.
length
>
1
)
{
if
(
val
[
val
.
length
-
1
]
===
"全部领域"
)
{
checkedAreaList
.
value
=
[
"全部领域"
];
}
else
{
checkedAreaList
.
value
=
val
.
filter
(
item
=>
item
!==
"全部领域"
);
const
checkedAreaList
=
ref
([
''
]);
const
handleGetSearchAllArea
=
async
()
=>
{
try
{
const
res
=
await
getSearchAllArea
({
sortCode
:
"337"
});
if
(
res
.
code
===
200
)
{
surveyAreaList
.
value
=
res
.
data
.
map
(
item
=>
({
name
:
item
.
AREANAME
,
id
:
item
.
AREACODE
}));
}
}
else
if
(
val
.
length
===
0
)
{
checkedAreaList
.
value
=
[
"全部领域"
];
}
catch
(
error
)
{}
surveyAreaList
.
value
.
unshift
({
name
:
"全部领域"
,
id
:
""
});
};
const
handleCheckedAreasChange
=
event
=>
{
if
(
event
.
length
&&
event
[
event
.
length
-
1
]
!==
""
)
{
checkedAreaList
.
value
=
event
.
filter
(
item
=>
item
!==
""
);
}
else
{
checkedAreaList
.
value
=
[
""
];
}
currentPage
.
value
=
1
;
handleFetchSurveyList
();
};
// 发布时间过滤
const
surveyYearList
=
ref
([]);
const
checkedSurveyYears
=
ref
([
'全部时间'
]);
const
isYearExpanded
=
ref
(
false
);
const
displayedYearList
=
computed
(()
=>
{
if
(
isYearExpanded
.
value
)
return
surveyYearList
.
value
;
return
surveyYearList
.
value
.
slice
(
0
,
6
);
});
const
handleCheckedYearsChange
=
value
=>
{
// const checkedCount = value.length;
// checkAllYears.value = checkedCount === surveyYearList.value.length;
// isIndeterminateYears.value = checkedCount > 0 && checkedCount
<
surveyYearList
.
value
.
length
;
if
(
val
.
includes
(
"全部时间"
)
&&
val
.
length
>
1
)
{
if
(
val
[
val
.
length
-
1
]
===
"全部时间"
)
{
checkedSurveyYears
.
value
=
[
"全部时间"
];
}
else
{
checkedSurveyYears
.
value
=
val
.
filter
(
item
=>
item
!==
"全部时间"
);
const
checkedYearList
=
ref
([
''
]);
const
handleGetSearchAllYear
=
async
()
=>
{
try
{
const
res
=
await
getSearchAllYear
({
sortCode
:
"337"
});
if
(
res
.
code
===
200
)
{
let
allYear
=
res
.
data
.
sort
((
a
,
b
)
=>
(
b
-
a
));
let
beforeYear
=
allYear
.
slice
(
6
).
join
(
','
);
surveyYearList
.
value
=
allYear
.
slice
(
0
,
6
).
map
(
item
=>
({
name
:
item
+
"年"
,
id
:
item
}));
if
(
beforeYear
)
surveyYearList
.
value
.
push
({
name
:
"更早"
,
id
:
beforeYear
});
}
}
else
if
(
val
.
length
===
0
)
{
checkedSurveyYears
.
value
=
[
"全部时间"
];
}
catch
(
error
)
{}
surveyYearList
.
value
.
unshift
({
name
:
"全部时间"
,
id
:
""
});
};
const
handleCheckedYearsChange
=
event
=>
{
if
(
event
.
length
&&
event
[
event
.
length
-
1
]
!==
""
)
{
checkedYearList
.
value
=
event
.
filter
(
item
=>
item
!==
""
);
}
else
{
checkedYearList
.
value
=
[
""
];
}
currentPage
.
value
=
1
;
handleFetchSurveyList
();
};
// 受调查国家/地区过滤
const
surveyCountryList
=
ref
([]);
const
checkedCountryList
=
ref
([
'全部'
]);
const
handleCheckedCountriesChange
=
val
=>
{
if
(
val
.
includes
(
"全部"
)
&&
val
.
length
>
1
)
{
if
(
val
[
val
.
length
-
1
]
===
"全部"
)
{
checkedCountryList
.
value
=
[
"全部"
];
}
else
{
checkedCountryList
.
value
=
val
.
filter
(
item
=>
item
!==
"全部"
);
const
checkedCountryList
=
ref
([
''
]);
const
handleGetSearchAllCountry
=
async
()
=>
{
try
{
const
res
=
await
getSearchAllCountry
();
if
(
res
.
code
===
200
)
{
surveyCountryList
.
value
=
res
.
data
.
map
(
item
=>
({
name
:
item
.
COUNTRYNAME
,
id
:
item
.
COUNTRYID
}));
}
}
else
if
(
val
.
length
===
0
)
{
checkedCountryList
.
value
=
[
"全部"
];
}
catch
(
error
)
{}
surveyCountryList
.
value
.
unshift
({
name
:
"全部"
,
id
:
""
});
};
const
handleCheckedCountriesChange
=
event
=>
{
if
(
event
.
length
&&
event
[
event
.
length
-
1
]
!==
""
)
{
checkedCountryList
.
value
=
event
.
filter
(
item
=>
item
!==
""
);
}
else
{
checkedCountryList
.
value
=
[
""
];
}
currentPage
.
value
=
1
;
handleFetchSurveyList
();
};
// 数据列表
...
...
@@ -203,9 +197,9 @@ const handleFetchSurveyList = async () => {
currentPage
:
currentPage
.
value
-
1
,
pageSize
:
pageSize
.
value
,
sortCode
:
"337"
,
publishYear
:
checked
SurveyYears
.
value
[
0
]
===
'全部时间'
?
null
:
checkedSurveyYears
.
value
.
toString
()
,
Area
:
checkedAreaList
.
value
[
0
]
===
'全部领域'
?
null
:
checkedAreaList
.
value
.
toString
()
,
searchCountry
:
checkedCountryList
.
value
[
0
]
===
'全部'
?
null
:
checkedCountryList
.
value
.
toString
()
,
publishYear
:
checked
YearList
.
value
.
join
(
','
)
||
null
,
Area
:
checkedAreaList
.
value
.
join
(
','
)
||
null
,
searchCountry
:
checkedCountryList
.
value
.
join
(
','
)
||
null
,
caseStatus
:
filterStage
.
value
?
filterStage
.
value
:
null
,
keywords
:
searchText
.
value
?
searchText
.
value
:
null
,
sortField
:
"date"
,
...
...
@@ -234,52 +228,11 @@ const handleSearch = () => {
};
// 监听过滤条件
watch
(
[
checkedSurveyYears
,
checkedAreaList
,
checkedCountryList
,
isSort
,
filterStage
,
filterParty
,
filterReason
],
()
=>
{
watch
([
isSort
,
filterStage
,
filterParty
,
filterReason
],
()
=>
{
if
(
isInitializing
.
value
)
return
;
currentPage
.
value
=
1
;
handleFetchSurveyList
();
}
);
const
handleGetSearchAllArea
=
async
()
=>
{
try
{
const
res
=
await
getSearchAllArea
({
sortCode
:
"337"
});
if
(
res
.
code
===
200
&&
res
.
data
)
{
surveyAreaList
.
value
=
res
.
data
.
map
(
item
=>
({
name
:
item
.
AREANAME
,
id
:
item
.
AREACODE
}));
handleCheckAllAreasChange
(
true
);
}
}
catch
(
error
)
{
}
};
const
handleGetSearchAllYear
=
async
()
=>
{
try
{
const
res
=
await
getSearchAllYear
({
sortCode
:
"337"
});
if
(
res
.
code
===
200
&&
res
.
data
)
{
const
sortedYears
=
res
.
data
.
sort
((
a
,
b
)
=>
b
-
a
);
surveyYearList
.
value
=
sortedYears
.
map
(
item
=>
({
name
:
item
+
"年"
,
id
:
item
}));
}
}
catch
(
error
)
{
}
};
const
handleGetSearchAllCountry
=
async
()
=>
{
try
{
const
res
=
await
getSearchAllCountry
();
if
(
res
.
code
===
200
&&
res
.
data
)
{
surveyCountryList
.
value
=
res
.
data
.
map
(
item
=>
({
name
:
item
.
COUNTRYNAME
,
id
:
item
.
COUNTRYID
}));
}
}
catch
(
error
)
{
}
};
});
onMounted
(
async
()
=>
{
await
Promise
.
all
([
handleGetSearchAllArea
(),
handleGetSearchAllYear
(),
handleGetSearchAllCountry
()]);
...
...
@@ -360,58 +313,50 @@ onMounted(async () => {
.left
{
width
:
360px
;
min-height
:
56
0px
;
min-height
:
30
0px
;
height
:
fit-content
;
padding-bottom
:
20px
;
border-radius
:
10px
;
box-shadow
:
0px
0px
15px
0px
rgba
(
60
,
87
,
126
,
0
.2
);
background
:
#fff
;
.left-box
{
margin-top
:
17px
;
.left-header
{
display
:
flex
;
align-items
:
center
;
.icon
{
.check-box
{
margin-top
:
18px
;
.check-head
{
position
:
relative
;
margin-bottom
:
12px
;
&
:
:
before
{
content
:
""
;
position
:
absolute
;
top
:
0px
;
left
:
0px
;
width
:
8px
;
height
:
1
6px
;
background
:
var
(
--
color-
main-active
);
height
:
1
00%
;
background
:
var
(
--
color-
primary-100
);
border-radius
:
0
2px
2px
0
;
}
.title
{
margin-left
:
17px
;
color
:
var
(
--
color-main-active
);
.head-name
{
margin-left
:
25px
;
color
:
var
(
--
color-primary-100
);
font-size
:
16px
;
font-weight
:
700
;
}
line-height
:
16px
;
font-family
:
Source
Han
Sans
CN
;
font-weight
:
bold
;
}
}
.checkbox-group
{
padding
:
10px
0
0
25px
;
.filter-checkbox
{
width
:
130px
;
margin-bottom
:
8px
;
.check-list
{
padding
:
0
10px
0
25px
;
display
:
grid
;
grid-template-columns
:
repeat
(
2
,
1fr
);
grid-gap
:
0
12px
;
.check-item
{
width
:
100%
;
height
:
32px
;
:deep
(
.el-checkbox__label
)
{
font-family
:
Source
Han
Sans
CN
;
font-size
:
16px
;
color
:
#5f656c
;
}
color
:
var
(
--
text-primary-65-color
);
}
.expand-btn
{
color
:
var
(
--
color-main-active
);
font-size
:
14px
;
cursor
:
pointer
;
display
:
flex
;
align-items
:
center
;
margin-top
:
4px
;
.el-icon
{
margin-left
:
4px
;
}
}
}
...
...
src/views/marketAccessRestrictions/singleCaseLayout/overview/232/index.vue
浏览文件 @
8d534f1e
...
...
@@ -100,7 +100,12 @@
<
script
setup
>
import
{
ref
,
onMounted
}
from
"vue"
;
import
{
useRoute
}
from
"vue-router"
;
import
{
getSearchBlurb
,
getSearchContext
,
getSearchConclusion
}
from
"@/api/marketAccessRestrictions"
;
import
{
getSearchBlurb
,
getSearchContext
,
getSearchConclusion
,
getRelatedEvents
,
}
from
"@/api/marketAccessRestrictions"
;
import
RelatedEvent
from
"@/views/marketAccessRestrictions/com/RelatedEvent.vue"
;
import
SurveyConclusion
from
"@/views/marketAccessRestrictions/com/SurveyConclusion.vue"
;
...
...
@@ -181,26 +186,21 @@ const handleGetSearchConclusion = async () => {
}
;
// 相关行政举措
const
eventList
=
ref
([
{
name
:
"某些特定外国制造的半导体器件及其下游产品和组件;委员会最终裁定未违反第337条的通知;调查终止"
,
text
:
"特此通知,2025 年 2 月 18 日,根据 1930 年《关税法》第 337 条(经修订)已代表爱尔兰 Longitude Licensing Ltd.和爱尔"
,
time
:
"2025年4月15日"
}
,
{
name
:
"某些特定外国制造的半导体器件及其下游产品和组件;委员会最终裁定未违反第337条的通知;调查终止"
,
text
:
"特此通知,2025 年 2 月 18 日,根据 1930 年《关税法》第 337 条(经修订)已代表爱尔兰 Longitude Licensing Ltd.和爱尔"
,
time
:
"2025年4月15日"
}
,
{
name
:
"某些特定外国制造的半导体器件及其下游产品和组件;委员会最终裁定未违反第337条的通知;调查终止"
,
text
:
"特此通知,2025 年 2 月 18 日,根据 1930 年《关税法》第 337 条(经修订)已代表爱尔兰 Longitude Licensing Ltd.和爱尔"
,
time
:
"2025年4月15日"
}
,
])
const
eventList
=
ref
([])
const
handleGetRelatedEvents
=
async
()
=>
{
try
{
const
res
=
await
getRelatedEvents
({
searchId
:
route
.
query
.
searchId
}
);
if
(
res
.
code
===
200
)
eventList
.
value
=
res
.
data
||
[];
}
catch
(
error
)
{
console
.
error
(
"获取相关行政举措失败"
,
error
);
}
}
;
onMounted
(()
=>
{
handleGetSearchBlurb
();
handleGetRelatedEvents
();
handleGetSearchContext
();
handleGetSearchConclusion
();
}
);
...
...
src/views/marketAccessRestrictions/singleCaseLayout/overview/301/index.vue
浏览文件 @
8d534f1e
<
template
>
<div
class=
"wrapper"
>
<div
class=
"left"
>
<div
class=
"box1"
v-loading=
"leftLoading"
>
<div
class=
"box-header"
>
<div
class=
"header-left"
></div>
<div
class=
"title"
>
基本信息
</div>
<div
class=
"header-right"
>
<div
class=
"icon"
>
<img
src=
"@/assets/icons/box-header-icon3.png"
alt=
""
/>
</div>
</div>
</div>
<AnalysisBox
title=
"基本信息"
:showAllBtn=
"false"
height=
"auto"
>
<div
class=
"box1-main"
>
<div
class=
"box1-item"
>
<div
class=
"box1-item-left"
>
{{
"启动时间:"
}}
</div>
...
...
@@ -34,14 +25,8 @@
<div
class=
"box1-item"
>
<div
class=
"box1-item-left"
>
{{
"调查领域:"
}}
</div>
<div
class=
"box1-item-right2"
>
<div
class=
"tag"
:class=
"
{ tag1: tag.type === 1, tag2: tag.type === 2 }"
v-for="(tag, index) in surveyAreaList"
:key="index"
>
{{
tag
.
name
}}
</div>
<AreaTag
v-for=
"(item, num) in surveyAreaList"
:key=
"num"
:tagName=
"item.name"
></AreaTag>
<div
v-if=
"!surveyAreaList?.length"
>
-
</div>
</div>
</div>
<div
class=
"box1-item"
>
...
...
@@ -68,50 +53,22 @@
</div>
</div>
</div>
</div>
<div
class=
"box2"
v-loading=
"leftLoading"
>
<div
class=
"box-header"
>
<div
class=
"header-left"
></div>
<div
class=
"title"
>
调查公告
</div>
<div
class=
"header-right"
>
<div
class=
"icon"
>
<img
src=
"@/assets/icons/box-header-icon3.png"
alt=
""
/>
</div>
</div>
</div>
<div
class=
"box2-main"
>
<div
class=
"box2-item"
v-for=
"(item, index) in box2Data"
:key=
"index"
>
<div
class=
"box2-item-left"
>
<img
src=
"./assets/images/box2-icon.png"
alt=
""
/>
</div>
<div
class=
"box2-item-right"
>
<div
class=
"time"
>
{{ item.time }}
</div>
<div
class=
"content"
>
{{ item.content }}
</div>
</div>
</div>
</div>
</div>
</AnalysisBox>
<SurveyAffiche
title=
"调查公告"
:listData=
"box2Data"
></SurveyAffiche>
</div>
<div
class=
"right"
>
<
div
class=
"box3"
v-loading=
"box3Loading
"
>
<
div
class=
"box-header"
>
<
AnalysisBox
:showAllBtn=
"false"
height=
"auto
"
>
<
template
#
custom-title
>
<div
class=
"btn-box"
>
<div
class=
"btn"
<div
class=
"btn"
:class=
"
{ btnActive: box3BtnActive === item }"
v-for=
"(item, index) in box3BtnList"
:key=
"index"
v-for="(item, index) in box3BtnList" :key="index"
@click="handleClickBox3Btn(item)"
>
{{
item
}}
</div>
</div>
<div
class=
"header-right"
>
<div
class=
"icon"
>
<img
src=
"@/assets/icons/box-header-icon3.png"
alt=
""
/>
</div>
</div>
</div>
</
template
>
<div
class=
"box3-main"
>
<div
class=
"box3-main1"
v-if=
"box3BtnActive === '事件脉络'"
>
<div
class=
"box3-main1-item"
v-for=
"(item, index) in box3Data1"
:key=
"index"
>
...
...
@@ -123,10 +80,10 @@
</div>
<div
class=
"right"
>
<div
class=
"header"
>
<div
class=
"time"
>
{{ item.
time
}}
</div>
<div
class=
"title"
>
{{ item.
title
}}
</div>
<div
class=
"time"
>
{{ item.
CONTTIME
}}
</div>
<div
class=
"title"
>
{{ item.
CONTNODE
}}
</div>
</div>
<div
class=
"content"
>
{{ item.
content
}}
</div>
<div
class=
"content"
>
{{ item.
CONTDESC
}}
</div>
</div>
</div>
</div>
...
...
@@ -151,60 +108,27 @@
</div>
</div>
</div>
</div>
<div
class=
"box4"
v-loading=
"box4Loading"
>
<div
class=
"box-header"
>
<div
class=
"header-left"
></div>
<div
class=
"title"
>
相关事件
</div>
<div
class=
"header-right"
>
<div
class=
"icon"
>
<img
src=
"@/assets/icons/box-header-icon3.png"
alt=
""
/>
</div>
</div>
</div>
<div
class=
"box4-main"
>
<div
class=
"box4-main-item"
v-for=
"(item, index) in box4Data"
:key=
"index"
>
<div
class=
"item-left"
>
<div
class=
"item-left-tag"
:class=
"{
tag1: item.tag.type == '新闻',
tag2: item.tag.type == '行政令',
tag3: item.tag.type == '法案',
}"
>
{{ item.tag.name }}
</div>
</div>
<div
class=
"item-right"
>
<div
class=
"item-right-header"
>
<div
class=
"item-right-title"
>
{{ item.title }}
</div>
<div
class=
"item-right-time"
>
{{ item.time }}
</div>
</div>
<div
class=
"item-right-content"
>
{{ item.content }}
</div>
</div>
</div>
</div>
</div>
</AnalysisBox>
<RelatedEvent
title=
"相关事件"
:listData=
"eventList"
></RelatedEvent>
</div>
</div>
</template>
<
script
setup
>
import
{
ref
,
onMounted
}
from
"vue"
;
import
{
useRoute
}
from
"vue-router"
;
import
{
getSearchBlurb
,
getRelatedEvents
,
getSearchContext
,
getSearchMeasures
}
from
"@/api/marketAccessRestrictions"
;
import
{
getSearchBlurb
,
getRelatedEvents
,
getSearchContext
,
getSearchMeasures
,
}
from
"@/api/marketAccessRestrictions"
;
import
RelatedEvent
from
"@/views/marketAccessRestrictions/com/RelatedEvent.vue"
;
import
SurveyAffiche
from
"@/views/marketAccessRestrictions/com/SurveyAffiche.vue"
;
const
route
=
useRoute
();
const
leftLoading
=
ref
(
false
);
const
box3Loading
=
ref
(
false
);
const
box4Loading
=
ref
(
false
);
const
baseInfo
=
ref
({});
const
surveyAreaList
=
ref
([]);
const
box2Data
=
ref
([]);
const
box3Data1
=
ref
([]);
const
box3Data2
=
ref
([]);
const
box4Data
=
ref
([]);
const
box3BtnList
=
ref
([
"事件脉络"
,
"报复性措施"
]);
const
box3BtnActive
=
ref
(
"事件脉络"
);
...
...
@@ -213,8 +137,8 @@ const handleClickBox3Btn = btn => {
box3BtnActive
.
value
=
btn
;
};
const
box2Data
=
ref
([]);
const
handleGetSearchBlurb
=
async
()
=>
{
leftLoading
.
value
=
true
;
try
{
const
res
=
await
getSearchBlurb
({
searchId
:
route
.
query
.
searchId
,
...
...
@@ -234,89 +158,43 @@ const handleGetSearchBlurb = async () => {
// 调查公告
if
(
data
.
progress
)
{
box2Data
.
value
=
data
.
progress
.
map
(
p
=>
({
time
:
p
.
PROGRESSDATE
,
content
:
p
.
PROGRESSSTAGE
}));
// 事件脉络
box3Data1
.
value
=
data
.
progress
.
map
(
p
=>
({
time
:
p
.
PROGRESSDATE
,
title
:
p
.
PROGRESSSTAGE
,
content
:
""
}));
}
// 报复性措施
if
(
data
.
SORTMEASURE
)
{
box3Data2
.
value
=
[
{
title
:
"报复性措施"
,
data
:
[{
content
:
data
.
SORTMEASURE
}]
}
];
box2Data
.
value
=
data
.
progress
.
map
(
p
=>
({
time
:
p
.
PROGRESSDATE
,
content
:
p
.
PROGRESSSTAGE
}));
}
}
}
catch
(
error
)
{
console
.
error
(
"获取调查详情失败"
,
error
);
}
finally
{
leftLoading
.
value
=
false
;
}
};
// 相关事件
const
eventList
=
ref
([]);
const
handleGetRelatedEvents
=
async
()
=>
{
box4Loading
.
value
=
true
;
try
{
const
res
=
await
getRelatedEvents
({
searchId
:
route
.
query
.
searchId
});
if
(
res
.
code
===
200
&&
res
.
data
)
{
box4Data
.
value
=
res
.
data
.
map
(
item
=>
({
title
:
item
.
NAME
,
content
:
item
.
SUMMARY
,
time
:
item
.
DATE
,
tag
:
{
type
:
item
.
TYPE
,
name
:
item
.
TYPE
}
}));
}
if
(
res
.
code
===
200
)
eventList
.
value
=
res
.
data
||
[];
}
catch
(
error
)
{
console
.
error
(
"获取相关事件失败"
,
error
);
}
finally
{
box4Loading
.
value
=
false
;
}
};
// 事件脉络
const
box3Data1
=
ref
([]);
const
handleGetSearchContext
=
async
()
=>
{
box3Loading
.
value
=
true
;
try
{
const
res
=
await
getSearchContext
({
searchId
:
route
.
query
.
searchId
});
if
(
res
.
code
===
200
&&
res
.
data
)
{
console
.
log
(
res
.
data
)
box3Data1
.
value
=
res
.
data
.
map
(
item
=>
({
time
:
item
.
CONTTIME
,
title
:
item
.
CONTNODE
,
content
:
item
.
CONTDESC
}));
}
const
res
=
await
getSearchContext
({
searchId
:
route
.
query
.
searchId
});
console
.
log
(
'事件脉络'
,
res
.
data
)
if
(
res
.
code
===
200
)
box3Data1
.
value
=
res
.
data
;
}
catch
(
error
)
{
console
.
error
(
"获取事件脉络失败"
,
error
);
}
finally
{
box3Loading
.
value
=
false
;
}
}
// 报复性措施
const
box3Data2
=
ref
([]);
const
handleGetSearchMeasures
=
async
()
=>
{
// box3Loading is shared with Context for now if they are called together
// or we can just set it true here as well
box3Loading
.
value
=
true
;
try
{
const
res
=
await
getSearchMeasures
({
searchId
:
route
.
query
.
searchId
});
const
res
=
await
getSearchMeasures
({
searchId
:
route
.
query
.
searchId
});
if
(
res
.
code
===
200
&&
res
.
data
)
{
box3Data2
.
value
=
res
.
data
.
map
(
item
=>
({
title
:
item
.
TITLE
,
...
...
@@ -325,8 +203,6 @@ const handleGetSearchMeasures = async () => {
}
}
catch
(
error
)
{
console
.
error
(
"获取报复性措施失败"
,
error
);
}
finally
{
box3Loading
.
value
=
false
;
}
};
onMounted
(()
=>
{
...
...
@@ -342,88 +218,24 @@ onMounted(() => {
width
:
1600px
;
margin
:
20px
auto
;
display
:
flex
;
.box-header
{
height
:
56px
;
display
:
flex
;
position
:
relative
;
.header-left
{
margin-top
:
20px
;
width
:
8px
;
height
:
16px
;
border-radius
:
0
4px
4px
0
;
background
:
var
(
--
color-main-active
);
}
.title
{
margin-left
:
14px
;
margin-top
:
16px
;
height
:
24px
;
line-height
:
24px
;
color
:
var
(
--
color-main-active
);
font-family
:
Microsoft
YaHei
;
font-size
:
18px
;
font-weight
:
700
;
}
.btn-box
{
position
:
absolute
;
top
:
17px
;
left
:
36px
;
.left
{
width
:
520px
;
display
:
flex
;
gap
:
20px
;
height
:
26px
;
.btn
{
height
:
26px
;
padding
:
0
8px
;
box-sizing
:
border-box
;
border
:
1px
solid
rgba
(
230
,
231
,
232
,
1
);
border-radius
:
4px
;
background
:
rgba
(
255
,
255
,
255
,
1
);
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
Microsoft
YaHei
;
font-style
:
Regular
;
font-size
:
18px
;
font-weight
:
400
;
line-height
:
24px
;
letter-spacing
:
0px
;
text-align
:
left
;
cursor
:
pointer
;
}
.btnActive
{
color
:
var
(
--
color-main-active
);
border
:
1px
solid
var
(
--
color-main-active
);
font-weight
:
bold
;
background
:
rgba
(
231
,
243
,
255
,
1
);
}
flex-direction
:
column
;
gap
:
16px
;
}
.header-right
{
position
:
absolute
;
top
:
14px
;
right
:
12px
;
.right
{
width
:
20px
;
flex
:
auto
;
display
:
flex
;
justify-content
:
flex-end
;
gap
:
4px
;
.icon
{
width
:
28px
;
height
:
28px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
}
flex-direction
:
column
;
gap
:
16px
;
margin-left
:
16px
;
}
.left
{
width
:
520px
;
margin-bottom
:
20px
;
.box1
{
margin-top
:
16px
;
width
:
520px
;
height
:
561px
;
border-radius
:
10px
;
box-shadow
:
0px
0px
15px
0px
rgba
(
60
,
87
,
126
,
0
.2
);
background
:
rgba
(
255
,
255
,
255
,
1
);
.box1-main
{
margin-top
:
6px
;
margin-left
:
22px
;
}
.box1-main
{
padding
:
0
22px
;
.box1-item
{
display
:
flex
;
margin-bottom
:
16px
;
...
...
@@ -470,33 +282,9 @@ onMounted(() => {
}
}
.box1-item-right2
{
margin-top
:
2px
;
height
:
24px
;
display
:
flex
;
flex-wrap
:
wrap
;
gap
:
8px
;
.tag
{
height
:
24px
;
padding
:
0
8px
;
box-sizing
:
border-box
;
border-radius
:
4px
;
text-align
:
center
;
line-height
:
24px
;
}
.tag1
{
color
:
rgba
(
19
,
168
,
168
,
1
);
border
:
1px
solid
rgba
(
135
,
232
,
222
,
1
);
background
:
rgba
(
230
,
255
,
251
,
1
);
}
.tag2
{
color
:
rgba
(
22
,
119
,
255
,
1
);
border
:
1px
solid
rgba
(
145
,
202
,
255
,
1
);
background
:
rgba
(
230
,
244
,
255
,
1
);
}
.tag3
{
color
:
rgba
(
114
,
46
,
209
,
1
);
border
:
1px
solid
rgba
(
211
,
173
,
247
,
1
);
background
:
rgba
(
249
,
240
,
255
,
1
);
}
}
.box1-item-right3
{
width
:
346px
;
...
...
@@ -512,86 +300,44 @@ onMounted(() => {
width
:
346px
;
}
}
}
}
.box2
{
width
:
520px
;
height
:
815px
;
margin-top
:
16px
;
border-radius
:
10px
;
box-shadow
:
0px
0px
15px
0px
rgba
(
60
,
87
,
126
,
0
.2
);
background
:
rgba
(
255
,
255
,
255
,
1
);
.box2-main
{
height
:
749px
;
border-top
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
.box2-item
{
width
:
483px
;
// height: 108px;
margin
:
0
auto
;
}
.btn-box
{
display
:
flex
;
gap
:
16px
;
padding
:
12px
8px
8px
8px
;
border-bottom
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
.box2-item-left
{
margin-top
:
4px
;
width
:
15px
;
height
:
15px
;
img
{
width
:
100%
;
align-items
:
center
;
height
:
100%
;
}
}
.box2-item-right
{
.time
{
height
:
24px
;
gap
:
20px
;
.btn
{
height
:
26px
;
padding
:
0
8px
;
box-sizing
:
border-box
;
border
:
1px
solid
rgba
(
230
,
231
,
232
,
1
);
border-radius
:
4px
;
background
:
rgba
(
255
,
255
,
255
,
1
);
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
Microsoft
YaHei
;
font-style
:
Bold
;
font-size
:
16px
;
font-weight
:
700
;
line-height
:
24px
;
letter-spacing
:
1px
;
text-align
:
left
;
}
.content
{
width
:
435px
;
// height: 60px;
margin-top
:
4px
;
color
:
rgba
(
95
,
101
,
108
,
1
);
font-family
:
Microsoft
YaHei
;
font-style
:
Regular
;
font-size
:
16
px
;
font-size
:
18
px
;
font-weight
:
400
;
line-height
:
30
px
;
line-height
:
24
px
;
letter-spacing
:
0px
;
text-align
:
justify
;
}
}
}
}
text-align
:
left
;
cursor
:
pointer
;
}
.btnActive
{
color
:
var
(
--
color-main-active
);
border
:
1px
solid
var
(
--
color-main-active
);
font-weight
:
bold
;
background
:
rgba
(
231
,
243
,
255
,
1
);
}
.right
{
width
:
1064px
;
margin-left
:
16px
;
.box3
{
margin-top
:
16px
;
width
:
1064px
;
// height: 410px;
border-radius
:
10px
;
box-shadow
:
0px
0px
15px
0px
rgba
(
60
,
87
,
126
,
0
.2
);
background
:
rgba
(
255
,
255
,
255
,
1
);
.box3-main
{
margin-top
:
8px
;
margin
:
10px
0
;
}
.box3-main
{
border-top
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
padding
:
15px
20px
;
.box3-main1
{
.box3-main1-item
{
// height: 140px;
margin-bottom
:
20px
;
display
:
flex
;
.left
{
width
:
10px
;
.point
{
...
...
@@ -646,7 +392,7 @@ onMounted(() => {
}
.box3-main2
{
.box3-main2-item
{
margin-top
:
16px
;
margin-bottom
:
16px
;
.box3-main2-item-header
{
width
:
1020px
;
height
:
48px
;
...
...
@@ -712,107 +458,6 @@ onMounted(() => {
}
}
}
}
}
.box4
{
margin-top
:
16px
;
margin-bottom
:
35px
;
width
:
1064px
;
// height: 714px;
border-radius
:
10px
;
box-shadow
:
0px
0px
15px
0px
rgba
(
60
,
87
,
126
,
0
.2
);
background
:
rgba
(
255
,
255
,
255
,
1
);
padding-bottom
:
18px
;
.box4-main
{
width
:
1014px
;
margin
:
10px
auto
;
.box4-main-item
{
width
:
1014px
;
padding
:
11px
0
;
display
:
flex
;
border-bottom
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
.item-left
{
width
:
90px
;
display
:
flex
;
.item-left-tag
{
width
:
80px
;
height
:
28px
;
padding
:
0px
8px
;
border-radius
:
20px
;
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
24px
;
letter-spacing
:
0px
;
text-align
:
center
;
padding
:
0
8px
;
}
.tag1
{
color
:
rgba
(
19
,
168
,
168
,
1
);
border
:
1px
solid
rgba
(
135
,
232
,
222
,
1
);
background
:
rgba
(
230
,
255
,
251
,
1
);
}
.tag2
{
color
:
rgba
(
22
,
119
,
255
,
1
);
border
:
1px
solid
rgba
(
145
,
202
,
255
,
1
);
background
:
rgba
(
230
,
244
,
255
,
1
);
}
.tag3
{
color
:
rgba
(
114
,
46
,
209
,
1
);
border
:
1px
solid
rgba
(
211
,
173
,
247
,
1
);
background
:
rgba
(
249
,
240
,
255
,
1
);
}
}
.item-right
{
width
:
924px
;
.item-right-header
{
width
:
924px
;
display
:
flex
;
justify-content
:
space-between
;
.item-right-title
{
width
:
800px
;
height
:
24px
;
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
700
;
line-height
:
24px
;
letter-spacing
:
0px
;
text-align
:
left
;
}
.item-right-time
{
width
:
124px
;
height
:
24px
;
color
:
rgba
(
95
,
101
,
108
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
24px
;
letter-spacing
:
0px
;
text-align
:
left
;
}
}
.item-right-content
{
margin-top
:
4px
;
width
:
928px
;
height
:
30px
;
color
:
rgba
(
95
,
101
,
108
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
30px
;
letter-spacing
:
0px
;
text-align
:
justify
;
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
}
}
}
}
}
}
}
:deep
(
.el-timeline-item
)
{
...
...
src/views/marketAccessRestrictions/singleCaseLayout/overview/337/index.vue
浏览文件 @
8d534f1e
...
...
@@ -30,37 +30,13 @@
<div
class=
"box1-item"
>
<div
class=
"box1-item-left"
>
{{
"调查领域:"
}}
</div>
<div
class=
"box1-item-right1"
>
<div
class=
"tag"
v-for=
"(item, index) in baseInfo.areaData"
:key=
"index"
>
{{
item
}}
</div>
<div
v-if=
"!baseInfo.areaData || !baseInfo.areaData.length"
>
-
</div>
</div>
</div>
<div
class=
"box1-item"
>
<div
class=
"box1-item-left"
>
{{
"案件进展:"
}}
</div>
<div
class=
"box1-item-right2"
>
<div
class=
"box1-item-right2-item"
v-for=
"(item, index) in processList"
:key=
"index"
>
<div
class=
"icon"
>
<img
src=
"./assets/images/icon1.png"
alt=
""
/>
</div>
<div
class=
"time"
>
{{
item
.
time
}}
</div>
<div
class=
"title"
>
{{
item
.
title
}}
</div>
</div>
</div>
</div>
</div>
</AnalysisBox>
<AnalysisBox
title=
"调查公告"
:showAllBtn=
"false"
height=
"auto"
>
<div
class=
"box4-main"
>
<div
v-for=
"(item, index) in afficheList"
:key=
"index"
class=
"box4-item"
>
<div
class=
"item-icon"
>
<img
src=
"@/views/marketAccessRestrictions/singleCaseLayout/assets/images/icon_affiche.png"
alt=
""
>
</div>
<div
class=
"item-right"
>
<div
class=
"item-time"
>
{{
item
.
time
}}
</div>
<div
class=
"item-text"
>
{{
item
.
text
}}
</div>
<AreaTag
v-for=
"(item, num) in baseInfo.areaData"
:key=
"num"
:tagName=
"item"
></AreaTag>
<div
v-if=
"!baseInfo.areaData?.length"
>
-
</div>
</div>
</div>
</div>
</AnalysisBox>
<SurveyAffiche
title=
"调查公告"
:listData=
"processList"
></SurveyAffiche>
</div>
<div
class=
"right"
>
<AnalysisBox
title=
"原告信息"
:showAllBtn=
"false"
height=
"auto"
>
...
...
@@ -99,19 +75,20 @@
<
script
setup
>
import
{
ref
,
onMounted
}
from
"vue"
;
import
{
useRoute
}
from
"vue-router"
;
import
{
getSearchBlurb
}
from
"@/api/marketAccessRestrictions"
;
import
{
getSearchBlurb
,
getRelatedEvents
}
from
"@/api/marketAccessRestrictions"
;
import
AiTips
from
"@/views/marketAccessRestrictions/com/AiTips.vue"
;
import
RelatedEvent
from
"@/views/marketAccessRestrictions/com/RelatedEvent.vue"
;
import
SurveyAffiche
from
"@/views/marketAccessRestrictions/com/SurveyAffiche.vue"
;
const
tips
=
`Pantech是韩国的一家通信设备公司,曾经是手机制造商,但现在可能已转型为专利持有实体。这类公司常被称为"非执业实体"(NPE)或"专利断言实体"(PAE),通过专利授权和诉讼获取收益。这些企业曾经是行业龙头,但因科技和市场形态巨变,加上自身改革步伐缓慢,经营状况每况愈下。卖掉实体业务部门后,留下来的是高达几万件的专利。`
const
route
=
useRoute
();
const
loading
=
ref
(
false
);
const
baseInfo
=
ref
({});
const
processList
=
ref
([]);
const
caseList
=
ref
([]);
// 调查概况
const
processList
=
ref
([]);
const
handleGetSearchBlurb
=
async
()
=>
{
loading
.
value
=
true
;
try
{
...
...
@@ -126,10 +103,7 @@ const handleGetSearchBlurb = async () => {
// 案件进展
if
(
data
.
progress
)
{
processList
.
value
=
data
.
progress
.
map
(
p
=>
({
time
:
p
.
PROGRESSDATE
,
title
:
p
.
PROGRESSSTAGE
}));
processList
.
value
=
data
.
progress
.
map
(
p
=>
({
time
:
p
.
PROGRESSDATE
,
content
:
p
.
PROGRESSSTAGE
}));
}
// 被告信息分组
...
...
@@ -157,51 +131,22 @@ const handleGetSearchBlurb = async () => {
loading
.
value
=
false
;
};
// 调查公告
const
afficheList
=
ref
([
{
time
:
"2025-03-30"
,
text
:
"美国ITC正式对外国制造的半导体器件及其下游产品和组件启动337调查"
},
{
time
:
"2025-03-30"
,
text
:
"美国ITC正式对外国制造的半导体器件及其下游产品和组件启动337调查"
},
{
time
:
"2025-03-30"
,
text
:
"美国ITC正式对外国制造的半导体器件及其下游产品和组件启动337调查"
},
{
time
:
"2025-03-30"
,
text
:
"美国ITC正式对外国制造的半导体器件及其下游产品和组件启动337调查"
},
{
time
:
"2025-03-30"
,
text
:
"美国ITC正式对外国制造的半导体器件及其下游产品和组件启动337调查"
},
]);
// 相关事件
const
eventList
=
ref
([
{
name
:
"某些特定外国制造的半导体器件及其下游产品和组件;委员会最终裁定未违反第337条的通知;调查终止"
,
text
:
"特此通知,2025 年 2 月 18 日,根据 1930 年《关税法》第 337 条(经修订)已代表爱尔兰 Longitude Licensing Ltd.和爱尔"
,
time
:
"2025年4月15日"
},
{
name
:
"某些特定外国制造的半导体器件及其下游产品和组件;委员会最终裁定未违反第337条的通知;调查终止"
,
text
:
"特此通知,2025 年 2 月 18 日,根据 1930 年《关税法》第 337 条(经修订)已代表爱尔兰 Longitude Licensing Ltd.和爱尔"
,
time
:
"2025年4月15日"
},
{
name
:
"某些特定外国制造的半导体器件及其下游产品和组件;委员会最终裁定未违反第337条的通知;调查终止"
,
text
:
"特此通知,2025 年 2 月 18 日,根据 1930 年《关税法》第 337 条(经修订)已代表爱尔兰 Longitude Licensing Ltd.和爱尔"
,
time
:
"2025年4月15日"
},
])
const
eventList
=
ref
([])
const
handleGetRelatedEvents
=
async
()
=>
{
try
{
const
res
=
await
getRelatedEvents
({
searchId
:
route
.
query
.
searchId
});
if
(
res
.
code
===
200
)
eventList
.
value
=
res
.
data
||
[];
}
catch
(
error
)
{
console
.
error
(
"获取相关事件失败"
,
error
);
}
};
onMounted
(()
=>
{
handleGetSearchBlurb
();
handleGetRelatedEvents
()
});
</
script
>
...
...
@@ -346,59 +291,6 @@ onMounted(() => {
display
:
flex
;
flex-wrap
:
wrap
;
gap
:
8px
;
.tag
{
margin-top
:
3px
;
margin-bottom
:
3px
;
height
:
24px
;
box-sizing
:
border-box
;
border
:
1px
solid
rgba
(
135
,
232
,
222
,
1
);
border-radius
:
4px
;
background
:
rgba
(
230
,
255
,
251
,
1
);
line-height
:
24px
;
text-align
:
center
;
padding
:
0
8px
;
color
:
rgba
(
19
,
168
,
168
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
14px
;
font-weight
:
400
;
}
}
.box1-item-right2
{
.box1-item-right2-item
{
width
:
332px
;
height
:
36px
;
display
:
flex
;
.icon
{
width
:
10px
;
height
:
10px
;
margin-left
:
17px
;
margin-top
:
10px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.time
{
height
:
24px
;
margin-left
:
16px
;
margin-top
:
6px
;
color
:
var
(
--
color-main-active
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
700
;
line-height
:
24px
;
}
.title
{
height
:
24px
;
margin-left
:
16px
;
margin-top
:
6px
;
color
:
var
(
--
color-main-active
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
24px
;
}
}
}
}
}
...
...
@@ -513,41 +405,4 @@ onMounted(() => {
}
}
}
.box4-main
{
padding
:
0
16px
16px
;
.box4-item
{
border-top
:
1px
solid
var
(
--
bg-black-5
);
padding
:
6px
;
display
:
flex
;
.item-icon
{
width
:
15px
;
height
:
15px
;
font-size
:
0px
;
margin-right
:
16px
;
margin-top
:
7px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.item-right
{
width
:
20px
;
flex
:
auto
;
font-family
:
Source
Han
Sans
CN
;
font-size
:
16px
;
line-height
:
30px
;
.item-time
{
font-weight
:
bold
;
color
:
var
(
--
text-primary-80-color
);
}
.item-text
{
color
:
var
(
--
text-primary-65-color
);
}
}
}
.box4-item
:last-child
{
border-bottom
:
1px
solid
var
(
--
bg-black-5
);
}
}
</
style
>
src/views/scientificFunding/components/askPage/index.vue
浏览文件 @
8d534f1e
...
...
@@ -23,8 +23,8 @@
</div>
</div>
-->
<NewsList
:newsList=
"leftList"
@
more-click=
"handleToMoreNews"
img=
"newsImage"
title=
"newsTitle"
content=
"newsContent"
from=
"from"
/>
<MessageBubble
:messageList=
"rightList"
@
more
-click=
"handleToSocialDetail"
source=
"orgName"
content=
"remarks"
content=
"newsContent"
from=
"from"
@
item-click=
"item => gotoNewsDetail(item.newsId)"
/>
<MessageBubble
:messageList=
"rightList"
@
person
-click=
"handleToSocialDetail"
source=
"orgName"
content=
"remarks"
name=
"personName"
imageUrl=
"personImage"
>
</MessageBubble>
<!--
<div
class=
"right-box"
>
...
...
@@ -56,6 +56,7 @@
import
NewsList
from
"@/components/base/newsList/index.vue"
;
import
{
ref
,
onMounted
}
from
"vue"
;
import
{
useGotoNewsDetail
}
from
"@/router/modules/news"
;
import
{
getSocialMediaInfo
,
getNews
}
from
"@/api/scientificFunding/overview"
;
...
...
@@ -171,15 +172,19 @@ const handleToMoreNews = () => {
};
// 查看社交媒体详情
const
handleToSocialDetail
=
item
=>
{
const
personId
=
item
?.
personId
||
item
?.
id
;
if
(
!
personId
)
return
;
const
route
=
router
.
resolve
({
path
:
"/characterPage"
,
query
:
{
personId
:
item
.
id
personId
}
});
window
.
open
(
route
.
href
,
"_blank"
);
};
const
gotoNewsDetail
=
useGotoNewsDetail
();
onMounted
(
async
()
=>
{
handleNews
()
handleSocialMediaInfo
()
...
...
src/views/scientificFunding/components/dataNew/assets/icon-black.png
0 → 100644
浏览文件 @
8d534f1e
17.6 KB
src/views/scientificFunding/components/dataNew/index.vue
浏览文件 @
8d534f1e
...
...
@@ -21,23 +21,30 @@
<div
class=
"left-center-main-ul"
>
<ul>
<li>
<img
src=
"./assets/icon-black.png"
alt=
""
class=
"li-img"
/>
<span
class=
"ul-title"
>
投资主体:
</span>
<span
class=
"ul-content"
>
美国国家科学基金会
</span>
</li>
<li>
<img
src=
"./assets/icon-black.png"
alt=
""
class=
"li-img"
/>
<span
class=
"ul-title"
>
发布日期:
</span>
<span
class=
"ul-content"
>
{{
itemData
.
publicationDate
}}
</span>
</li>
<li>
<img
src=
"./assets/icon-black.png"
alt=
""
class=
"li-img"
/>
<span
class=
"ul-title"
>
资助经费:
</span>
<span
class=
"ul-content"
>
{{
itemData
.
amount
}}
</span>
</li>
<li>
<img
src=
"./assets/icon-black.png"
alt=
""
class=
"li-img"
/>
<span
class=
"ul-title"
>
涉及领域:
</span>
<span
class=
"ul-pie cl1"
v-for=
"value in itemData.toOrgNameList"
>
{{
value
}}
</span>
<span
class=
"ul-pie cl1"
>
<AreaTag
v-for=
"(val, idx) in itemData.areaList"
:key=
"idx"
:tagName=
"val"
/>
</span>
</li>
<li>
<img
src=
"./assets/icon-black.png"
alt=
""
class=
"li-img"
/>
<span
class=
"ul-title"
>
资助对象:
</span>
<span
class=
"ul-content"
>
{{
itemData
.
fromOrgNameList
.
join
(
','
)
}}
</span>
</li>
...
...
@@ -97,42 +104,7 @@ import {
import
router
from
"@/router"
;
const
list
=
ref
([
{
id
:
1
,
title
:
"特别重大"
,
content
:
"NSF宣布新的“新兴技术体验式学习”计划资..."
,
time
:
"一天前"
},
{
id
:
2
,
title
:
"一般风险"
,
content
:
"美国NASA公布NIAC计划2025年度第一轮资助"
,
time
:
"一天前"
},
{
id
:
3
,
title
:
"特别重大"
,
content
:
"美国NASA公布“早期创新计划”2026年资助..."
,
time
:
"一天前"
},
{
id
:
4
,
title
:
"重大风险"
,
content
:
'美国NIH冻结多所顶尖大学资金引发广泛争议"'
,
time
:
"一天前"
},
{
id
:
5
,
title
:
"重大风险"
,
content
:
"美国NIH终止哥伦比亚大学研究项目拨款引发..."
,
time
:
"一天前"
},
{
id
:
6
,
title
:
"特别重大"
,
content
:
"美国DARPA资助可调控生物功能微系统技术开发"
,
time
:
"一天前"
}
]);
//// 获取风险信号
...
...
@@ -286,7 +258,7 @@ onMounted(async () => {
height
:
175px
;
.left-center-main-title
{
margin-left
:
19
px
;
margin-left
:
22
px
;
margin-bottom
:
17px
;
font-size
:
20px
;
font-weight
:
700
;
...
...
@@ -305,6 +277,20 @@ onMounted(async () => {
width
:
100%
;
height
:
24px
;
margin-bottom
:
12px
;
display
:
flex
;
.li-img
{
width
:
4px
;
height
:
4px
;
margin-right
:
18px
;
margin-top
:
10px
;
img
{
width
:
100%
;
height
:
100%
;
display
:
block
;
}
}
.ul-title
{
display
:
inline-block
;
...
...
@@ -326,19 +312,14 @@ onMounted(async () => {
}
.ul-pie
{
display
:
inline-block
;
display
:
flex
;
gap
:
8px
;
box-sizing
:
border-box
;
padding
:
2px
8px
;
border
:
1px
solid
;
border-radius
:
4px
;
flex-direction
:
row
;
margin-right
:
8px
;
}
.cl1
{
border-color
:
rgba
(
186
,
224
,
255
,
1
);
background-color
:
rgba
(
230
,
244
,
255
,
1
);
color
:
rgba
(
22
,
119
,
255
,
1
);
}
.cl2
{
border-color
:
rgba
(
255
,
163
,
158
,
1
);
...
...
src/views/scientificFunding/components/dataSub/index.vue
浏览文件 @
8d534f1e
...
...
@@ -5,20 +5,34 @@
<div
class=
"left-title"
>
<img
src=
"./assets/icon01.png"
alt=
""
/>
<div
class=
"tit"
>
资助领域分布情况
</div>
<div
:class=
"radio1 === true ? 'btn-select' : 'btn'"
style=
" right:250px;"
@
click=
"
changeradio1(
)"
>
<div
:class=
"radio1 === true ? 'btn-select' : 'btn'"
style=
" right:250px;"
@
click=
"
setRadio1(true
)"
>
资助经费
</div>
<div
:class=
"radio1 === false ? 'btn-select' : 'btn'"
style=
" right: 150px;"
@
click=
"
changeradio1(
)"
>
<div
:class=
"radio1 === false ? 'btn-select' : 'btn'"
style=
" right: 150px;"
@
click=
"
setRadio1(false
)"
>
资助项目
</div>
<el-select
v-model=
"value1"
placeholder=
"Select"
class=
"select"
style=
" right: 31px;"
>
<el-select
v-model=
"value1"
placeholder=
"Select"
class=
"select"
style=
" right: 31px;"
@
change=
"handleLeft1YearChange"
>
<el-option
v-for=
"item in options1"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</div>
<div
class=
"left-main"
>
<div
class=
"left-main-echarts"
ref=
"leftChartRef"
v-show=
"radio1 === true"
>
资助经费
</div>
<div
class=
"left-main-echarts"
ref=
"leftChartRef1"
v-show=
"radio1 === false"
>
资助项目
</div>
<div
class=
"left-main-echarts"
ref=
"leftChartRef"
v-show=
"radio1 === true"
></div>
<div
class=
"left-main-echarts"
ref=
"leftChartRef1"
v-show=
"radio1 === false"
></div>
<el-empty
v-show=
"!hasLeft1ChartData && !isLeft1Loading"
class=
"datasub-el-empty"
description=
"暂无数据"
:image-size=
"100"
/>
<div
class=
"source"
v-show=
"hasLeft1ChartData"
>
<TipTab
:text=
"'资助领域分布情况,数据来源:美国国会官网'"
/>
</div>
<div
class=
"chart-box"
v-show=
"hasLeft1ChartData"
>
<div
class=
"btn-box"
v-if=
"!isShowAiContentLeft1"
@
mouseenter=
"handleSwitchAiLeft1(true)"
>
<AiButton
/>
</div>
<div
class=
"content-box"
v-else
@
mouseleave=
"handleSwitchAiLeft1(false)"
>
<AiPane
:aiContent=
"aiContentLeft1"
/>
</div>
</div>
</div>
</div>
<div
class=
"left"
>
...
...
@@ -31,6 +45,18 @@
</div>
<div
class=
"left-main1"
>
<div
class=
"left-sankey-echarts"
ref=
"leftSankeyRef"
></div>
<el-empty
v-show=
"!hasLeft2ChartData"
class=
"datasub-el-empty"
description=
"暂无数据"
:image-size=
"100"
/>
<div
class=
"source"
v-show=
"hasLeft2ChartData"
>
<TipTab
:text=
"'机构资助领域情况,数据来源:美国国会官网'"
/>
</div>
<div
class=
"chart-box"
v-show=
"hasLeft2ChartData"
>
<div
class=
"btn-box"
v-if=
"!isShowAiContentLeft2"
@
mouseenter=
"handleSwitchAiLeft2(true)"
>
<AiButton
/>
</div>
<div
class=
"content-box"
v-else
@
mouseleave=
"handleSwitchAiLeft2(false)"
>
<AiPane
:aiContent=
"aiContentLeft2"
/>
</div>
</div>
</div>
</div>
</div>
...
...
@@ -39,33 +65,58 @@
<div
class=
"right-title"
>
<img
src=
"./assets/icon02.png"
alt=
""
/>
<div
class=
"tit"
>
资助经费变化情况
</div>
<div
:class=
"radio2 === true ? 'btn-select' : 'btn'"
style=
" right:250px;"
@
click=
"
changeradio2(
)"
>
<div
:class=
"radio2 === true ? 'btn-select' : 'btn'"
style=
" right:250px;"
@
click=
"
setRadio2(true
)"
>
资助经费
</div>
<div
:class=
"radio2 === false ? 'btn-select' : 'btn'"
style=
" right: 150px;"
@
click=
"
changeradio2(
)"
>
<div
:class=
"radio2 === false ? 'btn-select' : 'btn'"
style=
" right: 150px;"
@
click=
"
setRadio2(false
)"
>
资助项目
</div>
<el-select
v-model=
"value"
placeholder=
"Select"
class=
"select"
>
<el-select
v-model=
"value"
placeholder=
"Select"
class=
"select"
@
change=
"handleRight1RangeChange"
>
<el-option
v-for=
"item in options"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</div>
<div
class=
"right-main"
>
<div
class=
"right-main-echarts"
ref=
"rightChartRef"
v-show=
"radio2 === true"
></div>
<div
class=
"right-main-echarts"
ref=
"rightChartRef1"
v-show=
"radio2 === false"
></div>
<div
class=
"right-main-tit"
>
亿美元
</div>
<div
class=
"right-main-tit"
v-show=
"hasRight1ChartData"
>
亿美元
</div>
<el-empty
v-show=
"!hasRight1ChartData && !isRight1Loading"
class=
"datasub-el-empty"
description=
"暂无数据"
:image-size=
"100"
/>
<div
class=
"source"
v-show=
"hasRight1ChartData"
>
<TipTab
:text=
"'资助经费变化情况,数据来源:美国国会官网'"
/>
</div>
<div
class=
"chart-box"
v-show=
"hasRight1ChartData"
>
<div
class=
"btn-box"
v-if=
"!isShowAiContentRight1"
@
mouseenter=
"handleSwitchAiRight1(true)"
>
<AiButton
/>
</div>
<div
class=
"content-box"
v-else
@
mouseleave=
"handleSwitchAiRight1(false)"
>
<AiPane
:aiContent=
"aiContentRight1"
/>
</div>
</div>
</div>
</div>
<div
class=
"right"
>
<div
class=
"right-title"
>
<img
src=
"./assets/icon04.png"
alt=
""
/>
<div
class=
"tit"
>
项目资助强度分布
</div>
<el-select
v-model=
"value3"
placeholder=
"Select"
class=
"select"
>
<el-select
v-model=
"value3"
placeholder=
"Select"
class=
"select"
@
change=
"handleRight2YearChange"
>
<el-option
v-for=
"item in options1"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
</div>
<div
class=
"right-main1"
>
<div
class=
"right-boxplot-echarts"
ref=
"boxplotChartRef"
></div>
<div
class=
"right-main1-tit"
>
单位:亿美元
</div>
<div
class=
"right-main1-tit"
v-show=
"hasRight2ChartData"
>
单位:亿美元
</div>
<el-empty
v-show=
"!hasRight2ChartData"
class=
"datasub-el-empty"
description=
"暂无数据"
:image-size=
"100"
/>
<div
class=
"source"
v-show=
"hasRight2ChartData"
>
<TipTab
:text=
"'项目资助强度分布,数据来源:美国国会官网'"
/>
</div>
<div
class=
"chart-box"
v-show=
"hasRight2ChartData"
>
<div
class=
"btn-box"
v-if=
"!isShowAiContentRight2"
@
mouseenter=
"handleSwitchAiRight2(true)"
>
<AiButton
/>
</div>
<div
class=
"content-box"
v-else
@
mouseleave=
"handleSwitchAiRight2(false)"
>
<AiPane
:aiContent=
"aiContentRight2"
/>
</div>
</div>
</div>
</div>
</div>
...
...
@@ -73,13 +124,31 @@
</
template
>
<
script
setup
>
import
{
ref
,
onMounted
,
onBeforeUnmount
,
nextTick
}
from
"vue"
;
import
{
ref
,
onMounted
,
onBeforeUnmount
,
nextTick
,
computed
}
from
"vue"
;
import
{
getChartAnalysis
}
from
"@/api/aiAnalysis"
;
import
AiButton
from
"@/components/base/Ai/AiButton/index.vue"
;
import
AiPane
from
"@/components/base/Ai/AiPane/index.vue"
;
import
TipTab
from
"@/views/thinkTank/TipTab/index.vue"
;
import
{
findFundField
,
findCountryProjectAreaList
,
getCountryFundingChange
,
getCountryFundProjectChange
,
getOrgFundsArea
,
getOrgFundStrength
}
from
"@/api/scientificFunding/overview"
;
import
*
as
echarts
from
"echarts"
;
const
isNonEmptyArray
=
(
v
)
=>
Array
.
isArray
(
v
)
&&
v
.
length
>
0
;
// 兼容后端多种返回结构:[] / {data:[]} / {content:[]} 等
const
extractArrayData
=
(
res
)
=>
{
const
d
=
res
?.
data
;
if
(
Array
.
isArray
(
d
))
return
d
;
if
(
Array
.
isArray
(
d
?.
data
))
return
d
.
data
;
if
(
Array
.
isArray
(
d
?.
content
))
return
d
.
content
;
if
(
Array
.
isArray
(
d
?.
list
))
return
d
.
list
;
return
[];
};
const
isSuccessCode
=
(
res
)
=>
Number
(
res
?.
code
)
===
200
;
const
value
=
ref
(
10
);
...
...
@@ -107,54 +176,153 @@ const options1 = [
label
:
"2024年"
}
];
//获取当前时间x年前的日期
function
getDateYearsAgo
(
years
)
{
// 获取当前日期
const
currentDate
=
new
Date
();
// 计算指定年数之前的日期
const
pastDate
=
new
Date
(
currentDate
.
getFullYear
()
-
years
,
currentDate
.
getMonth
(),
currentDate
.
getDate
());
// 格式化日期为 "YYYY-MM-DD" 的形式
const
year
=
pastDate
.
getFullYear
();
const
month
=
String
(
pastDate
.
getMonth
()
+
1
).
padStart
(
2
,
"0"
);
// 月份从0开始,需要加1
const
day
=
String
(
pastDate
.
getDate
()).
padStart
(
2
,
"0"
);
return
`
${
year
}
-
${
month
}
-
${
day
}
`
;
}
const
normalizeYearParam
=
(
val
)
=>
{
const
y
=
Number
(
val
);
return
Number
.
isFinite
(
y
)
?
y
:
val
;
};
/** 资助经费变化情况:固定时间窗起点 */
const
buildStartDateByRange
=
(
rangeYears
)
=>
{
const
n
=
Number
(
rangeYears
);
if
(
n
===
10
)
return
"2015-01-01"
;
if
(
n
===
5
)
return
"2020-01-01"
;
// 兜底:保持原逻辑的“年初”
const
y
=
new
Date
().
getFullYear
()
-
(
Number
.
isFinite
(
n
)
?
n
:
0
);
return
`
${
y
}
-01-01`
;
};
const
radio1
=
ref
(
true
)
const
changeradio1
=
()
=>
{
radio1
.
value
=
!
radio1
.
value
}
const
setRadio1
=
(
val
)
=>
{
if
(
radio1
.
value
===
val
)
return
;
radio1
.
value
=
val
;
// 切换模式:先清空当前模式数据与图表,再按当前年份重新拉数
if
(
val
)
{
left1RawFund
.
value
=
[];
if
(
leftChart
)
{
leftChart
.
dispose
();
leftChart
=
null
;
}
}
else
{
left1RawProject
.
value
=
[];
if
(
leftChart1
)
{
leftChart1
.
dispose
();
leftChart1
=
null
;
}
}
handleLeft1YearChange
();
// 切换显示后强制当前图表 resize,确保 canvas 尺寸稳定
nextTick
(()
=>
{
if
(
radio1
.
value
)
{
if
(
leftChart
)
leftChart
.
resize
();
}
else
{
if
(
leftChart1
)
leftChart1
.
resize
();
}
});
};
const
value1
=
ref
(
2025
);
const
leftChartRef
=
ref
(
null
);
const
leftChartRef1
=
ref
(
null
);
const
left1RawFund
=
ref
([]);
const
left1RawProject
=
ref
([]);
const
left1FundLoading
=
ref
(
false
);
const
left1ProjLoading
=
ref
(
false
);
const
hasLeft1ChartData
=
computed
(()
=>
{
return
radio1
.
value
?
isNonEmptyArray
(
left1RawFund
.
value
)
:
isNonEmptyArray
(
left1RawProject
.
value
);
});
const
isLeft1Loading
=
computed
(()
=>
(
radio1
.
value
?
left1FundLoading
.
value
:
left1ProjLoading
.
value
));
let
left1FundReqSeq
=
0
;
let
left1ProjReqSeq
=
0
;
const
handleLeft1YearChange
=
()
=>
{
// 根据当前“资助经费/资助项目”切换状态请求对应接口
if
(
radio1
.
value
)
{
handleGetFundField
();
}
else
{
handleFindCountryProjectAreaList
();
}
};
// 资助体系v2.0:资助领域分布情况:资助经费
const
handleGetFundField
=
async
()
=>
{
const
seq
=
++
left1FundReqSeq
;
left1FundLoading
.
value
=
true
;
try
{
let
params
=
{
year
:
value1
.
value
year
:
normalizeYearParam
(
value1
.
value
)
}
const
res
=
await
findFundField
(
params
);
if
(
seq
!==
left1FundReqSeq
)
return
;
console
.
log
(
"资助领域分布情况"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
initLeftDonut
(
res
.
data
,
true
)
if
(
isSuccessCode
(
res
))
{
const
list
=
extractArrayData
(
res
);
left1RawFund
.
value
=
list
;
if
(
list
.
length
)
{
await
nextTick
();
initLeftDonut
(
list
,
true
)
}
else
if
(
leftChart
)
{
leftChart
.
dispose
();
leftChart
=
null
;
}
}
else
{
left1RawFund
.
value
=
[];
if
(
leftChart
)
{
leftChart
.
dispose
();
leftChart
=
null
;
}
}
}
catch
(
error
)
{
if
(
seq
!==
left1FundReqSeq
)
return
;
console
.
error
(
"获取资助领域分布情况error"
,
error
);
left1RawFund
.
value
=
[];
if
(
leftChart
)
{
leftChart
.
dispose
();
leftChart
=
null
;
}
}
finally
{
if
(
seq
===
left1FundReqSeq
)
{
left1FundLoading
.
value
=
false
;
}
}
};
//资助体系v2.0:资助领域分布情况:资助项目
const
handleFindCountryProjectAreaList
=
async
()
=>
{
const
seq
=
++
left1ProjReqSeq
;
left1ProjLoading
.
value
=
true
;
try
{
let
params
=
{
year
:
value1
.
value
year
:
normalizeYearParam
(
value1
.
value
)
}
const
res
=
await
findCountryProjectAreaList
(
params
);
if
(
seq
!==
left1ProjReqSeq
)
return
;
console
.
log
(
"资助领域分布情况"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
initLeftDonut
(
res
.
data
,
false
)
if
(
isSuccessCode
(
res
))
{
const
list
=
extractArrayData
(
res
);
left1RawProject
.
value
=
list
;
if
(
list
.
length
)
{
await
nextTick
();
initLeftDonut
(
list
,
false
)
}
else
if
(
leftChart1
)
{
leftChart1
.
dispose
();
leftChart1
=
null
;
}
}
else
{
left1RawProject
.
value
=
[];
if
(
leftChart1
)
{
leftChart1
.
dispose
();
leftChart1
=
null
;
}
}
}
catch
(
error
)
{
if
(
seq
!==
left1ProjReqSeq
)
return
;
console
.
error
(
"获取资助领域分布情况error"
,
error
);
left1RawProject
.
value
=
[];
if
(
leftChart1
)
{
leftChart1
.
dispose
();
leftChart1
=
null
;
}
}
finally
{
if
(
seq
===
left1ProjReqSeq
)
{
left1ProjLoading
.
value
=
false
;
}
}
};
// 资助领域分布情况
...
...
@@ -208,68 +376,179 @@ const initLeftDonut = (rawData, show) => {
};
if
(
show
==
true
)
{
if
(
leftChart
)
leftChart
.
dispose
();
leftChart
=
echarts
.
init
(
leftChartRef
.
value
);
leftChart
.
setOption
(
option
);
nextTick
(()
=>
leftChart
&&
leftChart
.
resize
());
}
else
{
if
(
leftChart1
)
leftChart1
.
dispose
();
leftChart1
=
echarts
.
init
(
leftChartRef1
.
value
);
leftChart1
.
setOption
(
option
);
nextTick
(()
=>
leftChart1
&&
leftChart1
.
resize
());
}
};
const
rightChartRef
=
ref
(
null
);
const
rightChartRef1
=
ref
(
null
);
const
right1RawFund
=
ref
([]);
const
right1RawProject
=
ref
([]);
const
right1FundLoading
=
ref
(
false
);
const
right1ProjLoading
=
ref
(
false
);
const
hasRight1ChartData
=
computed
(()
=>
{
return
radio2
.
value
?
isNonEmptyArray
(
right1RawFund
.
value
)
:
isNonEmptyArray
(
right1RawProject
.
value
);
});
const
isRight1Loading
=
computed
(()
=>
(
radio2
.
value
?
right1FundLoading
.
value
:
right1ProjLoading
.
value
));
const
radio2
=
ref
(
true
)
const
changeradio2
=
()
=>
{
radio2
.
value
?
handlegetCountryFundingChange
()
:
handlegetCountryFundProjectChange
()
radio2
.
value
=
!
radio2
.
value
}
const
handleRight1RangeChange
=
()
=>
{
// 根据当前“资助经费/资助项目”切换状态请求对应接口
if
(
radio2
.
value
)
{
handlegetCountryFundingChange
();
}
else
{
handlegetCountryFundProjectChange
();
}
};
const
setRadio2
=
(
val
)
=>
{
if
(
radio2
.
value
===
val
)
return
;
radio2
.
value
=
val
;
// 切换模式:先清空当前模式数据与图表,再按当前时间窗重新拉数
if
(
val
)
{
right1RawFund
.
value
=
[];
if
(
rightChart
)
{
rightChart
.
dispose
();
rightChart
=
null
;
}
}
else
{
right1RawProject
.
value
=
[];
if
(
rightChart1
)
{
rightChart1
.
dispose
();
rightChart1
=
null
;
}
}
handleRight1RangeChange
();
// 切换显示后强制当前图表 resize,确保 canvas 尺寸稳定
nextTick
(()
=>
{
if
(
radio2
.
value
)
{
if
(
rightChart
)
rightChart
.
resize
();
}
else
{
if
(
rightChart1
)
rightChart1
.
resize
();
}
});
};
// 资助体系v2.0:资助经费变化情况:资助经费
const
handlegetCountryFundingChange
=
async
()
=>
{
try
{
right1FundLoading
.
value
=
true
;
let
params
=
{
startDate
:
getDateYearsAgo
(
value
.
value
)
startDate
:
buildStartDateByRange
(
value
.
value
)
}
const
res
=
await
getCountryFundingChange
(
params
);
console
.
log
(
"资助经费变化情况"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
initRightLine
(
res
.
data
,
true
)
if
(
isSuccessCode
(
res
))
{
const
list
=
extractArrayData
(
res
);
right1RawFund
.
value
=
list
;
if
(
list
.
length
)
{
await
nextTick
();
initRightLine
(
list
,
true
)
}
else
if
(
rightChart
)
{
rightChart
.
dispose
();
rightChart
=
null
;
}
}
else
{
right1RawFund
.
value
=
[];
if
(
rightChart
)
{
rightChart
.
dispose
();
rightChart
=
null
;
}
}
}
catch
(
error
)
{
console
.
error
(
"获取资助经费变化情况error"
,
error
);
right1RawFund
.
value
=
[];
if
(
rightChart
)
{
rightChart
.
dispose
();
rightChart
=
null
;
}
}
finally
{
right1FundLoading
.
value
=
false
;
}
};
//资助体系v2.0:资助经费变化情况:资助项目
const
handlegetCountryFundProjectChange
=
async
()
=>
{
try
{
right1ProjLoading
.
value
=
true
;
let
params
=
{
startDate
:
getDateYearsAgo
(
value
.
value
)
startDate
:
buildStartDateByRange
(
value
.
value
)
}
const
res
=
await
getCountryFundProjectChange
(
params
);
console
.
log
(
"资助项目变化情况"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
initRightLine
(
res
.
data
)
if
(
isSuccessCode
(
res
))
{
const
list
=
extractArrayData
(
res
);
right1RawProject
.
value
=
list
;
if
(
list
.
length
)
{
await
nextTick
();
initRightLine
(
list
)
}
else
if
(
rightChart1
)
{
rightChart1
.
dispose
();
rightChart1
=
null
;
}
}
else
{
right1RawProject
.
value
=
[];
if
(
rightChart1
)
{
rightChart1
.
dispose
();
rightChart1
=
null
;
}
}
}
catch
(
error
)
{
console
.
error
(
"获取资助项目变化情况error"
,
error
);
right1RawProject
.
value
=
[];
if
(
rightChart1
)
{
rightChart1
.
dispose
();
rightChart1
=
null
;
}
}
finally
{
right1ProjLoading
.
value
=
false
;
}
};
//项目资助强度分布
const
value3
=
ref
(
2025
);
const
boxplotChartRef
=
ref
(
null
);
const
right2RawStrength
=
ref
([]);
const
hasRight2ChartData
=
computed
(()
=>
isNonEmptyArray
(
right2RawStrength
.
value
));
const
handleRight2YearChange
=
()
=>
{
handlegetOrgFundStrength
();
};
const
handlegetOrgFundStrength
=
async
()
=>
{
try
{
let
params
=
{
year
:
value3
.
value
year
:
normalizeYearParam
(
value3
.
value
)
}
const
res
=
await
getOrgFundStrength
(
params
);
console
.
log
(
"项目资助强度分布"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
initBoxPlot
(
res
.
data
)
if
(
isSuccessCode
(
res
))
{
const
list
=
extractArrayData
(
res
);
right2RawStrength
.
value
=
list
;
if
(
list
.
length
)
{
await
nextTick
();
initBoxPlot
(
list
)
}
else
if
(
boxplotChart
)
{
boxplotChart
.
dispose
();
boxplotChart
=
null
;
}
}
else
{
right2RawStrength
.
value
=
[];
if
(
boxplotChart
)
{
boxplotChart
.
dispose
();
boxplotChart
=
null
;
}
}
}
catch
(
error
)
{
console
.
error
(
"获取项目资助强度分布error"
,
error
);
right2RawStrength
.
value
=
[];
if
(
boxplotChart
)
{
boxplotChart
.
dispose
();
boxplotChart
=
null
;
}
}
};
//项目资助强度分布
...
...
@@ -420,11 +699,152 @@ const initBoxPlot = (data) => {
let
leftChart
;
let
leftChart1
;
//
let rightChart;
//
let rightChart1;
let
rightChart
;
let
rightChart1
;
let
leftSankey
;
let
boxplotChart
;
// ------- AI 解读(刷新后默认展开,行为对齐智库概览) -------
const
isShowAiContentLeft1
=
ref
(
true
);
const
isShowAiContentLeft2
=
ref
(
true
);
const
isShowAiContentRight1
=
ref
(
true
);
const
isShowAiContentRight2
=
ref
(
true
);
const
aiContentLeft1
=
ref
(
""
);
const
aiContentLeft2
=
ref
(
""
);
const
aiContentRight1
=
ref
(
""
);
const
aiContentRight2
=
ref
(
""
);
const
isAiLoadingLeft1
=
ref
(
false
);
const
isAiLoadingLeft2
=
ref
(
false
);
const
isAiLoadingRight1
=
ref
(
false
);
const
isAiLoadingRight2
=
ref
(
false
);
const
appendAiInterpretationChunk
=
(
targetRef
,
chunk
,
loadingText
=
"解读生成中…"
)
=>
{
if
(
!
chunk
)
return
;
const
current
=
String
(
targetRef
.
value
||
""
);
const
base
=
current
===
loadingText
?
""
:
current
;
targetRef
.
value
=
base
+
String
(
chunk
);
};
const
getInterpretationTextFromChartResponse
=
(
res
)
=>
{
const
list
=
res
?.
data
;
const
first
=
Array
.
isArray
(
list
)
?
list
[
0
]
:
null
;
return
(
first
?.[
"解读"
]
||
first
?.[
"interpretation"
]
||
first
?.[
"analysis"
]
||
first
?.[
"content"
]
||
""
);
};
const
fetchChartInterpretationOnce
=
async
(
payload
,
targetRef
,
loadingRef
)
=>
{
if
(
loadingRef
.
value
)
return
;
const
hasValidContent
=
targetRef
.
value
&&
targetRef
.
value
!==
"解读生成中…"
&&
targetRef
.
value
!==
"解读加载失败"
&&
targetRef
.
value
!==
"暂无图表数据"
;
if
(
hasValidContent
)
return
;
loadingRef
.
value
=
true
;
targetRef
.
value
=
"解读生成中…"
;
try
{
const
res
=
await
getChartAnalysis
(
{
text
:
JSON
.
stringify
(
payload
)
},
{
onChunk
:
(
chunk
)
=>
appendAiInterpretationChunk
(
targetRef
,
chunk
)
}
);
const
text
=
getInterpretationTextFromChartResponse
(
res
);
targetRef
.
value
=
text
||
targetRef
.
value
||
"未返回有效解读内容"
;
}
catch
(
e
)
{
console
.
error
(
"图表解读请求失败"
,
e
);
targetRef
.
value
=
"解读加载失败"
;
}
finally
{
loadingRef
.
value
=
false
;
}
};
const
buildPayloadLeft1
=
()
=>
{
const
raw
=
radio1
.
value
?
left1RawFund
.
value
:
left1RawProject
.
value
;
if
(
!
Array
.
isArray
(
raw
)
||
raw
.
length
===
0
)
return
null
;
return
{
type
:
"分布图"
,
name
:
radio1
.
value
?
"资助领域分布情况-资助经费"
:
"资助领域分布情况-资助项目"
,
data
:
raw
};
};
const
buildPayloadLeft2
=
()
=>
{
const
raw
=
left2RawSankey
.
value
;
if
(
!
Array
.
isArray
(
raw
)
||
raw
.
length
===
0
)
return
null
;
return
{
type
:
"桑基图"
,
name
:
"机构资助领域情况"
,
data
:
raw
};
};
const
buildPayloadRight1
=
()
=>
{
const
raw
=
radio2
.
value
?
right1RawFund
.
value
:
right1RawProject
.
value
;
if
(
!
Array
.
isArray
(
raw
)
||
raw
.
length
===
0
)
return
null
;
return
{
type
:
"折线图"
,
name
:
radio2
.
value
?
"资助经费变化情况-资助经费"
:
"资助经费变化情况-资助项目"
,
data
:
raw
};
};
const
buildPayloadRight2
=
()
=>
{
const
raw
=
right2RawStrength
.
value
;
if
(
!
Array
.
isArray
(
raw
)
||
raw
.
length
===
0
)
return
null
;
return
{
type
:
"箱线图"
,
name
:
"项目资助强度分布"
,
data
:
raw
};
};
const
handleSwitchAiLeft1
=
async
(
val
)
=>
{
isShowAiContentLeft1
.
value
=
val
;
if
(
!
val
)
return
;
const
payload
=
buildPayloadLeft1
();
if
(
!
payload
)
{
aiContentLeft1
.
value
=
"暂无图表数据"
;
return
;
}
await
fetchChartInterpretationOnce
(
payload
,
aiContentLeft1
,
isAiLoadingLeft1
);
};
const
handleSwitchAiLeft2
=
async
(
val
)
=>
{
isShowAiContentLeft2
.
value
=
val
;
if
(
!
val
)
return
;
const
payload
=
buildPayloadLeft2
();
if
(
!
payload
)
{
aiContentLeft2
.
value
=
"暂无图表数据"
;
return
;
}
await
fetchChartInterpretationOnce
(
payload
,
aiContentLeft2
,
isAiLoadingLeft2
);
};
const
handleSwitchAiRight1
=
async
(
val
)
=>
{
isShowAiContentRight1
.
value
=
val
;
if
(
!
val
)
return
;
const
payload
=
buildPayloadRight1
();
if
(
!
payload
)
{
aiContentRight1
.
value
=
"暂无图表数据"
;
return
;
}
await
fetchChartInterpretationOnce
(
payload
,
aiContentRight1
,
isAiLoadingRight1
);
};
const
handleSwitchAiRight2
=
async
(
val
)
=>
{
isShowAiContentRight2
.
value
=
val
;
if
(
!
val
)
return
;
const
payload
=
buildPayloadRight2
();
if
(
!
payload
)
{
aiContentRight2
.
value
=
"暂无图表数据"
;
return
;
}
await
fetchChartInterpretationOnce
(
payload
,
aiContentRight2
,
isAiLoadingRight2
);
};
//资助经费变化情况
...
...
@@ -463,8 +883,10 @@ const initRightLine = (data, show) => {
name
:
orgName
,
type
:
"line"
,
data
:
values
,
symbol
:
"none"
,
showSymbol
:
false
,
smooth
:
true
,
symbol
:
"emptyCircle"
,
showSymbol
:
true
,
symbolSize
:
6
,
endLabel
:
{
show
:
true
,
formatter
:
orgName
,
// 只显示 orgName
...
...
@@ -522,30 +944,55 @@ const initRightLine = (data, show) => {
};
if
(
show
==
true
)
{
let
rightChart
=
echarts
.
init
(
rightChartRef
.
value
);
if
(
rightChart
)
rightChart
.
dispose
();
rightChart
=
echarts
.
init
(
rightChartRef
.
value
);
rightChart
.
setOption
(
option
);
nextTick
(()
=>
rightChart
&&
rightChart
.
resize
());
}
else
{
let
rightChart1
=
echarts
.
init
(
rightChartRef1
.
value
);
if
(
rightChart1
)
rightChart1
.
dispose
();
rightChart1
=
echarts
.
init
(
rightChartRef1
.
value
);
rightChart1
.
setOption
(
option
);
nextTick
(()
=>
rightChart1
&&
rightChart1
.
resize
());
}
};
const
leftSankeyRef
=
ref
(
null
);
const
value2
=
ref
(
2025
);
const
left2RawSankey
=
ref
([]);
const
hasLeft2ChartData
=
computed
(()
=>
isNonEmptyArray
(
left2RawSankey
.
value
));
// 机构资助领域情况
const
handleGetOrgFundsArea
=
async
()
=>
{
try
{
let
params
=
{
year
:
value2
.
value
year
:
normalizeYearParam
(
value2
.
value
)
}
const
res
=
await
getOrgFundsArea
(
params
);
console
.
log
(
"机构资助领域情况"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
initLeftSankey
(
res
.
data
)
if
(
isSuccessCode
(
res
))
{
const
list
=
extractArrayData
(
res
);
left2RawSankey
.
value
=
list
;
if
(
list
.
length
)
{
await
nextTick
();
initLeftSankey
(
list
)
}
else
if
(
leftSankey
)
{
leftSankey
.
dispose
();
leftSankey
=
null
;
}
}
else
{
left2RawSankey
.
value
=
[];
if
(
leftSankey
)
{
leftSankey
.
dispose
();
leftSankey
=
null
;
}
}
}
catch
(
error
)
{
console
.
error
(
"获取机构资助领域情况error"
,
error
);
left2RawSankey
.
value
=
[];
if
(
leftSankey
)
{
leftSankey
.
dispose
();
leftSankey
=
null
;
}
}
};
//机构资助领域情况
...
...
@@ -638,6 +1085,7 @@ const initLeftSankey = (data) => {
};
leftSankey
.
setOption
(
option
);
nextTick
(()
=>
leftSankey
&&
leftSankey
.
resize
());
};
...
...
@@ -650,13 +1098,21 @@ const initLeftSankey = (data) => {
// };
onMounted
(()
=>
{
handleGetFundField
()
handleFindCountryProjectAreaList
()
handlegetCountryFundingChange
()
handlegetCountryFundProjectChange
()
handleGetOrgFundsArea
()
handlegetOrgFundStrength
()
// 刷新后 AiPane 默认展开:先给出“解读生成中…”占位,再在数据到位后触发解读请求
aiContentLeft1
.
value
=
"解读生成中…"
;
aiContentLeft2
.
value
=
"解读生成中…"
;
aiContentRight1
.
value
=
"解读生成中…"
;
aiContentRight2
.
value
=
"解读生成中…"
;
// 先拉数据;每块数据到位后立即触发一次 AI 解读(不必等其它块完成)
void
handleGetFundField
().
then
(()
=>
handleSwitchAiLeft1
(
true
));
void
handleFindCountryProjectAreaList
();
void
handlegetCountryFundingChange
().
then
(()
=>
handleSwitchAiRight1
(
true
));
void
handlegetCountryFundProjectChange
();
void
handleGetOrgFundsArea
().
then
(()
=>
handleSwitchAiLeft2
(
true
));
void
handlegetOrgFundStrength
().
then
(()
=>
handleSwitchAiRight2
(
true
));
});
// onBeforeUnmount(() => {
// window.removeEventListener("resize", handleResize);
...
...
@@ -746,18 +1202,24 @@ onMounted(() => {
.left-main
{
width
:
792px
;
height
:
412px
;
padding
:
52px
60px
78px
61px
;
box-sizing
:
border-box
;
/* 对齐智库概览-数据总览内边距 */
padding
:
24px
24px
65px
24px
;
position
:
relative
;
.left-main-echarts
{
width
:
780px
;
height
:
350px
;
width
:
100%
;
height
:
100%
;
}
}
.left-main1
{
width
:
792px
;
height
:
412px
;
padding
:
30px
30px
30px
30px
;
box-sizing
:
border-box
;
/* 对齐智库概览-数据总览内边距 */
padding
:
24px
24px
65px
24px
;
position
:
relative
;
.left-sankey-echarts
{
width
:
100%
;
...
...
@@ -825,14 +1287,16 @@ onMounted(() => {
.right-main
{
width
:
792px
;
height
:
421px
;
padding
:
40px
5px
30px
22px
;
height
:
412px
;
box-sizing
:
border-box
;
/* 对齐智库概览-数据总览内边距 */
padding
:
24px
24px
65px
24px
;
position
:
relative
;
.right-main-echarts
{
/* 矢量 476 */
width
:
780px
;
height
:
350px
;
width
:
100%
;
height
:
100%
;
}
.right-main-tit
{
...
...
@@ -849,15 +1313,16 @@ onMounted(() => {
.right-main1
{
width
:
792px
;
height
:
421px
;
padding
:
20px
20px
;
height
:
412px
;
/* 对齐智库概览-数据总览内边距 */
padding
:
24px
24px
65px
24px
;
position
:
relative
;
box-sizing
:
border-box
;
.right-boxplot-echarts
{
width
:
100%
;
height
:
100%
;
min-height
:
300px
;
height
:
323px
;
}
.right-main1-tit
{
...
...
@@ -876,6 +1341,50 @@ onMounted(() => {
}
}
/* 数据总览内:TipTab 与 AI 解读(尽量复用智库概览的定位) */
.source
{
position
:
absolute
;
left
:
24px
;
bottom
:
21px
;
z-index
:
2
;
}
.chart-box
{
position
:
absolute
;
right
:
0px
;
bottom
:
18px
;
width
:
74px
;
height
:
28px
;
z-index
:
3
;
.btn-box
{
width
:
74px
;
height
:
28px
;
}
.content-box
{
width
:
792px
;
position
:
absolute
;
right
:
0
;
bottom
:
-18px
;
}
}
.datasub-el-empty
{
position
:
absolute
;
inset
:
0
;
display
:
flex
;
align-items
:
center
;
justify-content
:
center
;
padding
:
0
;
margin
:
0
;
z-index
:
5
;
:deep
(
.el-empty__description
)
{
margin-top
:
8px
;
}
}
.btn
{
position
:
absolute
;
top
:
11px
;
...
...
src/views/scientificFunding/components/resLib/index.vue
浏览文件 @
8d534f1e
...
...
@@ -6,7 +6,7 @@
{{
item
.
orgName
}}
</div>
</div>
<div
class=
"
selec
t-box"
>
<div
class=
"
reslib-sor
t-box"
>
<div
class=
"paixu-btn"
@
click=
"handleSwithSort()"
>
<div
class=
"icon1"
>
<img
v-if=
"sort"
src=
"@/assets/icons/shengxu1.png"
alt=
""
/>
...
...
@@ -21,42 +21,41 @@
</div>
<div
class=
"main"
>
<div
class=
"left"
>
<div
class=
"left-ti1"
></div>
<div
class=
"left-ti2"
></div>
<!--
<div
class=
"left-title"
>
项目经费
</div>
<div
class=
"left-content"
>
<div
v-for=
"(item, i) in dataList"
:key=
"item.id"
class=
"left-item"
>
<input
type=
"checkbox"
checked
/>
{{
item
.
name
}}
<div
class=
"select-box"
>
<div
class=
"header"
>
<div
class=
"icon"
></div>
<div
class=
"title"
>
科技领域
</div>
</div>
</div>
-->
<div
class=
"left-title cl1"
>
涉及领域
</div>
<div
class=
"left-content"
>
<el-checkbox
v-model=
"checkAll"
:indeterminate=
"isIndeterminate"
class=
"all-checkbox"
@
change=
"handleCheckAllChange"
>
全部领域
<div
class=
"select-main"
>
<el-checkbox-group
class=
"checkbox-group"
:model-value=
"selectedAreaListModel"
@
change=
"handleAreaGroupChange"
>
<el-checkbox
class=
"filter-checkbox all-checkbox"
:label=
"RESOURCE_FILTER_ALL_AREA"
>
{{
RESOURCE_FILTER_ALL_AREA
}}
</el-checkbox>
<el-checkbox
v-for=
"research in areaList"
:key=
"research.id"
v-model=
"selectedAreaList"
:label=
"research.id"
@
change=
"handleCheckedAreaChange()"
class=
"filter-checkbox"
>
<el-checkbox
v-for=
"research in areaList"
:key=
"research.id"
class=
"filter-checkbox"
:label=
"research.id"
>
{{
research
.
name
}}
</el-checkbox>
<!--
<div
v-for=
"(item, i) in areaList"
:key=
"item.id"
class=
"left-item"
>
<input
type=
"checkbox"
:checked=
"i === 0"
/>
{{
item
.
name
}}
</div>
-->
</el-checkbox-group>
</div>
</div>
<div
class=
"left-title cl1"
>
发布时间
</div>
<div
class=
"left-content"
>
<el-checkbox
v-model=
"checkAllTime"
class=
"all-checkbox"
:indeterminate=
"isIndeterminateTime"
@
change=
"handleCheckAllChangeTime"
>
全部时间
<div
class=
"select-box"
>
<div
class=
"header"
>
<div
class=
"icon"
></div>
<div
class=
"title"
>
发布时间
</div>
</div>
<div
class=
"select-main"
>
<el-checkbox-group
class=
"checkbox-group"
:model-value=
"selectedPubTimeListModel"
@
change=
"handleTimeGroupChange"
>
<el-checkbox
class=
"filter-checkbox all-checkbox"
:label=
"RESOURCE_FILTER_ALL_TIME"
>
{{
RESOURCE_FILTER_ALL_TIME
}}
</el-checkbox>
<el-checkbox-group
v-model=
"selectedPubTimeList"
>
<el-checkbox
v-for=
"time in pubTimeList"
:key=
"time.id"
:label=
"time.id"
class=
"filter-checkbox"
@
change=
"handleCheckedAreaChangeTime()"
>
<el-checkbox
v-for=
"time in pubTimeList"
:key=
"time.id"
class=
"filter-checkbox"
:label=
"time.id"
>
{{
time
.
name
}}
</el-checkbox>
</el-checkbox-group>
</div>
</div>
</div>
<div
class=
"right"
>
<div
class=
"right-title"
>
<img
src=
"./assets/icon01.png"
alt=
""
/>
...
...
@@ -68,29 +67,22 @@
<div
class=
"right-item-title"
>
{{
item
.
projectName
}}
</div>
<div
class=
"right-item-content"
>
{{
item
.
abstractContent
}}
</div>
<div
class=
"right-item-pie"
>
<div
v-for=
"(pie, i) in item.areaList"
:key=
"i"
class=
"right-item-pie-item"
:class=
"
{
cl1: pie === '新材料',
cl2: pie === '人工智能',
cl3: pie === '量子科技',
cl4: pie === '能源',
cl5: pie === '生物科技',
cl6: pie === '航空航天'
}">
{{
pie
}}
</div>
<AreaTag
v-for=
"(val, idx) in item.areaList"
:key=
"idx"
:tagName=
"val"
/>
</div>
<div
class=
"right-item-time"
>
{{
item
.
publicationDate
}}
</div>
<div
class=
"right-item-money"
:style=
"
{ color: item.amount
<
=
1000
?
'
rgba
(
232
,
189
,
11
,
1
)'
:
item
.
amount
<
=
10000
?
'
rgba
(
255
,
149
,
77
,
1
)'
:
'
rgba
(
206
,
79
,
81
,
1
)'
}"
>
{{
'$'
+
item
.
amount
+
'万'
}}
</div>
</div>
<div
class=
"page"
>
<div
class=
"count"
>
共
{{
total
}}
项
</div>
<el-pagination
v-model:current-page=
"currentPage"
:page-size=
"pageSize"
:total=
"total"
layout=
"prev, pager, next"
background
@
current-change=
"handlePageChange"
/>
</div>
</div>
</div>
</div>
</div>
...
...
@@ -101,49 +93,35 @@ import { ref, onMounted } from "vue";
import
{
getProjectListNew
,
geFundSourceOrg
,
getAreaType
}
from
"@/api/scientificFunding/overview"
;
import
{
RESOURCE_FILTER_ALL_AREA
,
RESOURCE_FILTER_ALL_TIME
,
RESOURCE_FILTER_EARLIER
,
normalizeExclusiveAllOption
,
stripAllAreaForRequest
,
stripAllTimeForRequest
,
isSelectionCoveringAllOptions
,
expandEarlierNumericYears
}
from
"@/views/thinkTank/utils/resourceLibraryFilters"
;
/** 领域字典与接口 arealist 使用数字 id(1、2、3…) */
const
normalizeAreaId
=
(
id
)
=>
{
const
n
=
Number
(
id
);
return
Number
.
isFinite
(
n
)
?
n
:
id
;
};
/** 请求用:仅保留合法整数领域 id */
const
toAreaIdListForRequest
=
(
ids
)
=>
{
const
list
=
Array
.
isArray
(
ids
)
?
ids
:
[];
return
list
.
map
((
id
)
=>
normalizeAreaId
(
id
))
.
filter
((
id
)
=>
typeof
id
===
"number"
&&
Number
.
isInteger
(
id
));
};
const
navList
=
ref
([]);
const
activeItem
=
ref
(
""
);
const
areaList
=
ref
([
{
id
:
1
,
name
:
"全部领域"
},
{
id
:
2
,
name
:
"人工智能"
},
{
id
:
3
,
name
:
"集成电路"
},
{
id
:
4
,
name
:
"通信网络"
},
{
id
:
5
,
name
:
"量子科技"
},
{
id
:
6
,
name
:
"能源"
},
{
id
:
7
,
name
:
"生物科技"
},
{
id
:
8
,
name
:
"航空航天"
},
{
id
:
9
,
name
:
"海洋"
}
]);
const
areaList
=
ref
([]);
// 来源机构列表
...
...
@@ -160,99 +138,97 @@ const handleGeFundSourceOrg = async () => {
}
};
const
checkAll
=
ref
(
false
);
const
isIndeterminate
=
ref
(
true
);
const
selectedAreaList
=
ref
([]);
const
handleCheckAllChange
=
val
=>
{
// console.log(val, "handleCheckAllChange");
if
(
val
)
{
isIndeterminate
.
value
=
false
;
selectedAreaList
.
value
.
length
!==
areaList
.
value
.
length
?
(
selectedAreaList
.
value
=
areaList
.
value
.
map
(
obj
=>
obj
.
id
))
:
""
;
}
else
{
selectedAreaList
.
value
=
[];
}
// selectedAreaList.value = val ? areaList : []
// isIndeterminate.value = false
const
selectedAreaListModel
=
ref
([
RESOURCE_FILTER_ALL_AREA
]);
const
selectedPubTimeListModel
=
ref
([
RESOURCE_FILTER_ALL_TIME
]);
const
handleAreaGroupChange
=
(
val
)
=>
{
selectedAreaListModel
.
value
=
normalizeExclusiveAllOption
(
val
,
RESOURCE_FILTER_ALL_AREA
).
map
((
item
)
=>
item
===
RESOURCE_FILTER_ALL_AREA
?
item
:
normalizeAreaId
(
item
)
);
handleGetProjectListNew
();
};
const
handleCheckedAreaChange
=
()
=>
{
// console.log(selectedAreaList.value, "handleCheckedAreaChange");
console
.
log
(
selectedAreaList
.
value
,
"当前选中的领域"
);
selectedAreaList
.
value
.
length
!==
areaList
.
value
.
length
?
(
isIndeterminate
.
value
=
true
)
:
((
checkAll
.
value
=
true
),
(
isIndeterminate
.
value
=
false
));
const
handleTimeGroupChange
=
(
val
)
=>
{
selectedPubTimeListModel
.
value
=
normalizeExclusiveAllOption
(
val
,
RESOURCE_FILTER_ALL_TIME
);
handleGetProjectListNew
();
};
const
pubTimeList
=
ref
([
{
id
:
2025
,
name
:
"2025"
name
:
"2025
年
"
},
{
id
:
2024
,
name
:
"2024"
name
:
"2024
年
"
},
{
id
:
2023
,
name
:
"2023"
name
:
"2023
年
"
},
{
id
:
2022
,
name
:
"2022"
name
:
"2022
年
"
},
{
id
:
2021
,
name
:
"2021"
name
:
"2021年"
},
{
id
:
RESOURCE_FILTER_EARLIER
,
name
:
RESOURCE_FILTER_EARLIER
}
// {
// id: "更早时间",
// name: "更早时间"
// }
]);
const
selectedPubTimeList
=
ref
([
""
]);
const
checkAllTime
=
ref
(
false
);
const
isIndeterminateTime
=
ref
(
true
);
/** 选择「全部时间」时,yearlist 传 2000~2025 逐年 */
const
YEAR_ALL_RANGE_START
=
2000
;
const
YEAR_ALL_RANGE_END
=
2025
;
const
buildYearlistForRequest
=
(
selectedTimeModel
)
=>
{
const
strippedTime
=
stripAllTimeForRequest
(
selectedTimeModel
);
// 仅勾选「全部时间」、未选具体年份时,传 2000~2025 逐年
if
(
strippedTime
.
length
===
0
)
{
const
out
=
[];
for
(
let
y
=
YEAR_ALL_RANGE_START
;
y
<=
YEAR_ALL_RANGE_END
;
y
+=
1
)
{
out
.
push
(
String
(
y
));
}
return
out
;
}
const
hasEarlier
=
strippedTime
.
includes
(
RESOURCE_FILTER_EARLIER
);
const
numericOnly
=
strippedTime
.
filter
((
id
)
=>
id
!==
RESOURCE_FILTER_EARLIER
);
const
strippedNums
=
numericOnly
.
map
((
id
)
=>
Number
(
id
))
.
filter
((
n
)
=>
Number
.
isInteger
(
n
));
// 勾选「更早」:展开为 2000~2020,并与已选数字年合并(可与其他年份同时选)
if
(
hasEarlier
)
{
const
yearsSet
=
new
Set
(
expandEarlierNumericYears
());
strippedNums
.
forEach
((
n
)
=>
yearsSet
.
add
(
n
));
return
[...
yearsSet
]
.
sort
((
a
,
b
)
=>
a
-
b
)
.
map
((
n
)
=>
String
(
n
));
}
return
strippedNums
.
map
((
n
)
=>
String
(
n
));
};
const
sort
=
ref
(
false
);
const
handleSwithSort
=
()
=>
{
sort
.
value
=
!
sort
.
value
;
handleGetProjectListNew
();
};
const
handleCheckAllChangeTime
=
val
=>
{
// console.log(val, "handleCheckAllChange");
if
(
val
)
{
isIndeterminateTime
.
value
=
false
;
selectedPubTimeList
.
value
.
length
!==
pubTimeList
.
value
.
length
?
(
selectedPubTimeList
.
value
=
pubTimeList
.
value
.
map
(
obj
=>
obj
.
id
))
:
""
;
}
else
{
selectedPubTimeList
.
value
=
[];
}
// selectedAreaList.value = val ? areaList : []
// isIndeterminate.value = false
handleGetProjectListNew
();
};
const
handleCheckedAreaChangeTime
=
()
=>
{
// console.log(selectedAreaList.value, "handleCheckedAreaChange");
console
.
log
(
selectedPubTimeList
.
value
,
"当前选中的时间"
);
selectedPubTimeList
.
value
.
length
!==
pubTimeList
.
value
.
length
?
(
isIndeterminateTime
.
value
=
true
)
:
((
checkAllTime
.
value
=
true
),
(
isIndeterminateTime
.
value
=
false
));
handleGetProjectListNew
();
};
// 获取行业领域列表
const
handleGetAreaType
=
async
()
=>
{
try
{
const
res
=
await
getAreaType
();
console
.
log
(
"获取行业领域列表"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
areaList
.
value
=
res
.
data
areaList
.
value
=
res
.
data
.
map
((
row
)
=>
({
...
row
,
id
:
normalizeAreaId
(
row
.
id
)
}));
}
}
catch
(
error
)
{
console
.
error
(
"获取行业领域列表error"
,
error
);
...
...
@@ -270,11 +246,22 @@ const handlePageChange = p => {
// 资助体系v2.0:资助项目列表分页
const
handleGetProjectListNew
=
async
()
=>
{
try
{
const
strippedArea
=
toAreaIdListForRequest
(
stripAllAreaForRequest
(
selectedAreaListModel
.
value
)
);
const
allAreaIds
=
toAreaIdListForRequest
(
areaList
.
value
.
map
((
obj
)
=>
obj
.
id
));
const
arealist
=
strippedArea
.
length
===
0
||
isSelectionCoveringAllOptions
(
strippedArea
,
allAreaIds
)
?
allAreaIds
:
strippedArea
;
const
yearlist
=
buildYearlistForRequest
(
selectedPubTimeListModel
.
value
);
let
params
=
{
arealist
:
selectedAreaList
.
value
,
arealist
,
currentPage
:
currentPage
.
value
,
pageSize
:
10
,
yearlist
:
selectedPubTimeList
.
value
.
map
(
item
=>
item
.
toString
().
trim
()).
filter
(
item
=>
item
!==
""
)
,
yearlist
,
funSort
:
sort
.
value
?
'desc'
:
'asc'
,
orgId
:
activeItem
.
value
}
...
...
@@ -305,11 +292,10 @@ onMounted(async () => {
.reslib-page
{
width
:
1600px
;
height
:
1565px
;
position
:
relative
;
.select-box
{
position
:
relative
;
.reslib-sort-box
{
width
:
128px
;
position
:
absolute
;
top
:
7px
;
...
...
@@ -370,15 +356,15 @@ onMounted(async () => {
}
.nav
{
width
:
calc
(
100%
-
100px
);
height
:
42px
;
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
margin-bottom
:
34px
;
.nav-item
{
width
:
100%
;
text-align
:
center
;
cursor
:
pointer
;
padding
:
8px
20px
;
...
...
@@ -397,133 +383,85 @@ onMounted(async () => {
}
}
.select
{
width
:
128px
;
position
:
absolute
;
top
:
7px
;
right
:
0px
;
}
.main
{
width
:
1600px
;
height
:
1489px
;
display
:
flex
;
margin-bottom
:
100px
;
.left
{
width
:
3
0
0px
;
width
:
3
6
0px
;
margin-right
:
16px
;
height
:
100%
;
padding-bottom
:
24px
;
box-sizing
:
border-box
;
border
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
border-radius
:
10px
;
b
ackground-color
:
#fff
;
b
ox-shadow
:
0px
0px
20px
0px
rgba
(
25
,
69
,
130
,
0
.
1
);
b
ox-shadow
:
0px
0px
20px
0px
rgba
(
94
,
95
,
95
,
0
.1
)
;
b
ackground
:
rgba
(
255
,
255
,
255
,
1
);
position
:
relative
;
.left-ti1
{
width
:
8px
;
height
:
16px
;
background-color
:
rgb
(
5
,
95
,
194
);
border-top-right-radius
:
3px
;
border-bottom-right-radius
:
3px
;
position
:
absolute
;
top
:
17px
;
left
:
0px
;
}
.select-box
{
margin-top
:
16px
;
.left-ti2
{
.header
{
display
:
flex
;
gap
:
17px
;
.icon
{
margin-top
:
4px
;
width
:
8px
;
height
:
16px
;
background-color
:
rgb
(
5
,
95
,
194
);
border-top-right-radius
:
3px
;
border-bottom-right-radius
:
3px
;
position
:
absolute
;
top
:
207px
;
left
:
0px
;
background
:
var
(
--
color-main-active
);
border-radius
:
0
4px
4px
0
;
}
.left-title
{
margin-left
:
25px
;
color
:
rgb
(
5
,
95
,
194
);
.title
{
height
:
24px
;
color
:
var
(
--
color-main-active
);
font-family
:
"Source Han Sans CN"
;
font-size
:
16px
;
font-weight
:
700
;
font-family
:
"Microsoft YaHei"
;
line-height
:
24px
;
margin-top
:
13px
;
letter-spacing
:
1px
;
text-align
:
left
;
}
}
.left-content
{
width
:
253px
;
// height: 132px;
margin-left
:
25px
;
margin-top
:
13px
;
display
:
flex
;
flex-wrap
:
wrap
;
/* 允许内容换行 */
justify-content
:
space-between
;
/* 两端对齐 */
.left-item
{
white-space
:
nowrap
;
/* 保持在一行内 */
overflow
:
hidden
;
/* 隐藏超出部分 */
text-overflow
:
ellipsis
;
/* 超出部分显示省略号 */
width
:
calc
(
50%
-
8px
);
/* 每个选项占一半宽度,减去间距 */
height
:
30px
;
margin-bottom
:
4px
;
font-size
:
16px
;
font-weight
:
400
;
font-family
:
"Microsoft YaHei"
;
line-height
:
24px
;
color
:
rgb
(
95
,
101
,
108
);
.select-main
{
margin-left
:
24px
;
margin-top
:
12px
;
input
[
type
=
"checkbox"
]
{
-webkit-appearance
:
none
;
appearance
:
none
;
width
:
14px
;
height
:
14px
;
margin-right
:
8px
;
border
:
1px
solid
rgb
(
200
,
204
,
210
);
border-radius
:
4px
;
background-color
:
#fff
;
vertical-align
:
middle
;
}
.checkbox-group
{
display
:
grid
;
grid-template-columns
:
repeat
(
2
,
160px
);
gap
:
8px
4px
;
input
[
type
=
"checkbox"
]
:checked
{
background-color
:
rgb
(
5
,
95
,
194
);
border-top-right-radius
:
3px
;
border-bottom-right-radius
:
3px
;
margin-right
:
17px
;
:deep
(
.all-checkbox
)
{
width
:
160px
;
height
:
24px
;
margin
:
0
;
}
input
[
type
=
"checkbox"
]
:checked::after
{
content
:
""
;
display
:
block
;
width
:
4px
;
height
:
8px
;
margin
:
1px
auto
0
;
border
:
2px
solid
#fff
;
border-top
:
none
;
border-left
:
none
;
transform
:
rotate
(
45deg
);
:deep
(
.filter-checkbox
)
{
width
:
160px
;
height
:
24px
;
margin-right
:
0
!
important
;
}
}
}
.cl1
{
margin-top
:
21px
;
}
}
.right
{
width
:
12
8
4px
;
height
:
1489px
;
width
:
12
2
4px
;
border-radius
:
10px
;
background-color
:
#fff
;
box-shadow
:
0px
0px
20px
0px
rgba
(
25
,
69
,
130
,
0
.1
);
.right-title
{
width
:
12
8
4px
;
width
:
12
2
4px
;
height
:
48px
;
border-bottom
:
1px
solid
rgb
(
235
,
238
,
242
);
position
:
relative
;
...
...
@@ -550,13 +488,13 @@ onMounted(async () => {
}
.right-main
{
width
:
12
8
4px
;
height
:
1441px
;
width
:
12
2
4px
;
padding
:
19px
34px
20px
29px
;
position
:
relative
;
.right-item
{
width
:
1
22
1px
;
width
:
1
16
1px
;
height
:
124px
;
border-bottom
:
1px
solid
rgb
(
234
,
236
,
238
);
margin-bottom
:
8px
;
...
...
@@ -588,7 +526,7 @@ onMounted(async () => {
/* 隐藏超出部分 */
text-overflow
:
ellipsis
;
/* 超出部分显示省略号 */
width
:
90%
;
width
:
1112px
;
/* 设置一个固定的宽度或百分比 */
position
:
absolute
;
top
:
44px
;
...
...
@@ -605,6 +543,7 @@ onMounted(async () => {
top
:
76px
;
left
:
56px
;
display
:
flex
;
gap
:
8px
;
.right-item-pie-item
{
padding
:
2px
8px
;
...
...
@@ -677,15 +616,16 @@ onMounted(async () => {
}
.page
{
width
:
1
22
1px
;
width
:
1
16
1px
;
height
:
40px
;
display
:
flex
;
align-items
:
center
;
justify-content
:
space-between
;
position
:
absolute
;
bottom
:
20px
;
left
:
20px
;
padding-left
:
11px
;
margin-top
:
29px
;
.count
{
font-size
:
16px
;
...
...
@@ -749,7 +689,10 @@ onMounted(async () => {
background-color
:
#fff
;
}
}
}
}
}
}
...
...
src/views/scientificFunding/index.vue
浏览文件 @
8d534f1e
...
...
@@ -14,14 +14,8 @@
<div
class=
"main-content"
ref=
"containerRef"
>
<div
class=
"home-top-bg"
></div>
<!-- 搜索栏部分 -->
<SearchContainer
style=
"margin-bottom: 48px; height: fit-content"
v-if=
"containerRef"
:countInfo=
"countInfo"
placeholder=
"搜索科研资助实体、资助记录"
:containerRef=
"containerRef"
areaName=
""
/>
<SearchContainer
style=
"margin-bottom: 48px; height: fit-content"
v-if=
"containerRef"
:countInfo=
"countInfo"
placeholder=
"搜索科研资助实体、资助记录"
:containerRef=
"containerRef"
areaName=
""
/>
<!--
<div
class=
"search"
>
-->
<!--
<div
class=
"search-main"
>
...
...
@@ -78,7 +72,8 @@
<!--
</div>
-->
<!-- 6个数据 -->
<div
class=
"data"
>
<div
v-for=
"(item, index) in dataList"
:key=
"item.id"
class=
"data-item"
>
<div
v-for=
"(item, index) in dataList"
:key=
"item.orgId || item.id"
class=
"data-item"
@
click=
"handleClickOrg(item)"
>
<img
v-if=
"item.logoUrl && /\\.(jpe?g|png)$/i.test(item.logoUrl)"
:src=
"item.logoUrl"
alt=
""
/>
<img
v-else
src=
"./assets/images/nullcorpimg.png"
alt=
""
/>
<div
class=
"data-text-item"
>
...
...
@@ -91,28 +86,28 @@
</div>
<!-- 最新动态 -->
<div
class=
"newdata"
id=
"position1"
>
<com-title
title=
"最新动态"
/>
<com-title
title=
"最新动态"
style=
"width: 1600px;"
/>
<div
class=
"newdata-main"
>
<newData
/>
</div>
</div>
<!-- 资讯要问 -->
<div
class=
"ask"
id=
"position2"
>
<com-title
title=
"资讯要闻"
/>
<com-title
title=
"资讯要闻"
style=
"width: 1600px;"
/>
<div
class=
"ask-main"
>
<askPage
/>
</div>
</div>
<!-- 数据总览 -->
<div
class=
"datasub"
id=
"position3"
>
<com-title
title=
"数据总览"
/>
<com-title
title=
"数据总览"
style=
"width: 1600px;"
/>
<div
class=
"datasub-main"
>
<dataSub
/>
</div>
</div>
<!-- 资源库 -->
<div
class=
"reslib"
id=
"position4"
>
<com-title
title=
"资源库"
/>
<com-title
title=
"资源库"
style=
"width: 1600px;"
/>
<div
class=
"reslib-main"
>
<resLib
/>
</div>
...
...
@@ -170,6 +165,21 @@ const handleBackHome = () => {
path
:
"/overview"
});
};
// 点击机构卡片跳转机构详情
const
handleClickOrg
=
(
item
)
=>
{
const
orgId
=
item
?.
orgId
;
if
(
!
orgId
)
return
;
// Institution 路由开启了 dynamicTitle,这里提前写入标题,避免沿用上一次的“白宫”等旧值
const
title
=
item
?.
orgName
||
""
;
window
.
sessionStorage
.
setItem
(
"institutionTabName"
,
title
);
window
.
sessionStorage
.
setItem
(
"curTabName"
,
title
);
const
route
=
router
.
resolve
({
path
:
"/institution"
,
query
:
{
id
:
orgId
,
name
:
title
}
});
window
.
open
(
route
.
href
,
"_blank"
);
};
// 固定数据
const
dataList
=
ref
([
{
...
...
@@ -576,12 +586,12 @@ onMounted(async () => {
.reslib
{
width
:
1600px
;
height
:
1633px
;
margin
:
0
auto
0px
auto
;
.reslib-main
{
width
:
1600px
;
height
:
1565px
;
margin-top
:
26px
;
}
}
...
...
src/views/thinkTank/CongressHearingView/index.vue
浏览文件 @
8d534f1e
...
...
@@ -399,7 +399,8 @@ const reportAuthors = computed(() => {
// 点击报告作者头像,跳转到人物主页
// 与核心研究人员逻辑一致:核心依赖 personId,本页面依赖作者的 id(作为 personId 传入)
const
handleClickReportAuthor
=
async
(
author
)
=>
{
const
personId
=
author
?.
id
;
const
personId
=
author
?.
personId
;
if
(
!
personId
)
return
;
...
...
src/views/thinkTank/ThinkTankDetail/thinkDynamics/CongressHearing/index.vue
浏览文件 @
8d534f1e
...
...
@@ -96,6 +96,7 @@
</div>
<div
class=
"divider"
v-if=
"index !== hearingData.length - 1"
></div>
</div>
</div>
</div>
<div
class=
"right-footer"
>
...
...
@@ -107,6 +108,7 @@
@
current-change=
"handleCurrentChange"
:current-page=
"currentPage"
/>
</div>
</div>
</div>
</div>
</
template
>
...
...
@@ -287,6 +289,12 @@ const handleToReportDetail = item => {
.main-content
{
display
:
flex
;
gap
:
16px
;
height
:
100%
;
margin-bottom
:
100px
;
.left
{
width
:
360px
;
...
...
@@ -299,6 +307,7 @@ const handleToReportDetail = item => {
background
:
rgba
(
255
,
255
,
255
,
1
);
position
:
relative
;
.select-research-box
{
width
:
360px
;
height
:
100%
;
...
...
@@ -480,14 +489,20 @@ const handleToReportDetail = item => {
.right
{
width
:
1224px
;
height
:
1377px
;
.card-box
{
width
:
100%
;
height
:
1248px
;
height
:
100%
;
display
:
flex
;
background
:
rgba
(
255
,
255
,
255
,
1
);
box-sizing
:
border-box
;
border
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
...
...
@@ -495,12 +510,15 @@ const handleToReportDetail = item => {
box-shadow
:
0px
0px
20px
0px
rgba
(
94
,
95
,
95
,
0
.1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
.card-content
{
width
:
1211px
;
height
:
1067px
;
margin-top
:
33px
;
margin-top
:
33px
;
margin-left
:
37px
;
padding-bottom
:
27px
;
.card-item
{
width
:
100%
;
...
...
@@ -585,8 +603,13 @@ const handleToReportDetail = item => {
}
}
.right-footer
{
margin-top
:
43px
;
margin-top
:
35px
;
display
:
flex
;
justify-content
:
space-between
;
...
...
@@ -601,7 +624,6 @@ const handleToReportDetail = item => {
text-align
:
left
;
}
}
}
}
:deep
(
.el-checkbox
)
{
...
...
src/views/thinkTank/components/ThinkTankCongressHearingOverview.vue
浏览文件 @
8d534f1e
...
...
@@ -58,6 +58,7 @@
<div
class=
"right"
>
<div
class=
"card-box"
>
<div
class=
"card-content"
>
<div
v-for=
"(item, index) in hearingData"
:key=
"item.id ?? index"
>
<div
class=
"card-item"
>
<img
class=
"card-item-img"
:src=
"item.coverImgUrl"
alt=
"report image"
/>
...
...
@@ -80,9 +81,10 @@
</div>
<div
class=
"divider"
v-if=
"index !== hearingData.length - 1"
></div>
</div>
</div>
</div>
</div>
<div
class=
"right-footer"
>
<div
class=
"info"
>
共
{{
hearingData
.
length
}}
篇智库报告
...
...
@@ -92,6 +94,7 @@
@
current-change=
"handlePageChange"
:current-page=
"currentPage"
/>
</div>
</div>
</div>
</div>
</
template
>
...
...
@@ -186,6 +189,7 @@ const handlePageChange = page => {
.home-main-footer-main
{
margin
:
0
auto
;
margin-top
:
36px
;
width
:
1600px
;
display
:
flex
;
gap
:
16px
;
...
...
@@ -270,11 +274,11 @@ const handlePageChange = page => {
.right
{
width
:
1224px
;
height
:
1377px
;
.card-box
{
width
:
100%
;
height
:
1134px
;
display
:
flex
;
background
:
rgba
(
255
,
255
,
255
,
1
);
box-sizing
:
border-box
;
...
...
@@ -282,16 +286,22 @@ const handlePageChange = page => {
border-radius
:
10px
;
box-shadow
:
0px
0px
20px
0px
rgba
(
94
,
95
,
95
,
0
.1
);
padding-right
:
36px
;
height
:
100%
;
.card-content
{
width
:
1211px
;
height
:
1067px
;
margin-top
:
33px
;
margin-left
:
37px
;
padding-bottom
:
27px
;
}
}
.right-footer
{
}
.right-footer
{
margin-top
:
43px
;
display
:
flex
;
justify-content
:
space-between
;
...
...
@@ -306,7 +316,6 @@ const handlePageChange = page => {
letter-spacing
:
0px
;
text-align
:
left
;
}
}
}
.card-item
{
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论