Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
R
risk-monitor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蔡建
risk-monitor
Commits
86617244
提交
86617244
authored
4月 15, 2026
作者:
张伊明
浏览文件
操作
浏览文件
下载
差异文件
合并分支 'zy-dev' 到 'pre'
Zy dev 查看合并请求
!342
上级
ddff29ea
eb9f4307
流水线
#487
已通过 于阶段
in 4 分 50 秒
变更
31
流水线
1
隐藏空白字符变更
内嵌
并排
正在显示
31 个修改的文件
包含
2282 行增加
和
2086 行删除
+2282
-2086
index.js
src/api/marketAccessRestrictions/index.js
+23
-2
index.vue
src/components/base/TipTab/index.vue
+13
-2
marketAccessRestrictions.js
src/router/modules/marketAccessRestrictions.js
+8
-2
index.vue
src/views/decree/decreeHome/index.vue
+22
-65
index.vue
src/views/decree/decreeLayout/overview/measures/index.vue
+4
-90
Level1List.vue
src/views/marketAccessRestrictions/com/Level1List.vue
+91
-0
Level2List.vue
src/views/marketAccessRestrictions/com/Level2List.vue
+41
-0
SurveyConclusion.vue
src/views/marketAccessRestrictions/com/SurveyConclusion.vue
+3
-75
CarouselItem232.vue
...cessRestrictions/marketAccessHome/com/CarouselItem232.vue
+4
-4
CarouselItem301.vue
...cessRestrictions/marketAccessHome/com/CarouselItem301.vue
+4
-5
index.vue
...views/marketAccessRestrictions/marketAccessHome/index.vue
+147
-45
barChart1.js
...ketAccessRestrictions/marketAccessHome/utils/barChart1.js
+32
-18
index.vue
...tAccessRestrictions/marketAccessLayout/case/232/index.vue
+26
-47
index.vue
...tAccessRestrictions/marketAccessLayout/case/301/index.vue
+38
-75
index.vue
...tAccessRestrictions/marketAccessLayout/case/337/index.vue
+8
-49
index.vue
...ews/marketAccessRestrictions/marketAccessLayout/index.vue
+1
-2
index.vue
...essRestrictions/marketAccessLayout/overview/232/index.vue
+285
-317
index.vue
...essRestrictions/marketAccessLayout/overview/301/index.vue
+202
-385
barChart.js
...ictions/marketAccessLayout/overview/301/utils/barChart.js
+37
-30
index.vue
...essRestrictions/marketAccessLayout/overview/337/index.vue
+292
-521
barChart.js
...ictions/marketAccessLayout/overview/337/utils/barChart.js
+1
-1
reportOriginal.vue
src/views/marketAccessRestrictions/pages/reportOriginal.vue
+597
-0
index.vue
...AccessRestrictions/singleCaseLayout/deepdig/232/index.vue
+79
-115
index.vue
...AccessRestrictions/singleCaseLayout/deepdig/337/index.vue
+7
-19
index.vue
...views/marketAccessRestrictions/singleCaseLayout/index.vue
+16
-26
index.vue
...ccessRestrictions/singleCaseLayout/overview/232/index.vue
+30
-37
index.vue
...ccessRestrictions/singleCaseLayout/overview/301/index.vue
+38
-46
index.vue
...ccessRestrictions/singleCaseLayout/overview/337/index.vue
+5
-7
baseLineChart.js
src/views/marketAccessRestrictions/utils/baseLineChart.js
+56
-77
basePiechart.js
src/views/marketAccessRestrictions/utils/basePiechart.js
+60
-24
index.ts
src/views/marketAccessRestrictions/utils/index.ts
+112
-0
没有找到文件。
src/api/marketAccessRestrictions/index.js
浏览文件 @
86617244
...
...
@@ -11,10 +11,11 @@ export function getStatCount(params) {
}
// 分类接口
export
function
getStatSort
()
{
export
function
getStatSort
(
params
)
{
return
request
({
method
:
'GET'
,
url
:
`/api/marketsearchHome/statSort`
url
:
`/api/marketsearchHome/statSort`
,
params
})
}
...
...
@@ -39,6 +40,18 @@ export function getStatNum(params) {
})
}
// 查询关税税率
/**
* @param {byYorM}
*/
export
function
getSearchTariff
(
params
)
{
return
request
({
method
:
'GET'
,
url
:
`/api/marketsearchDetails/getSearchTariff`
,
params
})
}
// 制裁领域分布
/**
* @param {years}
...
...
@@ -178,6 +191,14 @@ export function getSearchBlurb(params) {
})
}
// 获取原文
export
function
getOriginalUrl
(
params
)
{
return
request
({
method
:
'GET'
,
url
:
`/api/marketsearchDetails/getOriginalUrl/
${
params
.
id
}
`
,
})
}
// 获取相关事件
export
function
getRelatedEvents
(
params
)
{
return
request
({
...
...
src/components/base/TipTab/index.vue
浏览文件 @
86617244
...
...
@@ -3,7 +3,10 @@
<div
class=
"icon"
>
<img
src=
"./tip-icon.svg"
alt=
""
>
</div>
<div
class=
"text text-tip-2 text-primary-50-clor"
>
{{
tipText
}}
</div>
<div
class=
"text text-tip-2 text-primary-50-clor"
>
<div
v-if=
"ellipsis"
:title=
"tipText"
class=
"one-line-ellipsis"
>
{{
tipText
}}
</div>
<div
v-else
>
{{
tipText
}}
</div>
</div>
</div>
</
template
>
...
...
@@ -23,7 +26,10 @@ const props = defineProps({
type
:
String
,
default
:
'2023.1至2025.12'
},
ellipsis
:
{
type
:
Boolean
,
default
:
false
}
})
const
tipText
=
computed
(()
=>
props
.
text
||
`数据来源:
${
props
.
dataSource
}
,数据时间:
${
props
.
dataTime
}
`
)
...
...
@@ -48,5 +54,9 @@ const tipText = computed(() => props.text || `数据来源:${props.dataSource}
height
:
100%
;
}
}
.text
{
width
:
20px
;
flex
:
auto
;
}
}
</
style
>
\ No newline at end of file
src/router/modules/marketAccessRestrictions.js
浏览文件 @
86617244
...
...
@@ -6,6 +6,7 @@ const MarketAccessCase = () => import('@/views/marketAccessRestrictions/marketAc
const
MarketSingleCaseLayout
=
()
=>
import
(
'@/views/marketAccessRestrictions/singleCaseLayout/index.vue'
)
const
MarketSingleCaseOverview
=
()
=>
import
(
'@/views/marketAccessRestrictions/singleCaseLayout/overview/index.vue'
)
const
MarketSingleCaseDeepdig
=
()
=>
import
(
'@/views/marketAccessRestrictions/singleCaseLayout/deepdig/index.vue'
)
const
MarketSingleReportOriginal
=
()
=>
import
(
'@/views/marketAccessRestrictions/pages/reportOriginal.vue'
)
const
marketAccessRestrictionsRoutes
=
[
// 市场准入限制首页
...
...
@@ -42,7 +43,6 @@ const marketAccessRestrictionsRoutes = [
}
]
},
{
path
:
"/marketSingleCaseLayout"
,
name
:
"MarketSingleCaseLayout"
,
...
...
@@ -67,7 +67,12 @@ const marketAccessRestrictionsRoutes = [
}
]
},
{
path
:
"reportOriginal"
,
name
:
"MarketSingleReportOriginal"
,
component
:
MarketSingleReportOriginal
,
meta
:
{
noTitle
:
true
}
}
]
export
default
marketAccessRestrictionsRoutes
\ No newline at end of file
src/views/decree/decreeHome/index.vue
浏览文件 @
86617244
...
...
@@ -152,7 +152,7 @@
</div>
<div
class=
"ai-pane"
>
<AiButton
/>
<AiPane
:aiContent=
"
summarize
1"
/>
<AiPane
:aiContent=
"
aiContent.content
1"
/>
</div>
</div>
...
...
@@ -188,7 +188,7 @@
</div>
<div
class=
"ai-pane"
>
<AiButton
/>
<AiPane
:aiContent=
"
summarize
2"
/>
<AiPane
:aiContent=
"
aiContent.content
2"
/>
</div>
</div>
</div>
...
...
@@ -442,6 +442,7 @@ import setChart from "@/utils/setChart";
import
DefaultIcon2
from
"@/assets/icons/default-icon2.png"
;
import
tipsTcon
from
"./assets/images/tips-icon.png"
;
import
{
ElMessage
}
from
"element-plus"
;
import
{
getAIReport
,
getNearYearList
}
from
"@/views/marketAccessRestrictions/utils/index.ts"
import
{
useGotoNewsDetail
}
from
'@/router/modules/news'
;
...
...
@@ -722,17 +723,16 @@ const handleClickPerson = async item => {
}
catch
(
error
)
{
}
};
// 获取最近年份列表
const
currentYear
=
new
Date
().
getFullYear
();
const
getYearList
=
(
count
=
6
)
=>
{
const
yearOptions
=
[];
for
(
let
i
=
0
;
i
<
count
;
i
++
)
{
const
year
=
currentYear
-
i
;
yearOptions
.
push
({
label
:
year
.
toString
(),
value
:
year
.
toString
()
});
}
return
yearOptions
;
};
const
yearList
=
getYearList
();
const
yearList
=
getNearYearList
();
// 获取AI智能报告
const
aiContent
=
reactive
({
content1
:
"正在生成..."
,
content2
:
"正在生成..."
,
})
const
onAIReport
=
(
data
,
key
)
=>
{
getAIReport
(
data
).
then
(
res
=>
{
aiContent
[
key
]
=
res
})
}
// 行政令发布频度
const
chart1Data
=
ref
({
...
...
@@ -745,7 +745,6 @@ const box5Params = reactive({
proposeName
:
''
,
loading
:
false
,
})
const
summarize1
=
ref
()
const
handleGetDecreeYearOrder
=
async
()
=>
{
box5Params
.
loading
=
true
try
{
...
...
@@ -763,61 +762,17 @@ const handleGetDecreeYearOrder = async () => {
chart1Data
.
value
.
dataY
=
res
.
data
.
map
(
item
=>
{
return
item
.
count
;
});
onChartInterpretation
({
type
:
"柱状图"
,
name
:
"数量变化趋势"
,
data
:
res
.
data
},
summarize1
)
onAIReport
({
type
:
"柱状图"
,
name
:
"数量变化趋势"
,
data
:
res
.
data
},
"content1"
)
}
else
{
chart1Data
.
value
.
dataX
=
[];
chart1Data
.
value
.
dataY
=
[];
aiContent
.
content1
=
""
}
}
catch
(
error
)
{
console
.
error
(
"行政令发布频度error"
,
error
);
}
box5Params
.
loading
=
false
};
// AI智能总结
const
onChartInterpretation
=
async
(
text
,
param
)
=>
{
param
.
value
=
"正在生成..."
// 👇 新增:超时 + 终止请求(只加这一段)
const
controller
=
new
AbortController
();
const
timeout
=
setTimeout
(()
=>
controller
.
abort
(),
10000
);
// 10秒超时
try
{
const
response
=
await
fetch
(
'/aiAnalysis/chart_interpretation'
,
{
method
:
'POST'
,
headers
:
{
"X-API-Key"
:
"aircasKEY19491001"
,
'Content-Type'
:
'application/json'
,
},
body
:
JSON
.
stringify
({
text
}),
signal
:
controller
.
signal
// 👇 新增:绑定中断信号
});
clearTimeout
(
timeout
);
// 👇 新增:请求成功清除定时器
if
(
!
response
.
ok
)
throw
new
Error
(
`HTTP 错误
${
response
.
status
}
`
);
const
reader
=
response
.
body
.
getReader
();
const
decoder
=
new
TextDecoder
();
let
buffer
=
''
;
let
summarize
=
''
;
while
(
true
)
{
const
{
done
,
value
}
=
await
reader
.
read
();
if
(
done
)
break
;
buffer
+=
decoder
.
decode
(
value
,
{
stream
:
true
});
const
lines
=
buffer
.
split
(
'
\
n'
);
buffer
=
lines
.
pop
()
||
''
;
for
(
const
line
of
lines
)
{
if
(
line
.
startsWith
(
'data: '
))
{
const
content
=
line
.
substring
(
6
);
const
textMatch
=
content
.
match
(
/"解读":
\s
*"
([^
"
]
*
)
"/
);
if
(
textMatch
&&
textMatch
[
1
])
summarize
=
textMatch
[
1
];
}
}
}
param
.
value
=
summarize
}
catch
(
err
)
{
param
.
value
=
"系统异常,生成失败"
;
}
}
const
handleBox5
=
async
()
=>
{
await
handleGetDecreeYearOrder
();
...
...
@@ -863,7 +818,6 @@ const box6Params = reactive({
proposeName
:
''
,
loading
:
false
,
});
const
summarize2
=
ref
()
const
handleGetDecreeArea
=
async
()
=>
{
box6Params
.
loading
=
true
try
{
...
...
@@ -880,7 +834,10 @@ const handleGetDecreeArea = async () => {
value
:
item
.
count
};
});
onChartInterpretation
({
type
:
"环形图"
,
name
:
"领域分布情况"
,
data
:
res
.
data
},
summarize2
)
onAIReport
({
type
:
"环形图"
,
name
:
"领域分布情况"
,
data
:
res
.
data
},
"content2"
)
}
else
{
chart2Data
.
value
=
[]
aiContent
.
content2
=
""
}
}
catch
(
error
)
{
console
.
error
(
"政令科技领域error"
,
error
);
...
...
src/views/decree/decreeLayout/overview/measures/index.vue
浏览文件 @
86617244
...
...
@@ -53,7 +53,7 @@
<div
v-for=
"(subSubItem, subSubIndex) in subItem.slaver"
:key=
"subSubIndex"
class=
"sub-sub-item"
>
<div
class=
"sub-sub-item-dot"
>
{{ ALPHABET[subSubIndex % 26] }}.
</div>
<div
class=
"sub-sub-item-word"
v-html=
"subItem.content"
></div>
<div
class=
"sub-sub-item-word"
v-html=
"sub
Sub
Item.content"
></div>
</div>
</div>
</div>
...
...
@@ -157,6 +157,7 @@ import ActionButton from '@/components/base/ActionButton/index.vue'
import
DefaultIcon1
from
"@/assets/icons/default-icon1.png"
;
import
DefaultIcon2
from
"@/assets/icons/default-icon2.png"
;
import
defaultCom
from
"@/views/coopRestriction/assets/images/default-icon2.png"
import
{
onNumToChinese
}
from
"@/views/marketAccessRestrictions/utils/index"
const
route
=
useRoute
();
...
...
@@ -185,70 +186,7 @@ const handleGetAreaList = async () => {
// 主要指令
const
isHighlight
=
ref
(
false
);
const
commandWord
=
ref
(
""
);
const
contentList
=
ref
([
// {
// content: "建立美国人工智能出口计划建立美国人工智能出口计划建立美国人工智能出口计划建立美国人工智能出口计划建立美国人工智能出口计划",
// slaver: [
// {
// content: '在本命令发布之日起 90 天内,商务部长应与国务卿及科学技术政策办公室(OSTP)主任协商,建立并实施美国人工智能出口计划(计划),以支持美国全栈人工智能出口软件包的开发和部署。'
// },
// {
// content: '商务部长应公开征集由行业主导的联盟提案,以纳入该计划。公开征集要求每项提案必须:',
// slaver: [
// {
// content: '包含一套全栈人工智能技术包,涵盖:',
// slaver: [
// {
// content: 'AI 优化的计算机硬件(如芯片、服务器和加速器)、数据中心存储、云服务和网络,以及这些设备是否以及在多大程度上在美国制造的描述;'
// },
// {
// content: '数据管道和标签系统;'
// },
// {
// content: '人工智能模型与系统;'
// },
// {
// content: '采取措施保障人工智能模型和系统的安全性和网络安全;'
// },
// {
// content: '针对特定用例的人工智能应用(如软件工程、教育、医疗保健、农业或交通运输);'
// }
// ]
// },
// {
// content: '确定出口参与者的具体目标国家或区域集团;'
// },
// {
// content: '描述一个业务和运营模型,以在高层次上说明哪些实体将建设、拥有和运营数据中心及相关基础设施;'
// },
// {
// content: '联邦激励和支持机制请求的细节;'
// },
// {
// content: '遵守所有相关的美国出口管制制度、出境投资法规和终端用户政策,包括美国法典第 50 编第 58 章及商务部工业与安全局的相关指导。'
// }
// ]
// },
// {
// content: '商务部要求提案须在公开征集后不超过 90 天内提交,并应滚动考虑提案纳入项目。'
// },
// {
// content: '商务部长应与国务卿、国防部长、能源部长及 OSTP 主任协商,评估提交的纳入计划提案。商务部长与国务卿、国防部长、能源部长及 OSTP 主任协商后选定的提案,将被指定为优先 AI 出口包,并通过优先访问本命令第 4 节指定的工具予以支持,符合适用法律。'
// }
// ]
// },
// {
// content: "动员联邦融资工具",
// slaver: [
// {
// content: '经济外交行动小组(EDAG),于 2024 年 6 月 21 日总统备忘录中成立,由国务卿主持,并与商务部长和美国贸易代表协商,并根据 2019 年《通过外交倡导美国企业法案》(公共法 116-94 J 部分第七章)第 708 条(CABDA)所述,应协调联邦融资工具的动员,以支持优先的人工智能出口方案。'
// },
// {
// content: '我将根据 CABDA α 第 708 (c) (3) 条授权小企业管理局局长和 OSTP 主任任命各自执行部门和机构的高级官员担任 EDAG 。'
// }
// ]
// }
]);
const
contentList
=
ref
([]);
const
ALPHABET
=
[
"a"
,
"b"
,
"c"
,
"d"
,
"e"
,
"f"
,
"g"
,
"h"
,
"i"
,
"j"
,
"k"
,
"l"
,
"m"
,
"n"
,
"o"
,
"p"
,
"q"
,
"r"
,
"s"
,
"t"
,
"u"
,
"v"
,
"w"
,
"x"
,
"y"
,
"z"
];
const
onMainContentData
=
async
()
=>
{
try
{
...
...
@@ -257,7 +195,7 @@ const onMainContentData = async () => {
console
.
log
(
"主要指令"
,
res
);
if
(
res
&&
res
.
code
===
200
)
{
contentList
.
value
=
res
.
data
||
[];
contentList
.
value
.
forEach
((
item
,
index
)
=>
{
item
.
content
=
`(
${
simple
NumToChinese
(
index
+
1
)}
)
${
item
.
content
}
`
})
contentList
.
value
.
forEach
((
item
,
index
)
=>
{
item
.
content
=
`(
${
on
NumToChinese
(
index
+
1
)}
)
${
item
.
content
}
`
})
if
(
keyword
)
{
let
word
=
keyword
.
replace
(
/
[
.*+?^${}()|[
\]\\]
/g
,
"
\\
$&"
);
contentList
.
value
.
forEach
(
item
=>
{
onHighlight
(
word
,
item
)
})
...
...
@@ -279,30 +217,6 @@ const onHighlight = (word, row) => {
row
.
slaver
.
forEach
(
item
=>
{
onHighlight
(
word
,
item
)
})
}
}
// 数字转中文(支持 0-99 整数)
const
simpleNumToChinese
=
(
num
)
=>
{
// 1. 基础校验:只处理 0-99 的整数
if
(
!
Number
.
isInteger
(
num
)
||
num
<
0
||
num
>
99
)
return
'100'
;
// 2. 定义基础字符
const
singleChars
=
[
'零'
,
'一'
,
'二'
,
'三'
,
'四'
,
'五'
,
'六'
,
'七'
,
'八'
,
'九'
];
const
tenChar
=
'十'
;
// 3. 核心转换逻辑
if
(
num
<
10
)
{
// 0-9 直接返回对应字符
return
singleChars
[
num
];
}
else
if
(
num
===
10
)
{
// 10 特殊处理
return
tenChar
;
}
else
if
(
num
<
20
)
{
// 11-19:十 + 个位(如十一、十九)
return
tenChar
+
singleChars
[
num
-
10
];
}
else
{
// 20-99:十位 + 十 + 个位(个位为0则省略,如二十、二十九)
const
ten
=
Math
.
floor
(
num
/
10
);
// 十位数字
const
unit
=
num
%
10
;
// 个位数字
return
singleChars
[
ten
]
+
tenChar
+
(
unit
===
0
?
''
:
singleChars
[
unit
]);
}
}
// 思维导图
const
isTreeDialog
=
ref
(
false
);
...
...
src/views/marketAccessRestrictions/com/Level1List.vue
0 → 100644
浏览文件 @
86617244
<
template
>
<div
class=
"data-list"
>
<div
class=
"data-item"
v-for=
"(item, index) in props.list"
:key=
"index"
>
<div
class=
"item-head"
>
<div
class=
"item-name"
>
{{
`(${onNumToChinese(Number(index)+1)
}
). ${item.title
}
`
}}
<
/div
>
<
div
class
=
"button-box"
@
click
=
"onNavigateTo()"
>
<
div
class
=
"button-icon"
>
<
img
src
=
"../assets/icons/open.png"
alt
=
""
/>
<
/div
>
<
div
class
=
"button-text"
>
跳转原文
<
/div
>
<
/div
>
<
/div
>
<
Level2List
:
list
=
"item.data"
><
/Level2List
>
<
/div
>
<
/div
>
<
/template
>
<
script
setup
lang
=
"ts"
name
=
"Level2List"
>
import
router
from
"@/router"
;
import
{
useRoute
}
from
"vue-router"
;
import
{
onNumToChinese
}
from
"@/views/marketAccessRestrictions/utils/index"
import
Level2List
from
"@/views/marketAccessRestrictions/com/Level2List.vue"
;
const
route
=
useRoute
();
const
props
=
defineProps
({
list
:
{
type
:
Array
as
any
,
default
:
()
=>
([])
}
,
}
)
const
onNavigateTo
=
()
=>
{
const
page
=
router
.
resolve
({
name
:
"MarketSingleReportOriginal"
,
query
:
{
...
route
.
query
}
}
);
window
.
open
(
page
.
href
,
"_blank"
);
}
<
/script
>
<
style
scoped
lang
=
"scss"
>
.
data
-
list
{
margin
-
bottom
:
16
px
;
border
-
top
:
1
px
solid
rgba
(
234
,
236
,
238
,
1
);
.
data
-
item
{
.
item
-
head
{
padding
:
0
20
px
;
height
:
48
px
;
border
-
bottom
:
1
px
solid
rgba
(
234
,
236
,
238
,
1
);
background
:
rgba
(
247
,
248
,
249
,
1
);
display
:
flex
;
align
-
items
:
center
;
.
item
-
name
{
width
:
20
px
;
flex
:
auto
;
font
-
family
:
Source
Han
Sans
CN
;
font
-
size
:
18
px
;
font
-
weight
:
bold
;
line
-
height
:
30
px
;
color
:
var
(
--
text
-
primary
-
80
-
color
);
}
.
button
-
box
{
display
:
flex
;
align
-
items
:
center
;
margin
-
left
:
50
px
;
cursor
:
pointer
;
.
button
-
icon
{
width
:
16
px
;
height
:
16
px
;
font
-
size
:
0
;
margin
-
right
:
4
px
;
img
{
width
:
100
%
;
height
:
100
%
;
}
}
.
button
-
text
{
color
:
var
(
--
color
-
primary
-
100
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
12
px
;
font
-
weight
:
400
;
line
-
height
:
12
px
;
}
}
}
}
}
<
/style>
\ No newline at end of file
src/views/marketAccessRestrictions/com/Level2List.vue
0 → 100644
浏览文件 @
86617244
<
template
>
<div
class=
"view-box"
>
<div
class=
"item-info"
v-for=
"(text, num) in props.list"
:key=
"num"
>
<div
class=
"item-num"
>
{{
Number
(
num
)
+
1
}}
.
</div>
<div
class=
"text-align-justify"
>
{{
text
}}
</div>
</div>
</div>
</
template
>
<
script
setup
lang=
"ts"
name=
"Level2List"
>
const
props
=
defineProps
({
list
:
{
type
:
Array
as
any
,
default
:
()
=>
([])
}
})
</
script
>
<
style
scoped
lang=
"scss"
>
.view-box
{
.item-info
{
padding
:
12px
20px
12px
50px
;
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
Source
Han
Sans
CN
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
30px
;
letter-spacing
:
0px
;
border-bottom
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
position
:
relative
;
.item-num
{
position
:
absolute
;
left
:
26px
;
top
:
12px
;
}
}
}
</
style
>
\ No newline at end of file
src/views/marketAccessRestrictions/com/SurveyConclusion.vue
浏览文件 @
86617244
...
...
@@ -2,29 +2,15 @@
<AnalysisBox
:title=
"title"
:showAllBtn=
"false"
height=
"auto"
>
<el-empty
v-if=
"!props.listData?.length"
description=
"暂无数据"
:image-size=
"200"
/>
<div
v-else
class=
"box-main"
>
<div
class=
"data-list"
>
<div
class=
"data-item"
v-for=
"(item, index) in props.listData"
:key=
"index"
>
<div
class=
"item-head"
>
<div
class=
"item-name"
>
{{
item
.
title
}}
</div>
<div
class=
"button-box"
>
<div
class=
"button-icon"
>
<img
src=
"../assets/icons/open.png"
alt=
""
/>
</div>
<div
class=
"button-text"
>
跳转原文
</div>
</div>
</div>
<div
class=
"item-down"
>
<div
class=
"item-text"
v-for=
"(text, num) in item.data"
:key=
"num"
>
{{
text
}}
</div>
</div>
</div>
</div>
<AiTips
:tips=
"tips"
></AiTips>
<Level1List
:list=
"props.listData"
></Level1List>
<!--
<AiTips
:tips=
"tips"
></AiTips>
-->
</div>
</AnalysisBox>
</
template
>
<
script
setup
lang=
"ts"
name=
"SurveyConclusion"
>
import
AiTips
from
"@/views/marketAccessRestrictions/com/AiTips.vue"
;
import
Level1List
from
"@/views/marketAccessRestrictions/com/Level1List.vue"
;
const
props
=
defineProps
({
listData
:
{
...
...
@@ -46,62 +32,5 @@ const props = defineProps({
<
style
scoped
lang=
"scss"
>
.box-main
{
padding
:
0
22px
20px
;
.data-list
{
margin-bottom
:
16px
;
border-top
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
.data-item
{
.item-head
{
padding
:
0
20px
;
height
:
48px
;
border-bottom
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
background
:
rgba
(
247
,
248
,
249
,
1
);
display
:
flex
;
align-items
:
center
;
.item-name
{
width
:
20px
;
flex
:
auto
;
font-family
:
Source
Han
Sans
CN
;
font-size
:
18px
;
font-weight
:
bold
;
line-height
:
30px
;
color
:
var
(
--
text-primary-80-color
);
}
.button-box
{
display
:
flex
;
align-items
:
center
;
margin-left
:
50px
;
.button-icon
{
width
:
16px
;
height
:
16px
;
font-size
:
0
;
margin-right
:
4px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.button-text
{
color
:
var
(
--
color-primary-100
);
font-family
:
Microsoft
YaHei
;
font-size
:
12px
;
font-weight
:
400
;
line-height
:
12px
;
}
}
}
.item-text
{
letter-spacing
:
1px
;
padding
:
12px
20px
12px
40px
;
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
Source
Han
Sans
CN
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
30px
;
letter-spacing
:
0px
;
text-align
:
justify
;
border-bottom
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
}
}
}
}
</
style
>
\ No newline at end of file
src/views/marketAccessRestrictions/marketAccessHome/com/CarouselItem232.vue
浏览文件 @
86617244
...
...
@@ -2,19 +2,19 @@
<div
class=
"box-text-box"
>
<div
class=
"box-text-item"
>
<div
class=
"box-text-left"
>
{{
"启动时间:"
}}
</div>
<div
class=
"box-text-right one-line-ellipsis"
>
{{
props
.
baseInfo
.
searchnum
}}
</div>
<div
class=
"box-text-right one-line-ellipsis"
>
{{
props
.
baseInfo
.
progressdate
}}
</div>
</div>
<div
class=
"box-text-item"
>
<div
class=
"box-text-left"
>
{{
"调查概括:"
}}
</div>
<div
class=
"box-text-right two-line-ellipsis"
>
{{
props
.
baseInfo
.
product
}}
</div>
<div
class=
"box-text-right two-line-ellipsis"
>
{{
props
.
baseInfo
.
investSummary
}}
</div>
</div>
<div
class=
"box-text-item"
>
<div
class=
"box-text-left"
>
{{
"调查阶段:"
}}
</div>
<div
class=
"box-text-right one-line-ellipsis"
>
{{
props
.
baseInfo
.
plaintiff
}}
</div>
<div
class=
"box-text-right one-line-ellipsis"
>
{{
props
.
baseInfo
.
investStage
}}
</div>
</div>
<div
class=
"box-text-item"
>
<div
class=
"box-text-left"
>
{{
"调查范围:"
}}
</div>
<div
class=
"box-text-right five-line-ellipsis"
>
{{
props
.
baseInfo
.
defendant
}}
</div>
<div
class=
"box-text-right five-line-ellipsis"
>
{{
props
.
baseInfo
.
investScope
}}
</div>
</div>
</div>
</
template
>
...
...
src/views/marketAccessRestrictions/marketAccessHome/com/CarouselItem301.vue
浏览文件 @
86617244
...
...
@@ -2,26 +2,25 @@
<div
class=
"box-blue-box"
>
<div
class=
"box-blue-name"
>
<div
class=
"box-blue-time"
>
{{
props
.
baseInfo
.
progressdate
}}
</div>
<div
class=
"box-blue-time"
>
{{
props
.
baseInfo
.
progressresult
}}
</div>
</div>
<div
class=
"box-blue-text one-line-ellipsis"
>
{{
props
.
baseInfo
.
progressdetails
}}
</div>
</div>
<div
class=
"box-text-box"
>
<div
class=
"box-text-item"
>
<div
class=
"box-text-left"
>
{{
"启动时间:"
}}
</div>
<div
class=
"box-text-right one-line-ellipsis"
>
{{
props
.
baseInfo
.
searchnum
}}
</div>
<div
class=
"box-text-right one-line-ellipsis"
>
{{
props
.
baseInfo
.
investDate
}}
</div>
</div>
<div
class=
"box-text-item"
>
<div
class=
"box-text-left"
>
{{
"调查对象:"
}}
</div>
<div
class=
"box-text-right one-line-ellipsis"
>
{{
props
.
baseInfo
.
produ
ct
}}
</div>
<div
class=
"box-text-right one-line-ellipsis"
>
{{
props
.
baseInfo
.
investSubje
ct
}}
</div>
</div>
<div
class=
"box-text-item"
>
<div
class=
"box-text-left"
>
{{
"调查状态:"
}}
</div>
<div
class=
"box-text-right one-line-ellipsis"
>
{{
props
.
baseInfo
.
plaintiff
}}
</div>
<div
class=
"box-text-right one-line-ellipsis"
>
{{
props
.
baseInfo
.
investStatus
}}
</div>
</div>
<div
class=
"box-text-item"
>
<div
class=
"box-text-left"
>
{{
"请愿方:"
}}
</div>
<div
class=
"box-text-right three-line-ellipsis"
>
{{
props
.
baseInfo
.
p
roduct
}}
</div>
<div
class=
"box-text-right three-line-ellipsis"
>
{{
props
.
baseInfo
.
p
etitioner
}}
</div>
</div>
</div>
</
template
>
...
...
src/views/marketAccessRestrictions/marketAccessHome/index.vue
浏览文件 @
86617244
...
...
@@ -11,7 +11,7 @@
<div
class=
"date-icon"
>
<img
:src=
"tipsTcon"
alt=
""
>
</div>
<div
class=
"date-text"
>
近期美国各联邦政府机构市场准入调查数量汇总
</div>
<div
class=
"date-text"
>
近期美国各联邦政府机构市场准入
限制
调查数量汇总
</div>
<TimeTabPane
@
time-click=
"handleGetStatSort"
activeTime=
"近一年"
/>
</div>
<div
class=
"home-main-header-card-box"
>
...
...
@@ -26,7 +26,7 @@
{{
item
.
sortDescription
}}
<
/div
>
<
/div
>
<
div
class
=
"item-dot"
>+
{{
"999"
}}
<
/div
>
<
div
class
=
"item-dot"
v
-
if
=
"item.addInvestCount"
>+
{{
item
.
addInvestCount
}}
<
/div
>
<
/div
>
<
/div
>
<
/div
>
...
...
@@ -74,7 +74,7 @@
<
DivideHeader
id
=
"position3"
class
=
"divide-header"
:
titleText
=
"'数据总览'"
><
/DivideHeader
>
<
div
class
=
"center-footer"
>
<
div
class
=
"box5"
>
<
OverviewNormalBox
title
=
"
调查数量
"
>
<
OverviewNormalBox
title
=
"
数量变化趋势
"
>
<
template
#
header
-
icon
>
<
img
style
=
"width: 100%; height: 100%;"
src
=
"./assets/icons/icon2.svg"
alt
=
""
/>
<
/template
>
...
...
@@ -89,14 +89,18 @@
<
div
class
=
"box-echart-main"
>
<
div
class
=
"box-echart-content"
>
<
el
-
empty
v
-
if
=
"!box5ChartData.title.length"
description
=
"暂无数据"
style
=
"padding: 100px 0 0;"
:
image
-
size
=
"100"
/>
<
div
v
-
if
=
"box5ChartData.title.length"
style
=
"width: 100%; height: 100%;"
id
=
"box5Chart"
><
/div
>
<
div
v
-
if
=
"box5ChartData.title.length"
style
=
"width: 100%; height: 100%;"
ref
=
"box5Ref"
><
/div
>
<
/div
>
<
TipTab
text
=
"美对华发起调查案件数量变化趋势,数据来源:美国国际贸易委员会、商务部、贸易代表办公室官网"
style
=
"margin-top: 16px;"
/>
<
div
class
=
"ai-pane"
>
<
AiButton
/>
<
AiPane
:
aiContent
=
"aiContent.content5"
/>
<
/div
>
<
TipTab
style
=
"margin-top: 6px;"
/>
<
/div
>
<
/OverviewNormalBox
>
<
/div
>
<
div
class
=
"box6"
>
<
OverviewNormalBox
title
=
"
制裁领域分布
"
width
=
"521px"
>
<
OverviewNormalBox
title
=
"
领域分布情况
"
width
=
"521px"
>
<
template
#
header
-
icon
>
<
img
style
=
"width: 100%; height: 100%;"
src
=
"./assets/icons/icon3.svg"
alt
=
""
/>
<
/template
>
...
...
@@ -112,14 +116,18 @@
<
el
-
empty
v
-
if
=
"!box6Data.title.length"
description
=
"暂无数据"
style
=
"padding: 100px 0 0;"
:
image
-
size
=
"100"
/>
<
div
v
-
if
=
"box6Data.title.length"
style
=
"width: 100%; height: 100%;"
id
=
"box6Chart"
><
/div
>
<
/div
>
<
TipTab
style
=
"margin-top: 6px;"
/>
<
TipTab
text
=
"美对华发起调查案件领域分布情况,数据来源:美国国际贸易委员会、商务部、贸易代表办公室官网"
ellipsis
style
=
"padding-right: 50px;"
/>
<
div
class
=
"ai-pane"
>
<
AiButton
/>
<
AiPane
:
aiContent
=
"aiContent.content6"
/>
<
/div
>
<
/div
>
<
/OverviewNormalBox
>
<
/div
>
<
/div
>
<
div
class
=
"center-footer1"
>
<
div
class
=
"box7"
>
<
OverviewNormalBox
title
=
"
受调查国家分布
"
width
=
"1064px"
>
<
OverviewNormalBox
title
=
"
国家分布情况
"
width
=
"1064px"
>
<
template
#
header
-
icon
>
<
img
style
=
"width: 100%; height: 100%;"
src
=
"./assets/icons/icon4.svg"
alt
=
""
/>
<
/template
>
...
...
@@ -140,12 +148,16 @@
<
el
-
empty
v
-
if
=
"!box7Data.data.length"
description
=
"暂无数据"
style
=
"padding: 100px 0 0;"
:
image
-
size
=
"100"
/>
<
div
v
-
if
=
"box7Data.data.length"
style
=
"width: 100%; height: 100%;"
id
=
"box7Chart"
><
/div
>
<
/div
>
<
TipTab
style
=
"margin-top: 6px;"
/>
<
TipTab
:
text
=
"`美发起调查案件的被调查国家分布情况,数据来源:${box7TipText
}
`"
style
=
"margin-top: 10px;"
/>
<
div
class
=
"ai-pane"
>
<
AiButton
/>
<
AiPane
:
aiContent
=
"aiContent.content7"
/>
<
/div
>
<
/div
>
<
/OverviewNormalBox
>
<
/div
>
<
div
class
=
"box8"
>
<
OverviewNormalBox
title
=
"
调查结果分布
"
width
=
"521px"
>
<
OverviewNormalBox
title
=
"
结果分布情况
"
width
=
"521px"
>
<
template
#
header
-
icon
>
<
img
style
=
"width: 100%; height: 100%"
src
=
"./assets/icons/icon5.svg"
alt
=
""
/>
<
/template
>
...
...
@@ -159,9 +171,13 @@
<
div
class
=
"box-echart-main"
>
<
div
class
=
"box-echart-content"
>
<
el
-
empty
v
-
if
=
"!box8Data.length"
description
=
"暂无数据"
style
=
"padding: 100px 0 0;"
:
image
-
size
=
"100"
/>
<
div
v
-
if
=
"box8Data.length"
style
=
"width: 100%; height: 100%;"
id
=
"box8Chart"
><
/div
>
<
div
v
-
if
=
"box8Data.length"
style
=
"width: 100%; height: 100%;"
ref
=
"box8Ref"
><
/div
>
<
/div
>
<
TipTab
:
text
=
"`美发起调查案件的被调查国家分布情况,数据来源:${box8TipText
}
`"
ellipsis
style
=
"padding-right: 50px;"
/>
<
div
class
=
"ai-pane"
>
<
AiButton
/>
<
AiPane
:
aiContent
=
"aiContent.content8"
/>
<
/div
>
<
TipTab
style
=
"margin-top: 6px;"
/>
<
/div
>
<
/OverviewNormalBox
>
<
/div
>
...
...
@@ -181,7 +197,6 @@
<
/template
>
<
el
-
option
v
-
for
=
"item in releaseTimeList"
:
key
=
"item.value"
:
label
=
"item.label"
:
value
=
"item.value"
/>
<
/el-select
>
<
/div
>
<
/div
>
<
div
class
=
"home-main-footer-main"
>
...
...
@@ -262,7 +277,7 @@
<
/template
>
<
script
setup
>
import
{
onMounted
,
ref
,
nextTick
,
reactive
}
from
"vue"
;
import
{
onMounted
,
ref
,
nextTick
,
reactive
,
computed
}
from
"vue"
;
import
LeftBtn
from
"@/components/base/pageBtn/LeftBtn.vue"
;
import
RightBtn
from
"@/components/base/pageBtn/RightBtn.vue"
;
...
...
@@ -279,13 +294,16 @@ import CarouselItem301 from '@/views/marketAccessRestrictions/marketAccessHome/c
import
CarouselItem232
from
'@/views/marketAccessRestrictions/marketAccessHome/com/CarouselItem232.vue'
;
import
setChart
from
"@/utils/setChart"
;
import
{
getDateBefore
,
getAIReport
,
getNearYearList
}
from
"@/views/marketAccessRestrictions/utils/index.ts"
;
import
router
from
"@/router"
;
import
{
navigateToViewRiskSignal
}
from
"@/utils/riskSignalOverviewNavigate"
;
import
getMultiLineChart
from
"./utils/multi
LineChart"
;
import
getPieChart
from
"./utils/piechart
"
;
import
createLineChart
from
"@/views/marketAccessRestrictions/utils/base
LineChart"
;
import
createPieChart
from
"@/views/marketAccessRestrictions/utils/basePiechart.js
"
;
import
getRadarChart
from
"./utils/radarChart"
;
import
getBarChart
from
"./utils/barChart1"
;
import
AiButton
from
'@/components/base/Ai/AiButton/index.vue'
;
import
AiPane
from
'@/components/base/Ai/AiPane/index.vue'
;
import
{
getPersonSummaryInfo
}
from
"@/api/common/index"
;
import
{
...
...
@@ -307,6 +325,17 @@ import tipsTcon from "./assets/icons/tips-icon.png";
const
getCardClass
=
(
code
)
=>
[
'theme-card'
,
`theme-${code
}
`
]
// 获取AI智能报告
const
aiContent
=
reactive
({
content5
:
"正在生成..."
,
content6
:
"正在生成..."
,
content7
:
"正在生成..."
,
content8
:
"正在生成..."
,
}
)
const
onAIReport
=
(
data
,
key
)
=>
{
getAIReport
(
data
).
then
(
res
=>
{
aiContent
[
key
]
=
res
}
)
}
const
handleToPosi
=
id
=>
{
const
element
=
document
.
getElementById
(
id
);
if
(
element
&&
containerRef
.
value
)
{
...
...
@@ -334,9 +363,12 @@ let containerRef = ref(null);
// 首页分类
const
sortInfo
=
ref
([]);
const
handleGetStatSort
=
async
(
event
)
=>
{
console
.
log
(
'周期筛选'
,
event
)
let
day
=
365
if
(
event
?.
time
===
'近一周'
)
day
=
7
if
(
event
?.
time
===
'近一月'
)
day
=
30
if
(
event
?.
time
===
'近一年'
)
day
=
365
try
{
const
res
=
await
getStatSort
();
const
res
=
await
getStatSort
(
{
startDate
:
getDateBefore
(
day
)
}
);
console
.
log
(
"首页分类"
,
res
);
// sortInfo.value = res.data.sort((a, b) => a.sortCode - b.sortCode);
sortInfo
.
value
=
res
.
data
;
...
...
@@ -543,7 +575,7 @@ function transformAllData(originalData) {
// 4. 构建最终结果
return
{
title
:
allYears
,
data
:
categoryData
list
:
categoryData
}
;
}
...
...
@@ -599,38 +631,55 @@ function transformAllData1(originalData) {
// 4. 构建最终结果
return
{
title
:
allDates
,
data
:
categoryData
list
:
categoryData
}
;
}
const
box5ChartData
=
ref
({
title
:
[],
data
:
[
list
:
[
{
name
:
"337调查"
,
value
:
[]
}
,
{
name
:
"301调查"
,
value
:
[]
}
,
{
name
:
"232调查"
,
value
:
[]
}
]
}
);
const
box5Ref
=
ref
(
null
)
const
box5Active
=
ref
(
1
);
const
hadleGetStatNum
=
async
(
event
)
=>
{
if
(
event
)
box5Active
.
value
=
event
;
try
{
let
byYorM
=
box5Active
.
value
const
res
=
await
getStatNum
({
byYorM
}
);
console
.
log
(
"
调查数量
"
,
res
);
console
.
log
(
"
数量变化趋势
"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
if
(
byYorM
===
1
)
{
box5ChartData
.
value
=
transformAllData1
(
res
.
data
);
}
else
{
box5ChartData
.
value
=
transformAllData
(
res
.
data
);
}
onAIReport
({
type
:
"折线图"
,
name
:
"数量变化趋势"
,
data
:
res
.
data
}
,
"content5"
)
}
else
{
box5ChartData
.
value
.
title
=
[];
box5ChartData
.
value
.
list
=
[
{
name
:
"337调查"
,
value
:
[]
}
,
{
name
:
"301调查"
,
value
:
[]
}
,
{
name
:
"232调查"
,
value
:
[]
}
]
aiContent
.
content5
=
""
;
}
}
catch
(
error
)
{
}
let
box5Chart
=
getMultiLineChart
(
box5ChartData
.
value
);
nextTick
(()
=>
{
setChart
(
box5Chart
,
"box5Chart"
)
}
)
}
catch
(
error
)
{
box5ChartData
.
value
.
title
=
[];
box5ChartData
.
value
.
list
=
[
{
name
:
"337调查"
,
value
:
[]
}
,
{
name
:
"301调查"
,
value
:
[]
}
,
{
name
:
"232调查"
,
value
:
[]
}
]
aiContent
.
content5
=
""
;
}
nextTick
(()
=>
{
createLineChart
(
box5Ref
,
box5ChartData
.
value
)
}
)
}
;
//
制裁领域分布
//
领域分布情况
const
box6SelectedYear
=
ref
(
"2025"
);
const
handleChangeBox6Year
=
()
=>
{
handleBox6
();
...
...
@@ -650,7 +699,7 @@ const handleGetStatArea = async () => {
}
;
try
{
const
res
=
await
getStatArea
(
params
);
console
.
log
(
"
制裁领域分布
"
,
res
);
console
.
log
(
"
领域分布情况
"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
const
arr
=
res
.
data
.
map
(
item
=>
{
return
item
.
areaname
;
...
...
@@ -707,6 +756,17 @@ const handleGetStatArea = async () => {
}
);
box6Data
.
value
.
maxNum
=
Math
.
max
(...
numArr
);
onAIReport
({
type
:
"雷达图"
,
name
:
"领域分布情况"
,
data
:
res
.
data
}
,
"content6"
)
}
else
{
box6Data
.
value
.
title
=
[];
box6Data
.
value
.
data
=
[
{
name
:
"337调查"
,
value
:
[]
}
,
{
name
:
"232调查"
,
value
:
[]
}
,
{
name
:
"301调查"
,
value
:
[]
}
];
box6Data
.
value
.
maxNum
=
0
;
aiContent
.
content6
=
""
;
}
}
catch
(
error
)
{
}
}
;
...
...
@@ -716,30 +776,28 @@ const handleBox6 = async () => {
setChart
(
box6Chart
,
"box6Chart"
);
}
;
//
受调查国家分布
//
国家分布情况
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"
}
,
]);
const
box7YearList
=
getNearYearList
();
const
box7SelectedYear
=
ref
(
"2025"
);
const
box7Data
=
reactive
({
title
:
[],
data
:
[]
}
);
const
box7TipText
=
computed
(()
=>
{
if
(
box7SelectedSurvey
.
value
===
"337"
)
return
"美国国际贸易委员会官网"
if
(
box7SelectedSurvey
.
value
===
"232"
)
return
"美国商务部官网"
if
(
box7SelectedSurvey
.
value
===
"301"
)
return
"美国贸易代表办公室官网"
return
""
}
)
const
handleGetBox7Data
=
async
()
=>
{
const
params
=
{
sortCode
:
box7SelectedSurvey
.
value
,
year
:
box7SelectedYear
.
value
year
s
:
box7SelectedYear
.
value
}
;
try
{
const
res
=
await
getSearchCountry
(
params
);
console
.
log
(
"
受调查国家分布
"
,
res
);
console
.
log
(
"
国家分布情况
"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
box7Data
.
title
=
res
.
data
.
map
(
item
=>
{
return
{
...
...
@@ -750,9 +808,16 @@ const handleGetBox7Data = async () => {
box7Data
.
data
=
res
.
data
.
map
(
item
=>
{
return
item
.
NUM
;
}
);
onAIReport
({
type
:
"柱状图"
,
name
:
"国家分布情况"
,
data
:
res
.
data
}
,
"content7"
)
}
else
{
box7Data
.
title
=
[];
box7Data
.
data
=
[];
aiContent
.
content7
=
""
;
}
}
catch
(
error
)
{
console
.
error
(
"受调查国家分布error"
,
error
);
box7Data
.
title
=
[];
box7Data
.
data
=
[];
aiContent
.
content7
=
""
;
}
}
;
...
...
@@ -767,23 +832,32 @@ const box8SurveyList = ref([
{
label
:
"301调查"
,
value
:
"301"
}
,
{
label
:
"232调查"
,
value
:
"232"
}
,
]);
//
调查结果分布
//
结果分布情况
const
box8SelectedSurvey
=
ref
(
"337"
);
const
box8Data
=
ref
([]);
const
box8Ref
=
ref
(
null
);
const
box8TipText
=
computed
(()
=>
{
if
(
box8SelectedSurvey
.
value
===
"337"
)
return
"美国国际贸易委员会官网"
if
(
box8SelectedSurvey
.
value
===
"232"
)
return
"美国商务部官网"
if
(
box8SelectedSurvey
.
value
===
"301"
)
return
"美国贸易代表办公室官网"
return
""
}
)
const
handleGetBox8Data
=
async
()
=>
{
try
{
const
res
=
await
getSearchResult
({
sortCode
:
box8SelectedSurvey
.
value
}
);
console
.
log
(
"
调查结果分布
"
,
res
);
console
.
log
(
"
结果分布情况
"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
box8Data
.
value
=
res
.
data
.
map
(
item
=>
({
name
:
item
.
RESULTNAME
,
value
:
item
.
RESULTNUM
}
))
onAIReport
({
type
:
"环形图"
,
name
:
"结果分布情况"
,
data
:
res
.
data
}
,
"content8"
)
}
else
{
box8Data
.
value
=
[]
aiContent
.
content8
=
""
;
}
}
catch
(
error
)
{
box8Data
.
value
=
[]
aiContent
.
content8
=
""
;
}
const
box8Chart
=
getPieChart
(
box8Data
.
value
);
nextTick
(()
=>
{
setChart
(
box8Chart
,
"box8Chart"
)
}
)
nextTick
(()
=>
{
createPieChart
(
box8Ref
,
box8Data
.
value
,
{
labelType
:
1
}
)
}
)
}
;
// 资源库
...
...
@@ -975,12 +1049,40 @@ onMounted(async () => {
height
:
100
%
;
display
:
flex
;
flex
-
direction
:
column
;
padding
:
8
px
22
px
20
px
;
padding
:
12
px
30
px
20
px
;
position
:
relative
;
.
box
-
echart
-
content
{
width
:
100
%
;
height
:
20
px
;
flex
:
auto
;
}
.
ai
-
pane
{
position
:
absolute
;
right
:
0
px
;
bottom
:
15
px
;
z
-
index
:
2
;
:
deep
(.
ai
-
pane
-
wrapper
)
{
display
:
none
;
}
:
deep
(.
ai
-
button
-
wrapper
)
{
display
:
flex
;
}
&
:
hover
{
width
:
100
%
;
bottom
:
0
px
;
:
deep
(.
ai
-
pane
-
wrapper
)
{
display
:
block
;
}
:
deep
(.
ai
-
button
-
wrapper
)
{
display
:
none
;
}
}
}
}
.
home
-
wrapper
{
...
...
src/views/marketAccessRestrictions/marketAccessHome/utils/barChart1.js
浏览文件 @
86617244
import
{
symbolCircle
}
from
"d3"
;
import
*
as
echarts
from
"echarts"
;
const
getBarChart
=
(
nameList
,
valueList
)
=>
{
...
...
@@ -15,27 +14,45 @@ const getBarChart = (nameList, valueList) => {
},
yAxis
:
{
type
:
'value'
,
name
:
"项"
,
nameLocation
:
'end'
,
nameGap
:
12
,
nameTextStyle
:
{
color
:
'#666'
,
fontSize
:
14
,
fontWeight
:
400
,
padding
:
[
0
,
0
,
6
,
-
26
]
},
axisLabel
:
{
formatter
:
'{value}'
,
color
:
'#666'
,
fontSize
:
14
,
fontWeight
:
400
},
splitLine
:
{
show
:
false
show
:
true
,
lineStyle
:
{
color
:
'#e7f3ff'
,
type
:
'dashed'
,
}
},
show
:
false
},
xAxis
:
{
type
:
'category'
,
data
:
nameList
.
map
(
item
=>
{
return
item
.
name
}),
splitLine
:
{
show
:
false
},
axisTick
:
{
show
:
false
},
data
:
nameList
.
map
(
item
=>
item
.
name
),
axisLine
:
{
show
:
false
show
:
true
,
lineStyle
:
{
color
:
'#e7f3ff'
,
},
},
axisLabel
:
{
show
:
true
show
:
true
,
textStyle
:
{
color
:
'rgba(95, 101, 108, 1)'
,
fontFamily
:
'Microsoft YaHei'
,
fontsize
:
14
,
}
}
},
series
:
[{
...
...
@@ -57,8 +74,7 @@ const getBarChart = (nameList, valueList) => {
barWidth
:
20
,
markPoint
:
{
symbol
:
'circle'
,
symbolSize
:
20
,
symbolSize
:
0
,
data
:
(
function
()
{
const
data
=
[];
nameList
.
forEach
((
item
,
index
)
=>
{
...
...
@@ -67,9 +83,7 @@ const getBarChart = (nameList, valueList) => {
xAxis
:
index
,
yAxis
:
valueList
[
index
],
symbol
:
`image://
${
item
.
img
}
`
,
// symbolSize: [20, 20],
symbolSize
:
20
,
// symbolOffset: [0, 20],
symbolCircle
:
20
,
itemStyle
:
{
borderRadius
:
'50%'
,
...
...
src/views/marketAccessRestrictions/marketAccessLayout/case/232/index.vue
浏览文件 @
86617244
...
...
@@ -11,22 +11,24 @@
<el-option
label=
"调查中"
value=
"1"
/>
<el-option
label=
"调查结束"
value=
"0"
/>
</el-select>
<el-select
v-model=
"filterParty"
placeholder=
"全部原告/被告"
class=
"filter-select"
clearable
>
<
!--
<
el-select
v-model=
"filterParty"
placeholder=
"全部原告/被告"
class=
"filter-select"
clearable
>
<el-option
label=
"全部原告/被告"
value=
""
/>
</el-select>
<el-select
v-model=
"filterReason"
placeholder=
"全部原因"
class=
"filter-select"
clearable
>
<el-option
label=
"全部原因"
value=
""
/>
</el-select>
</el-select>
-->
</div>
</div>
<div
class=
"select-box"
>
<div
class=
"paixu-btn"
@
click=
"handleSwithSort"
>
<div
class=
"text"
>
{{
"发布时间"
}}
</div>
<div
class=
"icon2"
>
<img
v-if=
"isSort"
src=
"@/assets/icons/shengxu2.png"
alt=
""
/>
<img
v-else
src=
"@/assets/icons/jiangxu2.png"
alt=
""
/>
</div>
</div>
<el-select
v-model=
"isSort"
placeholder=
"发布时间"
style=
"width: 166px"
>
<template
#
prefix
>
<div
style=
"display: flex; align-items: center; height: 100%"
>
<img
src=
"@/assets/icons/jiangxu1.png"
style=
"width: 14px; height: 14px"
/>
</div>
</
template
>
<el-option
label=
"按发布时间降序"
value=
"desc"
/>
<el-option
label=
"按发布时间升序"
value=
"asc"
/>
</el-select>
</div>
</div>
<div
class=
"wrapper-main"
>
...
...
@@ -95,11 +97,7 @@ const searchText = ref("");
const
filterStage
=
ref
(
""
);
const
filterParty
=
ref
(
""
);
const
filterReason
=
ref
(
""
);
const
isSort
=
ref
(
false
);
// false 降序
const
handleSwithSort
=
()
=>
{
isSort
.
value
=
!
isSort
.
value
;
}
;
const
isSort
=
ref
(
'desc'
);
// 降序
// 科技领域过滤
const
surveyAreaList
=
ref
([]);
...
...
@@ -166,20 +164,17 @@ const handleFetchSurveyList = async () => {
publishYear
:
checkedYearList
.
value
.
join
(
','
)
||
null
,
Area
:
checkedAreaList
.
value
.
join
(
','
)
||
null
,
caseStatus
:
filterStage
.
value
,
keywords
:
searchText
.
value
,
keywords
:
searchText
.
value
||
null
,
sortField
:
"date"
,
sortOrder
:
isSort
.
value
?
"asc"
:
"desc"
sortOrder
:
isSort
.
value
};
const
res
=
await
getSurveyList
(
params
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
surveyInfoList
.
value
=
res
.
data
.
content
;
totalDiscussNum
.
value
=
res
.
data
.
totalElements
||
0
;
}
}
catch
(
error
)
{
console
.
error
(
"获取调查列表失败"
,
error
);
}
finally
{
listLoading
.
value
=
false
;
}
}
catch
(
error
)
{}
listLoading
.
value
=
false
;
};
const
handleCurrentChange
=
val
=>
{
...
...
@@ -241,30 +236,6 @@ onMounted(async () => {
}
}
}
.
select
-
box
{
.
paixu
-
btn
{
display
:
flex
;
align
-
items
:
center
;
gap
:
8
px
;
height
:
32
px
;
border
:
1
px
solid
#
e6e7e8
;
border
-
radius
:
4
px
;
background
:
#
fff
;
cursor
:
pointer
;
padding
:
0
12
px
;
.
text
{
font
-
size
:
14
px
;
color
:
#
5
f656c
;
}
.
icon2
{
width
:
10
px
;
img
{
width
:
100
%
;
}
}
}
}
}
.wrapper-main
{
...
...
@@ -335,18 +306,26 @@ onMounted(async () => {
height
:
48px
;
display
:
flex
;
align-items
:
center
;
padding
:
0
20
px
;
.icon
{
width
:
22px
;
height
:
18px
;
margin-left
:
19px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.title
{
height
:
26px
;
margin-left
:
12px
;
color
:
var
(
--
color-main-active
);
font-family
:
Microsoft
YaHei
;
font-style
:
Bold
;
font-size
:
20px
;
font-weight
:
700
;
color
:
var
(
--
color
-
main
-
active
);
line-height
:
26px
;
letter-spacing
:
0px
;
text-align
:
left
;
}
}
...
...
src/views/marketAccessRestrictions/marketAccessLayout/case/301/index.vue
浏览文件 @
86617244
<
template
>
<div
class=
"case-wrapper"
>
<div
class=
"wrapper-header"
>
<div
class=
"search-box"
>
<el-input
v-model=
"searchText"
style=
"width: 360px; height: 32px"
placeholder=
"搜索调查案件"
@
keyup
.
enter=
"handleSearch"
:suffix-icon=
"Search"
></el-input>
<div
class=
"header-filters"
>
<div
class=
"search-box"
>
<el-input
v-model=
"searchText"
style=
"width: 360px; height: 32px"
placeholder=
"搜索调查案件"
@
keyup
.
enter=
"handleSearch"
:suffix-icon=
"Search"
></el-input>
</div>
</div>
<div
class=
"select-box"
>
<div
class=
"paixu-btn"
@
click=
"handleSwithSort"
>
<div
class=
"icon1"
>
<img
v-if=
"isSort"
src=
"@/assets/icons/shengxu1.png"
alt=
""
/>
<img
v-else
src=
"@/assets/icons/jiangxu1.png"
alt=
""
/>
</div>
<div
class=
"text"
>
{{
"发布时间"
}}
</div>
<div
class=
"icon2"
>
<img
v-if=
"isSort"
src=
"@/assets/icons/shengxu2.png"
alt=
""
/>
<img
v-else
src=
"@/assets/icons/jiangxu2.png"
alt=
""
/>
</div>
</div>
<el-select
v-model=
"isSort"
placeholder=
"发布时间"
style=
"width: 166px"
>
<template
#
prefix
>
<div
style=
"display: flex; align-items: center; height: 100%"
>
<img
src=
"@/assets/icons/jiangxu1.png"
style=
"width: 14px; height: 14px"
/>
</div>
</
template
>
<el-option
label=
"按发布时间降序"
value=
"desc"
/>
<el-option
label=
"按发布时间升序"
value=
"asc"
/>
</el-select>
</div>
</div>
<div
class=
"wrapper-main"
>
...
...
@@ -54,7 +54,7 @@
</div>
<SurveyHistory
v-loading=
"listLoading"
:surveyList=
"surveyInfoList"
></SurveyHistory>
<div
class=
"right-footer"
>
<div
class=
"footer-left"
>
{{
`共
${totalDiscussNum
}
项
`
}}
<
/div
>
<div
class=
"footer-left"
>
{{ `共
${totalDiscussNum}项调查
` }}
</div>
<div
class=
"footer-right"
>
<el-pagination
@
current-change=
"handleCurrentChange"
:pageSize=
"pageSize"
:current-page=
"currentPage"
background
layout=
"prev, pager, next"
:total=
"totalDiscussNum"
/>
</div>
...
...
@@ -70,10 +70,8 @@ import { Search } from "@element-plus/icons-vue";
import
{
getSearchAllArea
,
getSearchAllYear
,
getSurveyList
}
from
"@/api/marketAccessRestrictions"
;
import
SurveyHistory
from
"@/views/marketAccessRestrictions/com/SurveyHistory.vue"
const
isSort
=
ref
(
true
);
// true 升序 false 倒序
const
handleSwithSort
=
()
=>
{
isSort
.
value
=
!
isSort
.
value
;
}
;
const
searchText
=
ref
(
''
);
// 搜索文本
const
isSort
=
ref
(
'desc'
);
// 降序
// 科技领域过滤
const
surveyAreaList
=
ref
([]);
...
...
@@ -139,20 +137,17 @@ const handleFetchSurveyList = async () => {
sortCode
:
"301"
,
publishYear
:
checkedYearList
.
value
.
join
(
','
)
||
null
,
Area
:
checkedAreaList
.
value
.
join
(
','
)
||
null
,
// keywords: searchText.value
,
keywords
:
searchText
.
value
||
null
,
sortField
:
"date"
,
sortOrder
:
isSort
.
value
?
"asc"
:
"desc"
sortOrder
:
isSort
.
value
};
const
res
=
await
getSurveyList
(
params
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
surveyInfoList
.
value
=
res
.
data
.
content
;
totalDiscussNum
.
value
=
res
.
data
.
totalElements
||
0
;
}
}
catch
(
error
)
{
console
.
error
(
"获取调查列表失败"
,
error
);
}
finally
{
listLoading
.
value
=
false
;
}
}
catch
(
error
)
{}
listLoading
.
value
=
false
;
};
const
handleCurrentChange
=
(
val
)
=>
{
...
...
@@ -190,56 +185,24 @@ onMounted(async () => {
display
:
flex
;
margin-bottom
:
16px
;
justify-content
:
space-between
;
.
search
-
box
{
background
-
color
:
#
fff
;
border
:
1
px
solid
rgba
(
234
,
236
,
238
,
1
);
border
-
radius
:
4
px
;
}
.
select
-
box
{
height
:
32
px
;
box
-
sizing
:
border
-
box
;
.
paixu
-
btn
{
display
:
flex
;
width
:
120
px
;
height
:
32
px
;
box
-
sizing
:
border
-
box
;
border
:
1
px
solid
rgba
(
230
,
231
,
232
,
1
);
.header-filters
{
display
:
flex
;
gap
:
16px
;
align-items
:
center
;
.search-box
{
background-color
:
#fff
;
border
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
border-radius
:
4px
;
background
:
rgba
(
255
,
255
,
255
,
1
);
&
:
hover
{
background
:
var
(
--
color
-
bg
-
hover
);
}
cursor
:
pointer
;
.
icon1
{
width
:
11
px
;
height
:
14
px
;
margin
-
top
:
10
px
;
margin
-
left
:
9
px
;
img
{
width
:
100
%
;
height
:
100
%
;
}
}
.
text
{
height
:
19
px
;
color
:
rgba
(
95
,
101
,
108
,
1
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
14
px
;
font
-
weight
:
400
;
line
-
height
:
18
px
;
letter
-
spacing
:
0
px
;
text
-
align
:
left
;
margin
-
top
:
7
px
;
margin
-
left
:
9
px
;
}
.
icon2
{
width
:
10
px
;
height
:
5
px
;
margin
-
top
:
5
px
;
margin
-
left
:
13
px
;
img
{
width
:
100
%
;
height
:
100
%
;
}
.dropdown-filters
{
display
:
flex
;
gap
:
12px
;
.filter-select
{
width
:
140px
;
:deep
(
.el-input__wrapper
)
{
background-color
:
#fff
;
}
}
}
...
...
@@ -324,7 +287,7 @@ onMounted(async () => {
}
.title
{
height
:
26px
;
margin
-
left
:
1
9
px
;
margin-left
:
1
2
px
;
color
:
var
(
--
color-main-active
);
font-family
:
Microsoft
YaHei
;
font-style
:
Bold
;
...
...
src/views/marketAccessRestrictions/marketAccessLayout/case/337/index.vue
浏览文件 @
86617244
...
...
@@ -11,12 +11,12 @@
<el-option
label=
"调查中"
value=
"1"
/>
<el-option
label=
"调查结束"
value=
"0"
/>
</el-select>
<el-select
v-model=
"filterParty"
placeholder=
"全部原告/被告"
class=
"filter-select"
clearable
>
<
!--
<
el-select
v-model=
"filterParty"
placeholder=
"全部原告/被告"
class=
"filter-select"
clearable
>
<el-option
label=
"全部原告/被告"
value=
""
/>
</el-select>
<el-select
v-model=
"filterReason"
placeholder=
"全部原因"
class=
"filter-select"
clearable
>
<el-option
label=
"全部原因"
value=
""
/>
</el-select>
</el-select>
-->
</div>
</div>
<div
class=
"select-box"
>
...
...
@@ -26,7 +26,8 @@
<img
src=
"@/assets/icons/jiangxu1.png"
style=
"width: 14px; height: 14px"
/>
</div>
</
template
>
<el-option
v-for=
"item in releaseTimeList"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
<el-option
label=
"按发布时间降序"
value=
"desc"
/>
<el-option
label=
"按发布时间升序"
value=
"asc"
/>
</el-select>
</div>
</div>
...
...
@@ -99,19 +100,7 @@ const searchText = ref("");
const
filterStage
=
ref
(
""
);
const
filterParty
=
ref
(
""
);
const
filterReason
=
ref
(
""
);
const
isSort
=
ref
(
false
);
// false 降序
const
releaseTimeList
=
ref
([
{
label
:
"按发布时间倒序"
,
value
:
false
},
{
label
:
"按发布时间升序"
,
value
:
true
}
]);
const
isSort
=
ref
(
'desc'
);
// 降序
// 科技领域过滤
const
surveyAreaList
=
ref
([]);
...
...
@@ -203,18 +192,15 @@ const handleFetchSurveyList = async () => {
caseStatus
:
filterStage
.
value
||
null
,
keywords
:
searchText
.
value
||
null
,
sortField
:
"date"
,
sortOrder
:
isSort
.
value
?
"asc"
:
"desc"
sortOrder
:
isSort
.
value
};
const
res
=
await
getSurveyList
(
params
);
if
(
res
.
code
===
200
)
{
surveyInfoList
.
value
=
res
.
data
?.
content
||
[];
totalDiscussNum
.
value
=
res
.
data
?.
totalElements
||
0
;
}
}
catch
(
error
)
{
console
.
error
(
"获取调查列表失败"
,
error
);
}
finally
{
listLoading
.
value
=
false
;
}
}
catch
(
error
)
{}
listLoading
.
value
=
false
;
};
const
handleCurrentChange
=
val
=>
{
...
...
@@ -278,33 +264,6 @@ onMounted(async () => {
}
}
}
.select-box
{
.paixu-btn
{
display
:
flex
;
align-items
:
center
;
gap
:
8px
;
height
:
32px
;
border
:
1px
solid
#e6e7e8
;
border-radius
:
4px
;
background
:
#fff
;
cursor
:
pointer
;
padding
:
0
12px
;
.text
{
font-size
:
14px
;
color
:
#5f656c
;
}
.icon2
{
width
:
10px
;
img
{
width
:
100%
;
}
}
}
}
}
.wrapper-main
{
...
...
src/views/marketAccessRestrictions/marketAccessLayout/index.vue
浏览文件 @
86617244
...
...
@@ -19,8 +19,7 @@
<div
class=
"page-tabs"
>
<div
:class=
"['tab-item',
{'tab-active': activeName==item.name}]" v-for="(item, index) in tabList" :key="index" @click="handleClickBtn(item)">
<div
class=
"icon"
>
<img
:src=
"item.activeIcon"
alt=
""
v-if=
"activeName==item.name"
/>
<img
:src=
"item.icon"
alt=
""
v-else
/>
<img
:src=
"activeName==item.name ? item.activeIcon : item.icon"
alt=
""
/>
</div>
<div
class=
"text"
:class=
"
{ textActive: activeName==item.name }">
{{
item
.
name
}}
...
...
src/views/marketAccessRestrictions/marketAccessLayout/overview/232/index.vue
浏览文件 @
86617244
<
template
>
<div
class=
"wrap"
>
<div
class=
"top"
>
<div
class=
"
content-
top"
>
<div
class=
"item"
>
<div
class=
"item-left-box"
>
<div
class=
"item-left1"
>
{{
"总调查案件数"
}}
</div>
<div
class=
"item-left2"
>
{{
"1980-2025"
}}
</div>
</div>
<div
class=
"item-right"
>
{{
"452项"
}}
</div>
<div
class=
"item-right"
>
{{
`${totalCaseNum
}
项`
}}
<
/div
>
<
/div
>
<
div
class
=
"item"
>
<
div
class
=
"item-left"
>
{{
"仍在调查中的案件"
}}
<
/div
>
<div
class=
"item-right"
>
{{
"28项"
}}
</div>
<
div
class
=
"item-right"
>
{{
`${onCaseNum
}
项`
}}
<
/div
>
<
/div
>
<
div
class
=
"item"
>
<div
class=
"item-left"
>
{{
"
涉及中企数量
"
}}
</div>
<div
class=
"item-right"
>
{{
"326家"
}}
</div>
<
div
class
=
"item-left"
>
{{
"
已征收关税的案件
"
}}
<
/div
>
<
div
class
=
"item-right"
>
{{
`${isTariffNum
}
项`
}}
<
/div
>
<
/div
>
<
div
class
=
"item"
>
<div
class=
"item-left"
>
{{
"
胜诉/和解率
"
}}
</div>
<div
class=
"item-right"
>
{{
"38%"
}}
</div>
<
div
class
=
"item-left"
>
{{
"
撤销案件梳理
"
}}
<
/div
>
<
div
class
=
"item-right"
>
{{
`${cancelNum
}
`
}}
<
/div
>
<
/div
>
<
/div
>
<div
class=
"center"
>
<div
class=
"box1"
>
<div
class=
"box-header"
>
<div
class=
"header-left"
></div>
<div
class=
"title"
>
232调查数量年度变化趋势
</div>
<div
class=
"header-btn-box"
>
<!--
<div
class=
"btn"
:class=
"
{ btnActive: btnActiveName === '发起调查' }"
@click="handleClickBox1Btn('发起调查')"
>
{{
"发起调查"
}}
<
div
class
=
"content-list"
>
<
div
class
=
"content-item"
v
-
loading
=
"box1Loading"
>
<
AnalysisBox
title
=
"数量变化趋势"
>
<
template
#
header
-
btn
>
<
div
class
=
"header-btn-box"
>
<
ActionButton
:
type
=
"activeName === '1' ? 'active' : 'normal'"
name
=
"发起调查"
@
click
=
"onStatNum('1')"
><
/ActionButton
>
<
ActionButton
:
type
=
"activeName === '0' ? 'active' : 'normal'"
name
=
"结束调查"
@
click
=
"onStatNum('0')"
><
/ActionButton
>
<
/div
>
<div
class=
"btn"
:class=
"
{ btnActive: btnActiveName === '结束调查' }"
@click="handleClickBox1Btn('结束调查')"
>
{{
"结束调查"
}}
</div>
-->
<ActionButton
:type=
"btnActiveName === '发起调查' ? 'active' : 'normal'"
name=
"发起调查"
@
click=
"handleClickBox1Btn('发起调查')"
></ActionButton>
<ActionButton
:type=
"btnActiveName === '结束调查' ? 'active' : 'normal'"
name=
"结束调查"
@
click=
"handleClickBox1Btn('结束调查')"
></ActionButton>
</div>
<div
class=
"header-right"
>
<div
class=
"icon"
>
<img
src=
"@/assets/icons/box-header-icon1.png"
alt=
""
/>
</div>
<div
class=
"icon"
>
<img
src=
"@/assets/icons/box-header-icon2.png"
alt=
""
/>
</div>
<div
class=
"icon"
>
<img
src=
"@/assets/icons/box-header-icon3.png"
alt=
""
/>
<
/template
>
<
div
class
=
"box-main"
>
<
div
class
=
"box-head"
ref
=
"chart1"
><
/div
>
<
TipTab
text
=
"美对华232调查案件的数量变化趋势,数据来源:美国商务部官网"
style
=
"margin-top: 16px;"
/>
<
div
class
=
"ai-pane"
>
<
AiButton
/>
<
AiPane
:
aiContent
=
"aiContent.content1"
/>
<
/div
>
<
/div
>
</div>
<div
class=
"box1-main"
id=
"chart1"
></div>
<
/AnalysisBox
>
<
/div
>
<div
class=
"
box2
"
>
<
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-icon1.png"
alt=
""
/
>
</div
>
<div
class=
"
icon"
>
<img
src=
"@/assets/icons/box-header-icon2.png"
alt=
"
"
/>
<
/div
>
<div
class=
"icon"
>
<
img
src=
"@/assets/icons/box-header-icon3.png"
alt=
"
"
/>
<
div
class
=
"
content-item"
v
-
loading
=
"box2Loading
"
>
<
AnalysisBox
title
=
"领域分布情况
"
>
<
template
#
header
-
btn
>
<
el
-
select
v
-
model
=
"box2Paarams.years"
@
change
=
"handleGetStatArea()"
placeholder
=
"选择时间"
style
=
"width:120px; margin-right:12px;"
>
<
el
-
option
v
-
for
=
"item in yearList"
:
key
=
"item.value"
:
label
=
"item.label"
:
value
=
"item.value"
/
>
<
/el-select
>
<
/template
>
<
div
class
=
"box-main"
>
<
div
class
=
"
box-head"
ref
=
"chart2"
><
/div
>
<
TipTab
text
=
"美对华232调查案件的领域分布情况,数据来源:美国商务部官网"
style
=
"margin-top: -16px;
"
/>
<
div
class
=
"ai-pane"
>
<
AiButton
/
>
<
AiPane
:
aiContent
=
"aiContent.content2
"
/>
<
/div
>
<
/div
>
</div>
<div
class=
"box2-main"
id=
"chart2"
></div>
<
/AnalysisBox
>
<
/div
>
<
/div
>
<div
class=
"
footer
"
>
<div
class=
"
box3
"
>
<
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-icon1.png"
alt=
""
/
>
</div
>
<div
class=
"
icon"
>
<img
src=
"@/assets/icons/box-header-icon2.png"
alt=
"
"
/>
<
/div
>
<div
class=
"icon"
>
<
img
src=
"@/assets/icons/box-header-icon3.png"
alt=
"
"
/>
<
div
class
=
"
content-list
"
>
<
div
class
=
"
content-item"
v
-
loading
=
"box3Loading
"
>
<
AnalysisBox
title
=
"关税变化分布
"
>
<
template
#
header
-
btn
>
<
el
-
select
v
-
model
=
"box3Paarams.years"
@
change
=
"onSearchTariff()"
placeholder
=
"选择时间"
style
=
"width:120px; margin-right:12px;"
>
<
el
-
option
v
-
for
=
"item in yearList"
:
key
=
"item.value"
:
label
=
"item.label"
:
value
=
"item.value"
/
>
<
/el-select
>
<
/template
>
<
div
class
=
"box-main"
>
<
div
class
=
"
box-head"
ref
=
"chart3"
><
/div
>
<
TipTab
text
=
"美对华232调查案件导致的关税变化分布,数据来源:美国商务部官网"
style
=
"margin-top: -16px;
"
/>
<
div
class
=
"ai-pane"
>
<
AiButton
/
>
<
AiPane
:
aiContent
=
"aiContent.content3
"
/>
<
/div
>
<
/div
>
</div>
<div
class=
"box3-main"
id=
"chart3"
></div>
<
/AnalysisBox
>
<
/div
>
<div
class=
"
box4
"
>
<
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-icon1.png"
alt=
""
/
>
</div
>
<div
class=
"
icon"
>
<img
src=
"@/assets/icons/box-header-icon2.png"
alt=
"
"
/>
<
/div
>
<div
class=
"icon"
>
<
img
src=
"@/assets/icons/box-header-icon3.png"
alt=
"
"
/>
<
div
class
=
"
content-item"
v
-
loading
=
"box4Loading
"
>
<
AnalysisBox
title
=
"国家分布情况
"
>
<
template
#
header
-
btn
>
<
el
-
select
v
-
model
=
"box4Paarams.years"
@
change
=
"handleGetSearchCountry()"
placeholder
=
"选择时间"
style
=
"width:120px; margin-right:12px;"
>
<
el
-
option
v
-
for
=
"item in yearList"
:
key
=
"item.value"
:
label
=
"item.label"
:
value
=
"item.value"
/
>
<
/el-select
>
<
/template
>
<
div
class
=
"box-main"
>
<
div
class
=
"
box-head"
ref
=
"chart4"
><
/div
>
<
TipTab
text
=
"美232调查所涉及的国家分布情况,数据来源:美国商务部官网"
style
=
"margin-top: -16px;
"
/>
<
div
class
=
"ai-pane"
>
<
AiButton
/
>
<
AiPane
:
aiContent
=
"aiContent.content4
"
/>
<
/div
>
<
/div
>
</div>
<div
class=
"box4-main"
id=
"chart4"
></div>
<
/AnalysisBox
>
<
/div
>
<
/div
>
<
/div
>
<
/template
>
<
script
setup
>
import
{
ref
,
onMounted
,
nextTick
}
from
"vue"
;
import
*
as
echarts
from
"echarts"
;
import
ChinaJson
from
"../../assets/json/China.json"
;
import
getMultiLineChart
from
"./utils/multiLineChart"
;
import
getBarChart
from
"./utils/barChart"
;
import
getPieChart
from
"./utils/piechart"
;
import
getMapChart
from
"./utils/mapChart"
;
import
{
ref
,
onMounted
,
nextTick
,
reactive
}
from
"vue"
;
import
{
getStatCount
,
getStatArea
,
getSearchCountry
,
getStatNum
,
getSearchTariff
,
}
from
"@/api/marketAccessRestrictions"
;
// 绘制echarts图表
const
setChart
=
(
option
,
chartId
)
=>
{
let
chartDom
=
document
.
getElementById
(
chartId
);
chartDom
.
removeAttribute
(
"_echarts_instance_"
);
let
chart
=
echarts
.
init
(
chartDom
);
chart
.
setOption
(
option
);
return
chart
;
};
import
createLineChart
from
"@/views/marketAccessRestrictions/utils/baseLineChart"
;
import
createPieChart
from
"@/views/marketAccessRestrictions/utils/basePiechart.js"
;
import
AiButton
from
'@/components/base/Ai/AiButton/index.vue'
;
import
AiPane
from
'@/components/base/Ai/AiPane/index.vue'
;
import
{
getNearYearList
,
getAIReport
}
from
"@/views/marketAccessRestrictions/utils/index.ts"
;
const
btnActiveName
=
ref
(
"发起调查"
);
const
handleClickBox1Btn
=
name
=>
{
btnActiveName
.
value
=
name
;
};
const
yearList
=
getNearYearList
();
// 获取AI智能报告
const
aiContent
=
reactive
({
content1
:
"正在生成..."
,
content2
:
"正在生成..."
,
content3
:
"正在生成..."
,
content4
:
"正在生成..."
,
}
)
const
onAIReport
=
(
data
,
key
)
=>
{
getAIReport
(
data
).
then
(
res
=>
{
aiContent
[
key
]
=
res
}
)
}
const
chart1Data
=
ref
({
title
:
[
"2014"
,
"2015"
,
"2016"
,
"2017"
,
"2018"
,
"2019"
,
"2020"
,
"2021"
,
"2022"
,
"2023"
,
"2024"
,
"2025"
],
data
:
[
{
name
:
"提出法案"
,
value
:
[
145
,
52
,
84
,
99
,
71
,
96
,
128
,
144
,
140
,
168
,
188
,
172
]
// 数量统计
const
totalCaseNum
=
ref
(
0
)
const
onCaseNum
=
ref
(
0
)
const
isTariffNum
=
ref
(
0
)
const
cancelNum
=
ref
(
'0%'
)
const
handleGetStat
=
async
()
=>
{
try
{
const
res
=
await
getStatCount
({
sortCode
:
'232'
}
)
console
.
log
(
'232数量统计'
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
totalCaseNum
.
value
=
res
.
data
.
allCaseNum
onCaseNum
.
value
=
res
.
data
.
underCaseNum
isTariffNum
.
value
=
res
.
data
.
isTariffNum
cancelNum
.
value
=
res
.
data
.
cancelNum
}
]
});
const
chart2Data
=
ref
([
{
name
:
"半导体"
,
value
:
50
},
{
name
:
"电子设备"
,
value
:
46
},
{
name
:
"显示技术"
,
value
:
40
},
{
name
:
"新能源"
,
value
:
32
},
{
name
:
"通信设备"
,
value
:
31
},
{
name
:
"汽车"
,
value
:
31
},
{
name
:
"轻工业制造"
,
value
:
30
},
{
name
:
"其他"
,
value
:
24
}
]);
const
chart2ColorList
=
ref
([
"#69B1FF"
,
"#FFC069"
,
"#87E8DE"
,
"#597EF7"
,
"#D6E4FF"
,
"#FF7875"
,
"#B37FEB"
,
"#FFA39E"
]);
}
catch
(
error
)
{
}
}
const
chart3Data
=
ref
([
{
name
:
"税率25%+"
,
value
:
50
},
{
name
:
"税率11%-25%"
,
value
:
46
},
{
name
:
"税率1%-10%"
,
value
:
22
},
{
name
:
"税率0%"
,
value
:
10
},
]
const
chart1
=
ref
(
null
);
const
activeName
=
ref
(
'1'
);
const
box1Loading
=
ref
(
false
);
const
onStatNum
=
async
(
event
)
=>
{
if
(
event
)
activeName
.
value
=
event
;
box1Loading
.
value
=
true
;
let
chartData
=
{
title
:
[],
list
:
[]
}
;
try
{
const
res
=
await
getStatNum
({
sortCode
:
232
,
searchStatus
:
activeName
.
value
}
)
console
.
log
(
'数量变化趋势'
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
chartData
.
title
=
res
.
data
.
map
(
item
=>
item
.
searchYorM
),
chartData
.
list
=
[{
name
:
"232调查"
,
value
:
res
.
data
.
map
(
item
=>
item
.
searchCount
)
}
]
}
else
{
chartData
.
title
=
[];
chartData
.
list
=
[];
}
}
catch
(
error
)
{
chartData
.
title
=
[];
chartData
.
list
=
[];
}
onAIReport
({
type
:
"折线图"
,
name
:
"数量变化趋势"
,
data
:
chartData
}
,
"content1"
)
nextTick
(()
=>
{
createLineChart
(
chart1
,
chartData
)
}
);
box1Loading
.
value
=
false
;
}
);
const
chart3ColorList
=
ref
([
"#69B1FF"
,
"#FFC069"
,
"#87E8DE"
,
"#FFA39E"
]);
const
chart2
=
ref
(
null
);
const
box2Paarams
=
reactive
({
sortCode
:
232
,
years
:
'2025'
}
)
const
box2Loading
=
ref
(
false
);
const
handleGetStatArea
=
async
()
=>
{
box2Loading
.
value
=
true
;
let
chartData
=
[]
try
{
const
res
=
await
getStatArea
(
box2Paarams
);
console
.
log
(
'领域分布情况'
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
chartData
=
res
.
data
.
map
(
item
=>
({
name
:
item
.
areaname
,
value
:
item
.
areacount
}
)
);
}
else
{
chartData
=
[];
}
}
catch
(
error
)
{
chartData
=
[];
}
onAIReport
({
type
:
"环形图"
,
name
:
"领域分布情况"
,
data
:
chartData
}
,
"content2"
)
nextTick
(()
=>
{
createPieChart
(
chart2
,
chartData
)
}
);
box2Loading
.
value
=
false
;
}
;
const
chart4Data
=
ref
([
{
name
:
"加拿大"
,
value
:
50
},
{
name
:
"欧盟"
,
value
:
46
},
{
name
:
"韩国"
,
value
:
40
},
{
name
:
"日本"
,
value
:
31
},
{
name
:
"中国"
,
value
:
24
},
const
chart3
=
ref
(
null
);
const
box3Paarams
=
reactive
({
sortCode
:
232
,
years
:
'2025'
}
)
const
box3Loading
=
ref
(
false
);
const
onSearchTariff
=
async
()
=>
{
box3Loading
.
value
=
true
;
let
chartData
=
[]
try
{
const
res
=
await
getSearchTariff
(
box3Paarams
);
console
.
log
(
'关税变化分布'
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
chartData
=
[
{
name
:
"税率25%+"
,
value
:
res
.
data
.
TARIFF25
}
,
{
name
:
"税率11%-25%"
,
value
:
res
.
data
.
TARIFF11
}
,
{
name
:
"税率1%-10%"
,
value
:
res
.
data
.
TARIFF1
}
,
{
name
:
"税率0%"
,
value
:
res
.
data
.
TARIFF0
}
,
];
}
else
{
chartData
=
[];
}
}
catch
(
error
)
{
chartData
=
[];
}
onAIReport
({
type
:
"环形图"
,
name
:
"关税变化分布"
,
data
:
chartData
}
,
"content3"
)
nextTick
(()
=>
{
createPieChart
(
chart3
,
chartData
)
}
);
box3Loading
.
value
=
false
;
}
]);
const
chart4ColorList
=
ref
([
"#69B1FF"
,
"#FFC069"
,
"#87E8DE"
,
"#D6E4FF"
,
"#FFA39E"
]);
const
chart4
=
ref
(
null
);
const
box4Paarams
=
reactive
({
sortCode
:
232
,
years
:
'2025'
}
)
const
box4Loading
=
ref
(
false
);
const
handleGetSearchCountry
=
async
()
=>
{
box4Loading
.
value
=
true
;
let
chartData
=
[]
try
{
const
res
=
await
getSearchCountry
(
box4Paarams
);
console
.
log
(
'国家分布情况'
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
chartData
=
res
.
data
.
map
(
item
=>
({
name
:
item
.
COUNTRY
,
value
:
item
.
NUM
}
)
);
}
else
{
chartData
=
[]
}
}
catch
(
error
)
{
chartData
=
[]
}
onAIReport
({
type
:
"环形图"
,
name
:
"国家分布情况"
,
data
:
chartData
}
,
"content4"
)
nextTick
(()
=>
{
createPieChart
(
chart4
,
chartData
)
}
);
box4Loading
.
value
=
false
;
}
;
onMounted
(()
=>
{
let
chart1
=
getMultiLineChart
(
chart1Data
.
value
.
title
,
chart1Data
.
value
.
data
[
0
].
value
);
setChart
(
chart1
,
"chart1"
);
let
chart2
=
getPieChart
(
chart2Data
.
value
,
chart2ColorList
.
value
);
setChart
(
chart2
,
"chart2"
);
let
chart3
=
getPieChart
(
chart3Data
.
value
,
chart3ColorList
.
value
);
setChart
(
chart3
,
"chart3"
);
let
chart4
=
getPieChart
(
chart4Data
.
value
,
chart4ColorList
.
value
);
setChart
(
chart4
,
"chart4"
);
handleGetStat
()
onStatNum
()
handleGetStatArea
()
onSearchTariff
()
handleGetSearchCountry
()
}
);
<
/script
>
...
...
@@ -207,19 +265,23 @@ onMounted(() => {
display
:
flex
;
flex
-
direction
:
column
;
gap
:
16
px
;
.top
{
.
content
-
top
{
display
:
flex
;
justify-content
:
space-between
;
gap
:
16
px
;
.
item
{
width
:
388px
;
width
:
20
px
;
flex
:
auto
;
height
:
80
px
;
border-radius
:
4
px
;
border
-
radius
:
10
px
;
box
-
shadow
:
0
px
0
px
15
px
0
px
rgba
(
60
,
87
,
126
,
0.2
);
background
:
rgba
(
255
,
255
,
255
,
1
);
position
:
relative
;
display
:
flex
;
align
-
items
:
center
;
justify
-
content
:
space
-
between
;
&
::
before
{
position
:
absolute
;
content
:
""
;
...
...
@@ -229,9 +291,9 @@ onMounted(() => {
left
:
0
;
top
:
15
px
;
}
.
item
-
left
{
margin
-
left
:
30
px
;
margin-top
:
25px
;
height
:
24
px
;
color
:
rgba
(
59
,
65
,
75
,
1
);
font
-
family
:
Microsoft
YaHei
;
...
...
@@ -239,8 +301,8 @@ onMounted(() => {
font
-
weight
:
700
;
line
-
height
:
24
px
;
}
.
item
-
right
{
margin-top
:
28px
;
margin
-
right
:
35
px
;
height
:
24
px
;
color
:
var
(
--
color
-
main
-
active
);
...
...
@@ -249,188 +311,94 @@ onMounted(() => {
font
-
weight
:
700
;
line
-
height
:
24
px
;
}
.
item
-
left
-
box
{
margin
-
left
:
30
px
;
font
-
size
:
16
px
;
line
-
height
:
24
px
;
.
item
-
left1
{
margin-top
:
13px
;
height
:
24px
;
color
:
rgba
(
59
,
65
,
75
,
1
);
font
-
family
:
Microsoft
YaHei
;
font-size
:
16px
;
font
-
weight
:
700
;
line-height
:
24px
;
}
.
item
-
left2
{
height
:
2px
;
color
:
rgba
(
95
,
101
,
108
,
1
);
font
-
family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
24px
;
}
}
}
}
.box-header
{
height
:
56px
;
display
:
flex
;
position
:
relative
;
.header-left
{
margin-top
:
18px
;
width
:
8px
;
height
:
20px
;
border-radius
:
0
4px
4px
0
;
background
:
var
(
--
color-main-active
);
}
.title
{
margin-left
:
14px
;
margin-top
:
14px
;
height
:
26px
;
line-height
:
26px
;
color
:
var
(
--
color-main-active
);
font-family
:
Microsoft
YaHei
;
font-size
:
20px
;
font-weight
:
700
;
}
.header-btn-box
{
position
:
absolute
;
top
:
14px
;
right
:
120px
;
display
:
flex
;
gap
:
8px
;
.btn
{
margin-left
:
8px
;
height
:
28px
;
padding
:
0
8px
;
box-sizing
:
border-box
;
border
:
1px
solid
rgba
(
230
,
231
,
232
,
1
);
border-radius
:
4px
;
background
:
rgba
(
255
,
255
,
255
,
1
);
text-align
:
center
;
line-height
:
28px
;
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
cursor
:
pointer
;
}
.btnActive
{
border
:
1px
solid
var
(
--
color-main-active
);
background
:
rgba
(
246
,
250
,
255
,
1
);
color
:
var
(
--
color-main-active
);
}
}
.header-right
{
position
:
absolute
;
top
:
14px
;
right
:
12px
;
display
:
flex
;
justify-content
:
flex-end
;
gap
:
4px
;
.icon
{
width
:
28px
;
height
:
28px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
}
}
.center
{
.
content
-
list
{
height
:
410
px
;
display
:
flex
;
justify-content
:
space-between
;
.box1
{
width
:
792px
;
height
:
360px
;
border-radius
:
4px
;
box-shadow
:
0px
0px
15px
0px
rgba
(
60
,
87
,
126
,
0
.2
);
background
:
rgba
(
255
,
255
,
255
,
1
);
.box1-main
{
height
:
300px
;
}
}
.box2
{
width
:
792px
;
height
:
360px
;
border-radius
:
4px
;
box-shadow
:
0px
0px
15px
0px
rgba
(
60
,
87
,
126
,
0
.2
);
background
:
rgba
(
255
,
255
,
255
,
1
);
.box2-main
{
height
:
300px
;
// width: 752px;
box-sizing
:
border-box
;
padding
:
0
20px
;
}
}
}
.footer
{
display
:
flex
;
justify-content
:
space-between
;
.box3
{
width
:
792px
;
height
:
360px
;
border-radius
:
4px
;
box-shadow
:
0px
0px
15px
0px
rgba
(
60
,
87
,
126
,
0
.2
);
background
:
rgba
(
255
,
255
,
255
,
1
);
.box3-main
{
height
:
300px
;
}
.box3-main1
{
height
:
300px
;
gap
:
16
px
;
.
content
-
item
{
width
:
20
px
;
flex
:
auto
;
height
:
100
%
;
.
box
-
main
{
width
:
100
%
;
height
:
100
%
;
padding
:
12
px
30
px
20
px
;
display
:
flex
;
.box3-main1-left
{
width
:
380px
;
height
:
300px
;
overflow-y
:
auto
;
overflow-x
:
hidden
;
.box3-main1-left-item
{
flex
-
direction
:
column
;
position
:
relative
;
.
box
-
head
{
height
:
20
px
;
flex
:
auto
;
}
.
ai
-
pane
{
position
:
absolute
;
right
:
0
px
;
bottom
:
15
px
;
z
-
index
:
2
;
:
deep
(.
ai
-
pane
-
wrapper
)
{
display
:
none
;
}
:
deep
(.
ai
-
button
-
wrapper
)
{
display
:
flex
;
height
:
36px
;
margin-left
:
20px
;
.box3-main1-left-item-left
{
width
:
24px
;
height
:
24px
;
border-radius
:
12px
;
margin-left
:
12px
;
margin-top
:
6px
;
background
:
#e7f3ff
;
color
:
#0a57a6
;
text-align
:
center
;
line-height
:
24px
;
}
.box3-main1-left-item-center
{
height
:
36px
;
line-height
:
36px
;
width
:
220px
;
margin-left
:
12px
;
}
&
:
hover
{
width
:
100
%
;
bottom
:
0
px
;
:
deep
(.
ai
-
pane
-
wrapper
)
{
display
:
block
;
}
.box3-main1-left-item-right
{
width
:
80px
;
box-sizing
:
border-box
;
padding-right
:
10px
;
text-align
:
right
;
:
deep
(.
ai
-
button
-
wrapper
)
{
display
:
none
;
}
}
}
.box3-main1-right
{
width
:
390px
;
height
:
300px
;
}
}
}
.box4
{
width
:
792px
;
height
:
360px
;
}
.
header
-
btn
-
box
{
display
:
flex
;
gap
:
8
px
;
margin
-
right
:
12
px
;
.
btn
{
height
:
28
px
;
padding
:
0
8
px
;
box
-
sizing
:
border
-
box
;
border
:
1
px
solid
rgba
(
230
,
231
,
232
,
1
);
border
-
radius
:
4
px
;
box-shadow
:
0px
0px
15px
0px
rgba
(
60
,
87
,
126
,
0
.2
);
background
:
rgba
(
255
,
255
,
255
,
1
);
.box4-main
{
height
:
300px
;
box-sizing
:
border-box
;
padding
:
0
20px
;
}
text
-
align
:
center
;
line
-
height
:
28
px
;
color
:
rgba
(
59
,
65
,
75
,
1
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
16
px
;
font
-
weight
:
400
;
cursor
:
pointer
;
}
.
btnActive
{
border
:
1
px
solid
var
(
--
color
-
main
-
active
);
background
:
rgba
(
246
,
250
,
255
,
1
);
color
:
var
(
--
color
-
main
-
active
);
}
}
}
...
...
src/views/marketAccessRestrictions/marketAccessLayout/overview/301/index.vue
浏览文件 @
86617244
<
template
>
<div
class=
"wrap"
>
<div
class=
"top"
>
<div
class=
"box1 box"
v-loading=
"box1Loading"
>
<div
class=
"box-header"
>
<div
class=
"header-left"
></div>
<div
class=
"title"
>
对华301调查年度数量趋势
</div>
<div
class=
"warning-text"
>
{{
`${inProgressCount
}
项调查仍在进行中`
}}
<
/div
>
<
div
class
=
"header-right"
>
<
div
class
=
"icon"
>
<
img
src
=
"@/assets/icons/box-header-icon1.png"
alt
=
""
/>
<
/div
>
<
div
class
=
"icon"
>
<
img
src
=
"@/assets/icons/box-header-icon2.png"
alt
=
""
/>
<div
class=
"content-list"
>
<div
class=
"content-item"
v-loading=
"box1Loading"
>
<AnalysisBox
title=
"数量变化趋势"
>
<template
#
header-btn
>
<div
class=
"warning-text"
>
{{
`${inProgressCount
}
项调查仍在进行中`
}}
<
/div
>
<
/template
>
<
div
class
=
"box-main"
>
<
div
class
=
"box-head"
ref
=
"box1Chart"
><
/div
>
<
TipTab
text
=
"美对华301调查案件的数量变化趋势,数据来源:美国贸易代表办公室官网"
style
=
"margin-top: 16px"
/>
<
div
class
=
"ai-pane"
>
<
AiButton
/>
<
AiPane
:
aiContent
=
"aiContent.content1"
/>
<
/div
>
<
div
class
=
"icon"
>
<
img
src
=
"@/assets/icons/box-header-icon3.png"
alt
=
""
/>
<
/div
>
<
/div
>
<
/div
>
<
div
class
=
"box1-main"
id
=
"box1Chart"
><
/div
>
<
div
class
=
"box-footer"
>
<
div
class
=
"box-footer-left"
>
<
img
src
=
"@/assets/icons/box-footer-left-icon.png"
alt
=
""
/>
<
/div
>
<
div
class
=
"box-footer-center"
>
{{
"近年来美对华301调查呈现案件频发、聚焦专利壁垒、力图阻断产业链升级的特点。"
}}
<
/div
>
<
div
class
=
"box-footer-right"
>
<
img
src
=
"@/assets/icons/box-footer-right-icon.png"
alt
=
""
/>
<
/div
>
<
/div
>
<
/AnalysisBox
>
<
/div
>
<
div
class
=
"
box2 box
"
v
-
loading
=
"box2Loading"
>
<
div
class
=
"box-header
"
>
<
div
class
=
"header-left"
><
/div
>
<
div
class
=
"title"
>
301
调查国家分布
<
/div
>
<
div
class
=
"header-right"
>
<
div
class
=
"icon"
>
<
img
src
=
"@/assets/icons/box-header-icon1.png"
alt
=
""
/
>
<
/div
>
<
div
class
=
"
icon"
>
<
img
src
=
"@/assets/icons/box-header-icon2.png"
alt
=
"
"
/>
<
/div
>
<
div
class
=
"icon"
>
<
img
src
=
"@/assets/icons/box-header-icon3.png"
alt
=
"
"
/>
<
div
class
=
"
content-item
"
v
-
loading
=
"box2Loading"
>
<
AnalysisBox
title
=
"国家分布情况
"
>
<
template
#
header
-
btn
>
<
el
-
select
v
-
model
=
"box2Paarams.years"
@
change
=
"handleGetSearchCountry()"
placeholder
=
"选择时间"
style
=
"width:120px; margin-right:12px;"
>
<
el
-
option
v
-
for
=
"item in yearList"
:
key
=
"item.value"
:
label
=
"item.label"
:
value
=
"item.value"
/
>
<
/el-select
>
<
/template
>
<
div
class
=
"box-main"
>
<
div
class
=
"
box-head"
id
=
"box2Chart"
><
/div
>
<
TipTab
text
=
"美301调查所涉及的国家分布情况,数据来源:美国贸易代表办公室官网"
style
=
"margin-top: 16px
"
/>
<
div
class
=
"ai-pane"
>
<
AiButton
/
>
<
AiPane
:
aiContent
=
"aiContent.content2
"
/>
<
/div
>
<
/div
>
<
/div
>
<
div
class
=
"box2-main"
id
=
"box2Chart"
><
/div
>
<
div
class
=
"box-footer"
>
<
div
class
=
"box-footer-left"
>
<
img
src
=
"@/assets/icons/box-footer-left-icon.png"
alt
=
""
/>
<
/div
>
<
div
class
=
"box-footer-center"
>
{{
"现有调查以先进制造、半导体产业为主。"
}}
<
/div
>
<
div
class
=
"box-footer-right"
>
<
img
src
=
"@/assets/icons/box-footer-right-icon.png"
alt
=
""
/>
<
/div
>
<
/div
>
<
/AnalysisBox
>
<
/div
>
<
/div
>
<
div
class
=
"bottom"
>
<
div
class
=
"box3 box"
v
-
loading
=
"box3Loading"
>
<
div
class
=
"box-header"
>
<
div
class
=
"header-left"
><
/div
>
<
div
class
=
"title"
>
301
调查
direction
及结果分布
<
/div
>
<
div
class
=
"header-right"
>
<
div
class
=
"icon"
>
<
img
src
=
"@/assets/icons/box-header-icon1.png"
alt
=
""
/>
<
/div
>
<
div
class
=
"icon"
>
<
img
src
=
"@/assets/icons/box-header-icon2.png"
alt
=
""
/>
<
/div
>
<
div
class
=
"icon"
>
<
img
src
=
"@/assets/icons/box-header-icon3.png"
alt
=
""
/>
<
div
class
=
"content-list"
>
<
div
class
=
"content-item"
v
-
loading
=
"box3Loading"
>
<
AnalysisBox
title
=
"调查方向及结果分布"
>
<
div
class
=
"box-main"
>
<
div
class
=
"box-head"
id
=
"box3Chart"
><
/div
>
<
TipTab
text
=
"美301调查方向及结果分布情况,数据来源:美国贸易代表办公室官网"
style
=
"margin-top: 16px;"
/>
<
div
class
=
"ai-pane"
>
<
AiButton
/>
<
AiPane
:
aiContent
=
"aiContent.content3"
/>
<
/div
>
<
/div
>
<
/div
>
<
div
class
=
"box3-main"
id
=
"box3Chart"
><
/div
>
<
div
class
=
"box-footer"
>
<
div
class
=
"box-footer-left"
>
<
img
src
=
"@/assets/icons/box-footer-left-icon.png"
alt
=
""
/>
<
/div
>
<
div
class
=
"box-footer-center"
>
{{
"近年来美对华301调查呈现案件频发、聚焦专利壁垒、力图阻断产业链升级的特点。"
}}
<
/div
>
<
div
class
=
"box-footer-right"
>
<
img
src
=
"@/assets/icons/box-footer-right-icon.png"
alt
=
""
/>
<
/div
>
<
/div
>
<
/AnalysisBox
>
<
/div
>
<
div
class
=
"box4 box"
v
-
loading
=
"box4Loading"
>
<
div
class
=
"box-header"
>
<
div
class
=
"header-left"
><
/div
>
<
div
class
=
"title"
>
301
调查领域分布
<
/div
>
<
div
class
=
"header-select-box"
>
<
el
-
select
v
-
model
=
"selectYear"
@
change
=
"handleSelectYear"
placeholder
=
"选择时间"
style
=
"width: 120px"
>
<
div
class
=
"content-item"
v
-
loading
=
"box4Loading"
>
<
AnalysisBox
title
=
"领域分布情况"
>
<
template
#
header
-
btn
>
<
el
-
select
v
-
model
=
"box4Paarams.years"
@
change
=
"handleGetStatArea()"
placeholder
=
"选择时间"
style
=
"width:120px; margin-right:12px;"
>
<
el
-
option
v
-
for
=
"item in yearList"
:
key
=
"item.value"
:
label
=
"item.label"
:
value
=
"item.value"
/>
<
/el-select
>
<
/div
>
<
div
class
=
"header-right"
>
<
div
class
=
"icon"
>
<
img
src
=
"@/assets/icons/box-header-icon1.png"
alt
=
""
/>
<
/template
>
<
div
class
=
"box-main"
>
<
div
class
=
"box-head"
ref
=
"box4Chart"
><
/div
>
<
TipTab
text
=
"美对华301调查案件的领域分布情况,数据来源:美国贸易代表办公室官网"
style
=
"margin-top: -16px;"
/>
<
div
class
=
"ai-pane"
>
<
AiButton
/>
<
AiPane
:
aiContent
=
"aiContent.content4"
/>
<
/div
>
<
div
class
=
"icon"
>
<
img
src
=
"@/assets/icons/box-header-icon2.png"
alt
=
""
/>
<
/div
>
<
div
class
=
"icon"
>
<
img
src
=
"@/assets/icons/box-header-icon3.png"
alt
=
""
/>
<
/div
>
<
/div
>
<
/div
>
<
div
class
=
"box4-main"
id
=
"box4Chart"
><
/div
>
<
div
class
=
"box-footer"
>
<
div
class
=
"box-footer-left"
>
<
img
src
=
"@/assets/icons/box-footer-left-icon.png"
alt
=
""
/>
<
/div
>
<
div
class
=
"box-footer-center"
>
{{
"主要集中在存储、芯片设计及通信领域,如长江存储、长鑫存储、华为、中兴等"
}}
<
/div
>
<
div
class
=
"box-footer-right"
>
<
img
src
=
"@/assets/icons/box-footer-right-icon.png"
alt
=
""
/>
<
/div
>
<
/div
>
<
/AnalysisBox
>
<
/div
>
<
/div
>
<
/div
>
<
/template
>
<
script
setup
>
import
{
ref
,
onMounted
}
from
"vue"
;
import
{
ref
,
onMounted
,
nextTick
,
reactive
}
from
"vue"
;
import
setChart
from
"@/utils/setChart"
;
import
getLineChart
from
"./utils/lineChart"
;
import
getBarChart
from
"./utils/barChart"
;
import
getSankeyChart
from
"./utils/sankey"
;
import
getPieChart
from
"./utils/piechart"
;
import
getbarChart
from
"@/views/bill/utils/barchart"
;
import
{
getSearchCountry
,
getStatArea
,
getStatNum
,
getSearchDirection
}
from
"@/api/marketAccessRestrictions"
;
const
selectYear
=
ref
(
"2025"
);
const
yearList
=
ref
([
{
label
:
"2025"
,
value
:
"2025"
}
,
{
label
:
"2024"
,
value
:
"2024"
}
,
{
label
:
"2023"
,
value
:
"2023"
}
]);
import
{
getSearchCountry
,
getStatArea
,
getStatNum
,
getSearchDirection
}
from
"@/api/marketAccessRestrictions"
;
import
createLineChart
from
"@/views/marketAccessRestrictions/utils/baseLineChart"
;
import
createPieChart
from
"@/views/marketAccessRestrictions/utils/basePiechart.js"
;
import
AiButton
from
'@/components/base/Ai/AiButton/index.vue'
;
import
AiPane
from
'@/components/base/Ai/AiPane/index.vue'
;
import
{
getNearYearList
,
getAIReport
}
from
"@/views/marketAccessRestrictions/utils/index.ts"
;
const
yearList
=
getNearYearList
();
// 获取AI智能报告
const
aiContent
=
reactive
({
content1
:
"正在生成..."
,
content2
:
"正在生成..."
,
content3
:
"正在生成..."
,
content4
:
"正在生成..."
,
}
)
const
onAIReport
=
(
data
,
key
)
=>
{
getAIReport
(
data
).
then
(
res
=>
{
aiContent
[
key
]
=
res
}
)
}
const
inProgressCount
=
ref
(
0
);
const
box1Loading
=
ref
(
false
);
const
box2Loading
=
ref
(
false
);
const
box3Loading
=
ref
(
false
);
const
box4Loading
=
ref
(
false
);
const
box1ChartData
=
ref
({
title
:
[],
data
:
[]
}
);
const
box1Chart
=
ref
(
null
);
const
box1Loading
=
ref
(
false
);
const
handleGetStatNum
=
async
()
=>
{
box1Loading
.
value
=
true
;
let
chartData
=
{
title
:
[],
list
:
[]
}
try
{
const
res
=
await
getStatNum
({
byYorM
:
"12"
,
sortCode
:
"301"
}
);
const
res
=
await
getStatNum
({
byYorM
:
"12"
,
sortCode
:
"301"
}
);
console
.
log
(
'数量变化趋势'
,
res
)
if
(
res
.
code
===
200
&&
res
.
data
)
{
const
sortedData
=
res
.
data
.
sort
((
a
,
b
)
=>
parseInt
(
a
.
searchYorM
)
-
parseInt
(
b
.
searchYorM
));
box1ChartData
.
value
.
title
=
sortedData
.
map
(
item
=>
item
.
searchYorM
);
box1ChartData
.
value
.
data
=
sortedData
.
map
(
item
=>
item
.
searchCount
);
chartData
.
title
=
sortedData
.
map
(
item
=>
item
.
searchYorM
);
chartData
.
list
=
[{
name
:
"301调查"
,
value
:
sortedData
.
map
(
item
=>
item
.
searchCount
)
}
]
inProgressCount
.
value
=
res
.
data
.
reduce
((
acc
,
cur
)
=>
acc
+
(
cur
.
inSearchCount
||
0
),
0
);
const
box1Chart
=
getLineChart
(
box1ChartData
.
value
.
title
,
box1ChartData
.
value
.
data
);
setChart
(
box1Chart
,
"box1Chart"
);
}
else
{
chartData
.
title
=
[]
chartData
.
list
=
[]
inProgressCount
.
value
=
0
}
}
catch
(
error
)
{
c
onsole
.
error
(
"获取调查年度数量趋势失败"
,
error
);
}
finally
{
box1Loading
.
value
=
false
;
c
hartData
.
title
=
[]
chartData
.
list
=
[]
inProgressCount
.
value
=
0
}
onAIReport
({
type
:
"折线图"
,
name
:
"数量变化趋势"
,
data
:
chartData
}
,
"content1"
)
nextTick
(()
=>
{
createLineChart
(
box1Chart
,
chartData
)
}
)
box1Loading
.
value
=
false
;
}
;
const
box2ChartData
=
ref
({
title
:
[],
data
:
[]
}
);
const
box3ChartData
=
ref
({
nodes
:
[],
links
:
[]
}
);
const
box2Paarams
=
reactive
({
sortCode
:
301
,
years
:
'2025'
}
)
const
box2Loading
=
ref
(
false
);
const
handleGetSearchCountry
=
async
()
=>
{
box2Loading
.
value
=
true
;
let
chartData
=
{
title
:
[],
data
:
[]
}
try
{
const
res
=
await
getSearchCountry
(
box2Paarams
);
console
.
log
(
'国家分布情况'
,
res
)
if
(
res
.
code
===
200
&&
res
.
data
)
{
chartData
.
title
=
res
.
data
.
map
(
item
=>
({
img
:
item
.
COUNTRYIMAGE
?
(
item
.
COUNTRYIMAGE
.
startsWith
(
"http"
)
?
item
.
COUNTRYIMAGE
:
`http://${item.COUNTRYIMAGE
}
`
)
:
""
,
name
:
item
.
COUNTRY
}
));
chartData
.
data
=
res
.
data
.
map
(
item
=>
item
.
NUM
)
}
else
{
chartData
.
title
=
[]
chartData
.
data
=
[]
}
}
catch
(
error
)
{
chartData
.
title
=
[]
chartData
.
data
=
[]
}
onAIReport
({
type
:
"柱状图"
,
name
:
"国家分布情况"
,
data
:
chartData
}
,
"content2"
)
nextTick
(()
=>
{
const
box2Chart
=
getBarChart
(
chartData
.
title
,
chartData
.
data
);
setChart
(
box2Chart
,
"box2Chart"
);
}
)
box2Loading
.
value
=
false
;
}
;
const
box3Loading
=
ref
(
false
);
const
handleGetSearchDirection
=
async
()
=>
{
box3Loading
.
value
=
true
;
let
chartData
=
{
nodes
:
[],
links
:
[]
}
try
{
const
res
=
await
getSearchDirection
({
sortCode
:
"301"
}
);
const
res
=
await
getSearchDirection
({
sortCode
:
"301"
}
);
console
.
log
(
'调查方向及结果分布'
,
res
)
chartData
.
nodes
=
[];
chartData
.
links
=
[];
if
(
res
.
code
===
200
&&
res
.
data
)
{
const
nodes
=
[];
const
links
=
[];
const
nodeNames
=
new
Set
();
res
.
data
.
forEach
(
item
=>
{
if
(
item
.
SEARCHDIRECTION
)
nodeNames
.
add
(
item
.
SEARCHDIRECTION
);
if
(
item
.
SEARCHRESULT
)
nodeNames
.
add
(
item
.
SEARCHRESULT
);
if
(
item
.
SEARCHDIRECTION
&&
item
.
SEARCHRESULT
)
{
links
.
push
({
chartData
.
links
.
push
({
source
:
item
.
SEARCHDIRECTION
,
target
:
item
.
SEARCHRESULT
,
value
:
item
.
SEARCHCOUNT
||
0
}
);
}
}
);
nodeNames
.
forEach
(
name
=>
{
nodes
.
push
({
name
}
);
}
);
box3ChartData
.
value
=
{
nodes
,
links
}
;
const
box3Chart
=
getSankeyChart
(
box3ChartData
.
value
.
nodes
,
box3ChartData
.
value
.
links
);
setChart
(
box3Chart
,
"box3Chart"
);
nodeNames
.
forEach
(
name
=>
{
chartData
.
nodes
.
push
({
name
}
)
}
);
}
}
catch
(
error
)
{
console
.
error
(
"获取调查方向及结果分布失败"
,
error
);
}
finally
{
box3Loading
.
value
=
false
;
chartData
.
nodes
=
[];
chartData
.
links
=
[];
}
onAIReport
({
type
:
"桑基图"
,
name
:
"调查方向及结果分布"
,
data
:
chartData
}
,
"content3"
)
nextTick
(()
=>
{
const
box3Chart
=
getSankeyChart
(
chartData
.
nodes
,
chartData
.
links
);
setChart
(
box3Chart
,
"box3Chart"
);
}
)
box3Loading
.
value
=
false
;
}
;
const
box4ChartData
=
ref
([]);
// 切换年份
const
handleSelectYear
=
val
=>
{
selectYear
.
value
=
val
;
handleGetStatArea
();
}
;
const
box4Chart
=
ref
(
null
)
const
box4Paarams
=
reactive
({
sortCode
:
301
,
years
:
'2025'
}
)
const
box4Loading
=
ref
(
false
);
const
handleGetStatArea
=
async
()
=>
{
box4Loading
.
value
=
true
;
const
yearMap
=
{
2023
:
2023
,
2024
:
2024
,
2025
:
2025
}
;
const
params
=
{
years
:
yearMap
[
selectYear
.
value
]
||
2025
,
sortCode
:
301
}
;
let
chartData
=
[]
try
{
const
res
=
await
getStatArea
(
params
);
const
res
=
await
getStatArea
(
box4Paarams
);
console
.
log
(
'领域分布情况'
,
res
)
if
(
res
.
code
===
200
&&
res
.
data
)
{
box4ChartData
.
value
=
res
.
data
.
filter
(
item
=>
item
.
SORTNAME
===
"301调查"
)
.
map
(
item
=>
({
name
:
item
.
AREANAME
,
value
:
item
.
AREACOUNT
}
));
const
box4Chart
=
getPieChart
(
box4ChartData
.
value
);
setChart
(
box4Chart
,
"box4Chart"
);
chartData
=
res
.
data
.
map
(
item
=>
({
name
:
item
.
areaname
,
value
:
item
.
areacount
}
));
}
else
{
chartData
=
[]
}
}
catch
(
error
)
{
console
.
error
(
"获取制裁领域分布失败"
,
error
);
}
finally
{
box4Loading
.
value
=
false
;
}
}
;
const
handleGetSearchCountry
=
async
()
=>
{
box2Loading
.
value
=
true
;
try
{
const
res
=
await
getSearchCountry
({
sortCode
:
301
,
year
:
new
Date
().
getFullYear
()
-
1
}
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
box2ChartData
.
value
=
{
title
:
res
.
data
.
map
(
item
=>
({
img
:
item
.
COUNTRYIMAGE
?
(
item
.
COUNTRYIMAGE
.
startsWith
(
"http"
)
?
item
.
COUNTRYIMAGE
:
`http://${item.COUNTRYIMAGE
}
`
)
:
""
,
name
:
item
.
COUNTRY
}
)),
data
:
res
.
data
.
map
(
item
=>
item
.
NUM
)
}
;
const
box2Chart
=
getBarChart
(
box2ChartData
.
value
.
title
,
box2ChartData
.
value
.
data
);
setChart
(
box2Chart
,
"box2Chart"
);
}
}
catch
(
error
)
{
console
.
error
(
"获取受调查国家分布失败"
,
error
);
}
finally
{
box2Loading
.
value
=
false
;
chartData
=
[]
}
onAIReport
({
type
:
"环形图"
,
name
:
"领域分布情况"
,
data
:
chartData
}
,
"content4"
)
nextTick
(()
=>
{
createPieChart
(
box4Chart
,
chartData
)
}
)
box4Loading
.
value
=
false
;
}
;
onMounted
(()
=>
{
...
...
@@ -321,164 +240,62 @@ onMounted(() => {
flex
-
direction
:
column
;
gap
:
16
px
;
.
box
{
width
:
792
px
;
.
content
-
list
{
height
:
410
px
;
border
:
1
px
solid
rgba
(
234
,
236
,
238
,
1
);
border
-
radius
:
10
px
;
box
-
shadow
:
0
px
0
px
20
px
0
px
rgba
(
25
,
69
,
130
,
0.1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
}
.
box
-
header
{
height
:
46
px
;
display
:
flex
;
position
:
relative
;
.
header
-
left
{
margin
-
top
:
18
px
;
width
:
8
px
;
height
:
20
px
;
border
-
radius
:
0
4
px
4
px
0
;
background
:
var
(
--
color
-
main
-
active
);
}
.
title
{
margin
-
left
:
14
px
;
margin
-
top
:
14
px
;
height
:
26
px
;
color
:
var
(
--
color
-
main
-
active
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
20
px
;
font
-
weight
:
700
;
line
-
height
:
26
px
;
}
.
warning
-
text
{
position
:
absolute
;
top
:
16
px
;
right
:
124
px
;
height
:
24
px
;
color
:
rgba
(
206
,
79
,
81
,
1
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
18
px
;
font
-
weight
:
700
;
line
-
height
:
24
px
;
letter
-
spacing
:
0
px
;
text
-
align
:
center
;
}
.
header
-
select
-
box
{
position
:
absolute
;
top
:
13
px
;
right
:
121
px
;
}
.
header
-
right
{
position
:
absolute
;
top
:
14
px
;
right
:
12
px
;
display
:
flex
;
justify
-
content
:
flex
-
end
;
gap
:
4
px
;
.
icon
{
width
:
28
px
;
height
:
28
px
;
img
{
width
:
100
%
;
height
:
100
%
;
}
}
}
}
.
box
-
footer
{
margin
:
5
px
auto
;
width
:
759
px
;
height
:
40
px
;
display
:
flex
;
flex
-
direction
:
row
;
justify
-
content
:
center
;
align
-
items
:
center
;
gap
:
10
px
;
padding
:
6
px
12
px
6
px
12
px
;
box
-
sizing
:
border
-
box
;
border
:
1
px
solid
rgba
(
231
,
243
,
255
,
1
);
border
-
radius
:
4
px
;
background
:
rgba
(
246
,
250
,
255
,
1
);
.
box
-
footer
-
left
{
width
:
19
px
;
height
:
20
px
;
img
{
width
:
100
%
;
height
:
100
%
;
}
}
.
box
-
footer
-
center
{
width
:
666
px
;
height
:
24
px
;
color
:
rgba
(
5
,
95
,
194
,
1
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
16
px
;
font
-
weight
:
400
;
line
-
height
:
24
px
;
letter
-
spacing
:
0
px
;
text
-
align
:
justify
;
}
.
box
-
footer
-
right
{
width
:
24
px
;
height
:
24
px
;
gap
:
16
px
;
img
{
.
content
-
item
{
width
:
20
px
;
flex
:
auto
;
height
:
100
%
;
.
box
-
main
{
width
:
100
%
;
height
:
100
%
;
padding
:
12
px
30
px
20
px
;
display
:
flex
;
flex
-
direction
:
column
;
position
:
relative
;
.
box
-
head
{
height
:
20
px
;
flex
:
auto
;
}
.
ai
-
pane
{
position
:
absolute
;
right
:
0
px
;
bottom
:
15
px
;
z
-
index
:
2
;
:
deep
(.
ai
-
pane
-
wrapper
)
{
display
:
none
;
}
:
deep
(.
ai
-
button
-
wrapper
)
{
display
:
flex
;
}
&
:
hover
{
width
:
100
%
;
bottom
:
0
px
;
:
deep
(.
ai
-
pane
-
wrapper
)
{
display
:
block
;
}
:
deep
(.
ai
-
button
-
wrapper
)
{
display
:
none
;
}
}
}
}
}
}
.
top
{
display
:
flex
;
justify
-
content
:
center
;
gap
:
16
px
;
.
box1
{
.
box1
-
main
{
height
:
304
px
;
// background: orange;
}
}
.
box2
{
.
box2
-
main
{
height
:
304
px
;
// background: orange;
}
}
}
.
bottom
{
display
:
flex
;
justify
-
content
:
center
;
gap
:
16
px
;
.
box3
{
.
box3
-
main
{
height
:
304
px
;
// background: orange;
}
}
.
box4
{
.
box4
-
main
{
height
:
304
px
;
// background: orange;
}
}
.
warning
-
text
{
margin
-
right
:
12
px
;
height
:
24
px
;
color
:
rgba
(
206
,
79
,
81
,
1
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
18
px
;
font
-
weight
:
700
;
line
-
height
:
24
px
;
letter
-
spacing
:
0
px
;
text
-
align
:
center
;
}
}
<
/style
>
src/views/marketAccessRestrictions/marketAccessLayout/overview/301/utils/barChart.js
浏览文件 @
86617244
...
...
@@ -3,48 +3,56 @@ import * as echarts from "echarts";
const
getBarChart
=
(
nameList
,
valueList
)
=>
{
const
option
=
{
tooltip
:
{},
title
:
{
text
:
'单位:万人'
,
left
:
660
,
top
:
10
,
textStyle
:
{
color
:
'rgba(95, 101, 108, 1)'
,
fontSize
:
14
,
fontFamily
:
'Microsoft YaHei'
,
fontstyle
:
'Regular'
,
fontWeight
:
'normal'
}
},
grid
:
{
top
:
'5%'
,
right
:
'3%'
,
bottom
:
'1%'
,
width
:
'100%'
,
height
:
'83%'
,
top
:
'15%'
,
right
:
'5%'
,
bottom
:
'2%'
,
left
:
'1%'
,
containLabel
:
true
},
yAxis
:
{
type
:
'value'
,
name
:
"项"
,
nameLocation
:
'end'
,
nameGap
:
12
,
nameTextStyle
:
{
color
:
'#666'
,
fontSize
:
14
,
fontWeight
:
400
,
padding
:
[
0
,
0
,
6
,
-
26
]
},
axisLabel
:
{
formatter
:
'{value}'
,
color
:
'#666'
,
fontSize
:
14
,
fontWeight
:
400
},
splitLine
:
{
show
:
false
show
:
true
,
lineStyle
:
{
color
:
'#e7f3ff'
,
type
:
'dashed'
,
}
},
show
:
false
},
xAxis
:
{
type
:
'category'
,
data
:
nameList
.
map
(
item
=>
{
return
item
.
name
}),
splitLine
:
{
show
:
false
},
axisTick
:
{
show
:
false
},
data
:
nameList
.
map
(
item
=>
item
.
name
),
axisLine
:
{
show
:
false
show
:
true
,
lineStyle
:
{
color
:
'#e7f3ff'
,
},
},
axisLabel
:
{
show
:
true
show
:
true
,
textStyle
:
{
color
:
'rgba(95, 101, 108, 1)'
,
fontFamily
:
'Microsoft YaHei'
,
fontsize
:
14
,
}
}
},
series
:
[{
...
...
@@ -71,8 +79,7 @@ const getBarChart = (nameList, valueList) => {
const
data
=
[];
nameList
.
forEach
((
item
,
index
)
=>
{
data
.
push
({
name
:
'icon'
,
// value: '',
name
:
`icon
${
index
}
`
,
xAxis
:
index
,
yAxis
:
valueList
[
index
],
symbol
:
`image://
${
item
.
img
}
`
,
...
...
src/views/marketAccessRestrictions/marketAccessLayout/overview/337/index.vue
浏览文件 @
86617244
<
template
>
<div
class=
"wrap"
>
<div
class=
"top"
>
<div
class=
"
content-
top"
>
<div
class=
"item"
>
<div
class=
"item-left-box"
>
<div
class=
"item-left1"
>
{{
"总调查案件数"
}}
</div>
...
...
@@ -18,63 +18,94 @@
<
/div
>
<
div
class
=
"item"
>
<
div
class
=
"item-left"
>
{{
"胜诉/和解率"
}}
<
/div
>
<
div
class
=
"item-right"
>
{{
`${windRate
}
/${cancelRate
}
`
}}
<
/div
>
<
div
class
=
"item-right"
>
{{
`${windRate
}
`
}}
<
/div
>
<
/div
>
<
/div
>
<
div
class
=
"center"
>
<
div
class
=
"box1"
v
-
loading
=
"box1Loading"
>
<
AnalysisBox
title
=
"美国对华337调查年度趋势"
>
<
div
class
=
"box1-main"
id
=
"chart1"
><
/div
>
<
div
class
=
"box1-footer"
>
<
TipTab
/>
<
div
class
=
"content-list"
>
<
div
class
=
"content-item"
v
-
loading
=
"box1Loading"
>
<
AnalysisBox
title
=
"数量变化趋势"
>
<
template
#
header
-
btn
>
<
div
class
=
"header-btn-box"
>
<
ActionButton
:
type
=
"box1Paarams.byYorM === '12' ? 'active' : 'normal'"
name
=
"按年度"
@
click
=
"handleGetStatNum('12')"
><
/ActionButton
>
<
ActionButton
:
type
=
"box1Paarams.byYorM === '0' ? 'active' : 'normal'"
name
=
"按调查"
@
click
=
"handleGetStatNum('0')"
><
/ActionButton
>
<
/div
>
<
/template
>
<
div
class
=
"box-main"
>
<
div
class
=
"box-head"
ref
=
"chart1"
><
/div
>
<
TipTab
text
=
"美对华337调查案件的数量变化趋势,数据来源:美国国际贸易委员会官网"
style
=
"margin-top: 16px;"
/>
<
div
class
=
"ai-pane"
>
<
AiButton
/>
<
AiPane
:
aiContent
=
"aiContent.content1"
/>
<
/div
>
<
/div
>
<
/AnalysisBox
>
<
/div
>
<
div
class
=
"box2"
v
-
loading
=
"box2Loading"
>
<
AnalysisBox
title
=
"调查案件领域分布"
>
<
div
class
=
"box2-main"
id
=
"chart2"
><
/div
>
<
div
class
=
"box2-footer"
>
<
TipTab
/>
<
div
class
=
"content-item"
v
-
loading
=
"box2Loading"
>
<
AnalysisBox
title
=
"领域分布情况"
>
<
template
#
header
-
btn
>
<
el
-
select
v
-
model
=
"box2Paarams.years"
@
change
=
"handleGetStatArea()"
style
=
"width:120px; margin-right:12px;"
>
<
el
-
option
v
-
for
=
"item in yearList"
:
key
=
"item.value"
:
label
=
"item.label"
:
value
=
"item.value"
/>
<
/el-select
>
<
/template
>
<
div
class
=
"box-main"
>
<
div
class
=
"box-head"
ref
=
"chart2"
><
/div
>
<
TipTab
text
=
"美对华337调查案件的领域分布情况,数据来源:美国国际贸易委员会官网"
style
=
"margin-top: -16px;"
/>
<
div
class
=
"ai-pane"
>
<
AiButton
/>
<
AiPane
:
aiContent
=
"aiContent.content2"
/>
<
/div
>
<
/div
>
<
/AnalysisBox
>
<
/div
>
<
/div
>
<
div
class
=
"
footer
"
>
<
div
class
=
"
box3
"
v
-
loading
=
"box3Loading"
>
<
AnalysisBox
title
=
"中国
公司受调查
情况"
>
<
div
class
=
"
content-list
"
>
<
div
class
=
"
content-item
"
v
-
loading
=
"box3Loading"
>
<
AnalysisBox
title
=
"中国
实体分布
情况"
>
<
template
#
header
-
btn
>
<
div
class
=
"header-btn-box"
>
<
div
class
=
"btn"
:
class
=
"{ btnActive: btnActiveName === '调查次数'
}
"
@
click
=
"handleClickBox3Btn('调查次数')"
>
调查次数
<
/div
>
<
div
class
=
"btn"
:
class
=
"{ btnActive: btnActiveName === '注册地分布'
}
"
@
click
=
"handleClickBox3Btn('注册地分布')"
>
注册地分布
<
/div
>
<
/div
>
<
el
-
select
v
-
model
=
"box3Paarams.years"
@
change
=
"handleGetStatcnOrgCount()"
style
=
"width:120px; margin-right:12px;"
>
<
el
-
option
v
-
for
=
"item in yearList"
:
key
=
"item.value"
:
label
=
"item.label"
:
value
=
"item.value"
/>
<
/el-select
>
<
el
-
select
v
-
model
=
"box3Paarams.type"
@
change
=
"handleGetStatcnOrgCount()"
style
=
"width:120px; margin-right:12px;"
>
<
el
-
option
label
=
"调查次数"
value
=
"01"
/>
<
el
-
option
label
=
"注册地分布"
value
=
"02"
/>
<
/el-select
>
<
/template
>
<
div
v
-
show
=
"btnActiveName === '调查次数'"
class
=
"box3-main"
id
=
"chart3"
><
/div
>
<
div
v
-
show
=
"btnActiveName === '注册地分布'"
class
=
"box3-main1"
>
<
div
class
=
"box3-main1-left"
>
<
div
class
=
"box3-main1-left-item"
v
-
for
=
"(item, index) in mapData"
:
key
=
"index"
>
<
div
class
=
"box3-main1-left-item-left"
>
{{
index
+
1
}}
<
/div
>
<
div
class
=
"box3-main1-left-item-center"
>
{{
item
.
name
}}
<
/div
>
<
div
class
=
"box3-main1-left-item-right"
>
{{
item
.
value
+
"次"
}}
<
div
class
=
"box-main"
>
<
div
v
-
show
=
"box3Paarams.type === '01'"
class
=
"box-head"
id
=
"chart3"
><
/div
>
<
div
v
-
show
=
"box3Paarams.type === '02'"
class
=
"box-head2"
>
<
div
class
=
"map-box-left"
>
<
div
class
=
"map-box-left-item"
v
-
for
=
"(item, index) in mapData"
:
key
=
"index"
>
<
div
class
=
"map-box-left-item-left"
>
{{
index
+
1
}}
<
/div
>
<
div
class
=
"map-box-left-item-center"
>
{{
item
.
name
}}
<
/div
>
<
div
class
=
"map-box-left-item-right"
>
{{
item
.
value
+
"次"
}}
<
/div
>
<
/div
>
<
/div
>
<
div
class
=
"map-box-right"
id
=
"chartMap"
><
/div
>
<
/div
>
<
TipTab
text
=
"美对华337调查案件的中国实体分布情况,数据来源:美国国际贸易委员会官网"
/>
<
div
class
=
"ai-pane"
>
<
AiButton
/>
<
AiPane
:
aiContent
=
"aiContent.content3"
/>
<
/div
>
<
div
class
=
"box3-main1-right"
id
=
"chartMap"
><
/div
>
<
/div
>
<
div
class
=
"box3-footer"
>
<
TipTab
/>
<
/div
>
<
/AnalysisBox
>
<
/div
>
<
div
class
=
"
box4
"
v
-
loading
=
"box4Loading"
>
<
div
class
=
"
content-item
"
v
-
loading
=
"box4Loading"
>
<
AnalysisBox
title
=
"调查结果分布"
>
<
div
class
=
"box4-main"
id
=
"chart4"
><
/div
>
<
div
class
=
"box4-footer"
>
<
TipTab
/>
<
template
#
header
-
btn
>
<
el
-
select
v
-
model
=
"box4Paarams.years"
@
change
=
"handleGetSearchResult()"
style
=
"width:120px; margin-right:12px;"
>
<
el
-
option
v
-
for
=
"item in yearList"
:
key
=
"item.value"
:
label
=
"item.label"
:
value
=
"item.value"
/>
<
/el-select
>
<
/template
>
<
div
class
=
"box-main"
>
<
div
class
=
"box-head"
ref
=
"chart4"
><
/div
>
<
TipTab
text
=
"美对华337调查案件的调查结果分布情况,数据来源:美国国际贸易委员会官网"
style
=
"margin-top: -16px;"
/>
<
div
class
=
"ai-pane"
>
<
AiButton
/>
<
AiPane
:
aiContent
=
"aiContent.content4"
/>
<
/div
>
<
/div
>
<
/AnalysisBox
>
<
/div
>
...
...
@@ -82,178 +113,37 @@
<
/div
>
<
/template
>
<
script
setup
>
import
{
ref
,
onMounted
,
nextTick
}
from
"vue"
;
import
{
ref
,
onMounted
,
nextTick
,
reactive
}
from
"vue"
;
import
setChart
from
"@/utils/setChart"
;
import
TipTab
from
"@/components/base/TipTab/index.vue"
import
AnalysisBox
from
"@/components/base/boxBackground/analysisBox.vue"
import
{
getStatCount
,
getStatcnOrgCount
,
getSearchResult
,
getStatArea
,
getStatNum
}
from
"@/api/marketAccessRestrictions"
;
import
{
getStatCount
,
getStatcnOrgCount
,
getSearchResult
,
getStatArea
,
getStatNum
}
from
"@/api/marketAccessRestrictions"
;
import
getMultiLineChart
from
"./utils/multiLineChart"
;
import
createLineChart
from
"@/views/marketAccessRestrictions/utils/baseLineChart"
;
import
createPieChart
from
"@/views/marketAccessRestrictions/utils/basePiechart.js"
;
import
getBarChart
from
"./utils/barChart"
;
import
getPieChart
from
"./utils/piechart"
;
import
getMapChart
from
"./utils/mapChart"
;
import
CompanyImg
from
"./symbol.png"
import
getGraphChart
from
"./utils/graphChart"
;
import
getGraph
from
"./utils/graph"
;
const
box1Loading
=
ref
(
false
);
const
box2Loading
=
ref
(
false
);
const
box3Loading
=
ref
(
false
);
const
box4Loading
=
ref
(
false
);
const
btnActiveName
=
ref
(
"调查次数"
);
const
nodes
=
ref
([
{
id
:
0
,
name
:
"泰丰先行"
,
// category: 0,
symbolSize
:
30
,
value
:
8
,
symbol
:
`image://${CompanyImg
}
`
,
}
,
{
id
:
1
,
name
:
"国轩高科"
,
// category: 0,
symbolSize
:
30
,
value
:
9
,
symbol
:
`image://${CompanyImg
}
`
,
}
,
{
id
:
2
,
name
:
"智方纳米"
,
// category: 2,
symbolSize
:
30
,
value
:
7
,
symbol
:
`image://${CompanyImg
}
`
,
}
,
{
id
:
3
,
name
:
"香百科技"
,
// category: 1,
symbolSize
:
30
,
value
:
6
,
symbol
:
`image://${CompanyImg
}
`
,
}
,
{
id
:
4
,
name
:
"格林滨"
,
// category: 2,
symbolSize
:
30
,
value
:
6
,
symbol
:
`image://${CompanyImg
}
`
,
}
,
{
id
:
5
,
name
:
"江西紫宸"
,
// category: 2,
symbolSize
:
30
,
value
:
7
,
symbol
:
`image://${CompanyImg
}
`
,
}
,
{
id
:
6
,
name
:
"紫江企业"
,
// category: 4,
symbolSize
:
30
,
value
:
6
,
symbol
:
`image://${CompanyImg
}
`
,
}
,
{
id
:
7
,
name
:
"大而美法案"
,
// category: 4,
symbolSize
:
50
,
value
:
5
,
symbol
:
`image://${CompanyImg
}
`
,
}
,
{
id
:
8
,
name
:
"比亚迪"
,
// category: 0,
symbolSize
:
30
,
value
:
10
,
symbol
:
`image://${CompanyImg
}
`
,
}
,
{
id
:
9
,
name
:
"铜陵有色"
,
// category: 3,
symbolSize
:
30
,
value
:
8
,
symbol
:
`image://${CompanyImg
}
`
,
}
,
{
id
:
10
,
name
:
"长盛精密"
,
// category: 1,
symbolSize
:
30
,
value
:
7
,
symbol
:
`image://${CompanyImg
}
`
,
}
,
{
id
:
11
,
name
:
"天合光能"
,
// category: 0,
symbolSize
:
30
,
value
:
8
,
symbol
:
`image://${CompanyImg
}
`
,
}
,
{
id
:
12
,
name
:
"昆仑化学"
,
// category: 2,
symbolSize
:
30
,
value
:
6
,
symbol
:
`image://${CompanyImg
}
`
,
}
,
{
id
:
13
,
name
:
"嘉源科技"
,
// category: 1,
symbolSize
:
30
,
value
:
6
,
symbol
:
`image://${CompanyImg
}
`
,
}
,
{
id
:
14
,
name
:
"华阳集团"
,
// category: 4,
symbolSize
:
30
,
value
:
7
,
symbol
:
`image://${CompanyImg
}
`
,
}
,
{
id
:
15
,
name
:
"海辰智能"
,
// category: 1,
symbolSize
:
30
,
value
:
7
,
symbol
:
`image://${CompanyImg
}
`
,
}
,
]);
const
links
=
ref
([
{
source
:
1
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'合作'
}
}
,
{
source
:
2
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'持股'
}
}
,
{
source
:
3
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'合作'
}
}
,
{
source
:
4
,
target
:
7
,
lineStyle
:
{
type
:
'dashed'
,
color
:
'#d32f2f'
}
,
label
:
{
show
:
true
,
formatter
:
'从属'
}
}
,
{
source
:
5
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'合作'
}
}
,
{
source
:
6
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'持股'
}
}
,
{
source
:
0
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'持股'
}
}
,
{
source
:
8
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'合作'
}
}
,
{
source
:
9
,
target
:
7
,
lineStyle
:
{
type
:
'dashed'
,
color
:
'#d32f2f'
}
,
label
:
{
show
:
true
,
formatter
:
'从属'
}
}
,
{
source
:
10
,
target
:
7
,
lineStyle
:
{
type
:
'dashed'
,
color
:
'#d32f2f'
}
,
label
:
{
show
:
true
,
formatter
:
'合作'
}
}
,
{
source
:
11
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'合作'
}
}
,
{
source
:
12
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'合作'
}
}
,
{
source
:
13
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'合作'
}
}
,
{
source
:
14
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'合作'
}
}
,
{
source
:
15
,
target
:
7
,
label
:
{
show
:
true
,
formatter
:
'合作'
,
color
:
'red'
,
borderColor
:
'red'
}
}
,
]);
import
AiButton
from
'@/components/base/Ai/AiButton/index.vue'
;
import
AiPane
from
'@/components/base/Ai/AiPane/index.vue'
;
import
{
getNearYearList
,
getAIReport
}
from
"@/views/marketAccessRestrictions/utils/index.ts"
;
const
yearList
=
getNearYearList
();
// 获取AI智能报告
const
aiContent
=
reactive
({
content1
:
"正在生成..."
,
content2
:
"正在生成..."
,
content3
:
"正在生成..."
,
content4
:
"正在生成..."
,
}
)
const
onAIReport
=
(
data
,
key
)
=>
{
getAIReport
(
data
).
then
(
res
=>
{
aiContent
[
key
]
=
res
}
)
}
const
provinceCoords
=
{
"北京"
:
[
116.46
,
39.92
],
...
...
@@ -296,185 +186,164 @@ const provinceCoords = {
const
totalCaseNum
=
ref
(
0
)
const
onCaseNum
=
ref
(
0
)
const
relateCnNum
=
ref
(
0
)
const
cancelRate
=
ref
(
'0%'
)
const
windRate
=
ref
(
'0%'
)
const
handleGetStat
=
async
()
=>
{
const
params
=
{
sortCode
:
'337'
}
try
{
const
res
=
await
getStatCount
(
params
)
console
.
log
(
'
337
数量统计'
,
res
);
const
res
=
await
getStatCount
(
{
sortCode
:
'337'
}
)
console
.
log
(
'数量统计'
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
totalCaseNum
.
value
=
res
.
data
.
allCaseNum
onCaseNum
.
value
=
res
.
data
.
underCaseNum
relateCnNum
.
value
=
res
.
data
.
involvinChinese
cancelRate
.
value
=
res
.
data
.
cancelNum
windRate
.
value
=
res
.
data
.
winRate
}
}
catch
(
error
)
{
console
.
error
(
'337数量统计error'
,
error
);
}
}
catch
(
error
)
{
}
}
handleGetStat
()
const
handleGetStatcnOrgCount
=
async
(
type
)
=>
{
box3Loading
.
value
=
true
;
try
{
const
res
=
await
getStatcnOrgCount
({
type
,
sortCode
:
"337"
}
);
console
.
log
(
'中国公司受调查情况'
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
if
(
type
===
"01"
)
{
chart3Data
.
value
=
{
name
:
res
.
data
.
map
(
item
=>
item
.
ORGNAME
),
value
:
res
.
data
.
map
(
item
=>
item
.
ORGCOUNT
)
}
;
nextTick
(()
=>
{
let
chart3
=
getBarChart
(
chart3Data
.
value
.
name
,
chart3Data
.
value
.
value
);
setChart
(
chart3
,
"chart3"
);
}
);
}
else
if
(
type
===
"02"
)
{
mapData
.
value
=
res
.
data
.
map
(
item
=>
{
const
name
=
item
.
ORGPROVINCE
//.replace(/省|市|自治区|特别行政区/g, "");
return
{
name
:
item
.
ORGPROVINCE
,
value
:
item
.
PROVINCECOUNT
,
coord
:
provinceCoords
[
name
]
||
[
0
,
0
]
}
;
}
);
nextTick
(()
=>
{
let
chartMap
=
getMapChart
(
mapData
.
value
);
setChart
(
chartMap
,
"chartMap"
);
}
);
}
}
}
catch
(
error
)
{
console
.
error
(
"获取中国公司受调查情况失败"
,
error
);
}
finally
{
box3Loading
.
value
=
false
;
}
}
;
const
handleClickBox3Btn
=
name
=>
{
btnActiveName
.
value
=
name
;
if
(
name
===
"调查次数"
)
{
handleGetStatcnOrgCount
(
"01"
);
}
else
{
handleGetStatcnOrgCount
(
"02"
);
}
}
;
const
chart1Data
=
ref
({
title
:
[],
data
:
[]
}
);
const
handleGetStatNum
=
async
()
=>
{
const
chart1
=
ref
(
null
);
const
box1Paarams
=
reactive
({
sortCode
:
337
,
byYorM
:
'12'
}
)
const
box1Loading
=
ref
(
false
);
const
handleGetStatNum
=
async
(
type
)
=>
{
if
(
type
)
box1Paarams
.
byYorM
=
type
box1Loading
.
value
=
true
;
let
chartData
=
{
title
:
[],
list
:
[]
}
try
{
const
res
=
await
getStatNum
({
byYorM
:
"12"
,
sortCode
:
"337"
}
);
const
res
=
await
getStatNum
(
box1Paarams
);
console
.
log
(
'数量变化趋势'
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
const
sortedData
=
res
.
data
.
sort
((
a
,
b
)
=>
parseInt
(
a
.
searchYorM
)
-
parseInt
(
b
.
searchYorM
));
chart1Data
.
value
.
title
=
sortedData
.
map
(
item
=>
item
.
searchYorM
);
chart1Data
.
value
.
data
=
[
{
name
:
"调查数量"
,
value
:
sortedData
.
map
(
item
=>
item
.
searchCount
)
}
chartData
.
title
=
sortedData
.
map
(
item
=>
item
.
searchYorM
);
chartData
.
list
=
[
{
name
:
"调查数量"
,
value
:
sortedData
.
map
(
item
=>
item
.
searchCount
)
}
];
nextTick
(()
=>
{
let
chart1
=
getMultiLineChart
(
chart1Data
.
value
.
title
,
chart1Data
.
value
.
data
[
0
].
value
);
setChart
(
chart1
,
"chart1"
);
}
);
}
else
{
chartData
.
title
=
[];
chartData
.
list
=
[];
}
}
catch
(
error
)
{
console
.
error
(
"获取年度趋势数据失败"
,
error
);
}
finally
{
box1Loading
.
value
=
false
;
chartData
.
title
=
[];
chartData
.
list
=
[];
}
onAIReport
({
type
:
"折线图"
,
name
:
"数量变化趋势"
,
data
:
chartData
}
,
"content1"
)
nextTick
(()
=>
{
createLineChart
(
chart1
,
chartData
)
}
);
box1Loading
.
value
=
false
;
}
;
const
chart2Data
=
ref
([]);
const
chart2
=
ref
(
null
);
const
box2Paarams
=
reactive
({
sortCode
:
337
,
years
:
'2025'
}
)
const
box2Loading
=
ref
(
false
);
const
handleGetStatArea
=
async
()
=>
{
box2Loading
.
value
=
true
;
let
chartData
=
[]
try
{
const
res
=
await
getStatArea
({
sortCode
:
"337"
}
);
const
res
=
await
getStatArea
(
box2Paarams
);
console
.
log
(
'领域分布情况'
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
console
.
log
(
'调查案件领域分布'
,
res
);
chart2Data
.
value
=
res
.
data
.
filter
(
item
=>
item
.
sortcode
===
"337"
||
item
.
sortname
===
"337调查"
)
.
map
(
item
=>
({
name
:
item
.
areaname
,
value
:
item
.
areacount
}
));
nextTick
(()
=>
{
let
chart2
=
getPieChart
(
chart2Data
.
value
);
setChart
(
chart2
,
"chart2"
);
}
);
chartData
=
res
.
data
.
map
(
item
=>
({
name
:
item
.
areaname
,
value
:
item
.
areacount
}
));
}
else
{
chartData
=
[];
}
}
catch
(
error
)
{
console
.
error
(
"获取调查案件领域分布失败"
,
error
);
}
finally
{
box2Loading
.
value
=
false
;
chartData
=
[];
}
onAIReport
({
type
:
"环形图"
,
name
:
"领域分布情况"
,
data
:
chartData
}
,
"content2"
)
nextTick
(()
=>
{
createPieChart
(
chart2
,
chartData
)
}
);
box2Loading
.
value
=
false
;
}
;
const
chart3Data
=
ref
({
name
:
[],
value
:
[]
}
);
const
mapData
=
ref
([]);
const
box3Paarams
=
reactive
({
sortCode
:
337
,
years
:
'2025'
,
type
:
'01'
}
)
const
box3Loading
=
ref
(
false
);
const
handleGetStatcnOrgCount
=
async
()
=>
{
box3Loading
.
value
=
true
;
if
(
box3Paarams
.
type
===
"01"
)
{
let
chartData
=
{
name
:
[],
value
:
[]
}
try
{
const
res
=
await
getStatcnOrgCount
(
box3Paarams
);
console
.
log
(
'中国实体分布情况'
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
chartData
.
name
=
res
.
data
.
map
(
item
=>
item
.
ORGNAME
)
chartData
.
value
=
res
.
data
.
map
(
item
=>
item
.
ORGCOUNT
)
}
else
{
chartData
.
name
=
[];
chartData
.
value
=
[];
}
}
catch
(
error
)
{
chartData
.
name
=
[];
chartData
.
value
=
[];
}
onAIReport
({
type
:
"柱状图"
,
name
:
"中国实体分布情况"
,
data
:
chartData
}
,
"content3"
)
nextTick
(()
=>
{
let
chart3
=
getBarChart
(
chartData
.
name
,
chartData
.
value
);
setChart
(
chart3
,
"chart3"
);
}
);
}
else
if
(
box3Paarams
.
type
===
"02"
)
{
try
{
const
res
=
await
getStatcnOrgCount
(
box3Paarams
);
console
.
log
(
'中国实体分布情况'
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
mapData
.
value
=
res
.
data
.
map
(
item
=>
{
return
{
name
:
item
.
ORGPROVINCE
,
value
:
item
.
PROVINCECOUNT
,
coord
:
provinceCoords
[
item
.
ORGPROVINCE
]
||
[
0
,
0
]
}
;
}
);
}
else
{
mapData
.
value
=
[];
}
}
catch
(
error
)
{
mapData
.
value
=
[];
}
onAIReport
({
type
:
"地图"
,
name
:
"中国实体分布情况"
,
data
:
mapData
.
value
}
,
"content3"
)
nextTick
(()
=>
{
let
chartMap
=
getMapChart
(
mapData
.
value
);
setChart
(
chartMap
,
"chartMap"
);
}
);
}
box3Loading
.
value
=
false
;
}
;
const
chart4Data
=
ref
([]);
const
chart4
=
ref
(
null
)
const
box4Paarams
=
reactive
({
sortCode
:
337
,
years
:
'2025'
}
)
const
box4Loading
=
ref
(
false
);
const
handleGetSearchResult
=
async
()
=>
{
box4Loading
.
value
=
true
;
let
chartData
=
[]
try
{
const
res
=
await
getSearchResult
({
sortCode
:
"337"
}
);
const
res
=
await
getSearchResult
(
box4Paarams
);
console
.
log
(
'调查结果分布'
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
chart4Data
.
value
=
res
.
data
.
map
(
item
=>
({
name
:
item
.
RESULTNAME
,
value
:
item
.
RESULTNUM
}
));
nextTick
(()
=>
{
let
chart4
=
getPieChart
(
chart4Data
.
value
);
setChart
(
chart4
,
"chart4"
);
}
);
chartData
=
res
.
data
.
map
(
item
=>
({
name
:
item
.
RESULTNAME
,
value
:
item
.
RESULTNUM
}
));
}
else
{
chartData
=
[];
}
}
catch
(
error
)
{
console
.
error
(
"获取调查结果分布失败"
,
error
);
}
finally
{
box4Loading
.
value
=
false
;
chartData
=
[];
}
onAIReport
({
type
:
"环形图"
,
name
:
"调查结果分布"
,
data
:
chartData
}
,
"content4"
)
nextTick
(()
=>
{
createPieChart
(
chart4
,
chartData
)
}
);
box4Loading
.
value
=
false
;
}
;
onMounted
(()
=>
{
let
graph
=
getGraphChart
(
nodes
.
value
,
links
.
value
)
setChart
(
graph
,
'graphChart'
)
handleGetStat
()
handleGetStatNum
();
handleGetStatArea
();
handleGetStatcnOrgCount
(
btnActiveName
.
value
===
"调查次数"
?
"01"
:
"02"
);
handleGetStatcnOrgCount
();
handleGetSearchResult
();
}
);
<
/script
>
...
...
@@ -488,18 +357,20 @@ onMounted(() => {
flex
-
direction
:
column
;
gap
:
16
px
;
.
top
{
.
content
-
top
{
display
:
flex
;
justify
-
content
:
space
-
between
;
gap
:
16
px
;
.
item
{
width
:
388
px
;
width
:
20
px
;
flex
:
auto
;
height
:
80
px
;
border
-
radius
:
10
px
;
box
-
shadow
:
0
px
0
px
15
px
0
px
rgba
(
60
,
87
,
126
,
0.2
);
background
:
rgba
(
255
,
255
,
255
,
1
);
position
:
relative
;
display
:
flex
;
align
-
items
:
center
;
justify
-
content
:
space
-
between
;
&
::
before
{
...
...
@@ -514,7 +385,6 @@ onMounted(() => {
.
item
-
left
{
margin
-
left
:
30
px
;
margin
-
top
:
25
px
;
height
:
24
px
;
color
:
rgba
(
59
,
65
,
75
,
1
);
font
-
family
:
Microsoft
YaHei
;
...
...
@@ -524,7 +394,6 @@ onMounted(() => {
}
.
item
-
right
{
margin
-
top
:
28
px
;
margin
-
right
:
35
px
;
height
:
24
px
;
color
:
var
(
--
color
-
main
-
active
);
...
...
@@ -536,218 +405,120 @@ onMounted(() => {
.
item
-
left
-
box
{
margin
-
left
:
30
px
;
font
-
size
:
16
px
;
line
-
height
:
24
px
;
.
item
-
left1
{
margin
-
top
:
13
px
;
height
:
24
px
;
color
:
rgba
(
59
,
65
,
75
,
1
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
16
px
;
font
-
weight
:
700
;
line
-
height
:
24
px
;
}
.
item
-
left2
{
height
:
2
px
;
color
:
rgba
(
95
,
101
,
108
,
1
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
16
px
;
font
-
weight
:
400
;
line
-
height
:
24
px
;
}
}
}
}
.
box
-
header
{
height
:
56
px
;
.
content
-
list
{
height
:
410
px
;
display
:
flex
;
position
:
relative
;
.
header
-
left
{
margin
-
top
:
18
px
;
width
:
8
px
;
height
:
20
px
;
border
-
radius
:
0
4
px
4
px
0
;
background
:
var
(
--
color
-
main
-
active
);
}
.
title
{
margin
-
left
:
14
px
;
margin
-
top
:
14
px
;
height
:
26
px
;
line
-
height
:
26
px
;
color
:
var
(
--
color
-
main
-
active
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
20
px
;
font
-
weight
:
700
;
}
.
header
-
right
{
position
:
absolute
;
top
:
14
px
;
right
:
12
px
;
display
:
flex
;
justify
-
content
:
flex
-
end
;
gap
:
4
px
;
.
icon
{
width
:
28
px
;
height
:
28
px
;
img
{
width
:
100
%
;
height
:
100
%
;
gap
:
16
px
;
.
content
-
item
{
width
:
20
px
;
flex
:
auto
;
height
:
100
%
;
.
box
-
main
{
width
:
100
%
;
height
:
100
%
;
padding
:
12
px
30
px
20
px
;
display
:
flex
;
flex
-
direction
:
column
;
position
:
relative
;
.
box
-
head
{
height
:
20
px
;
flex
:
auto
;
}
.
ai
-
pane
{
position
:
absolute
;
right
:
0
px
;
bottom
:
15
px
;
z
-
index
:
2
;
:
deep
(.
ai
-
pane
-
wrapper
)
{
display
:
none
;
}
:
deep
(.
ai
-
button
-
wrapper
)
{
display
:
flex
;
}
&
:
hover
{
width
:
100
%
;
bottom
:
0
px
;
:
deep
(.
ai
-
pane
-
wrapper
)
{
display
:
block
;
}
:
deep
(.
ai
-
button
-
wrapper
)
{
display
:
none
;
}
}
}
}
}
}
.
center
{
.
header
-
btn
-
box
{
display
:
flex
;
justify
-
content
:
space
-
between
;
.
box1
{
width
:
792
px
;
height
:
360
px
;
.
box1
-
main
{
height
:
263
px
;
}
.
box1
-
footer
{
height
:
40
px
;
}
}
.
box2
{
width
:
792
px
;
height
:
360
px
;
.
box2
-
main
{
width
:
792
px
;
height
:
263
px
;
box
-
sizing
:
border
-
box
;
padding
:
0
24
px
;
}
.
box2
-
footer
{
height
:
40
px
;
}
}
gap
:
12
px
;
margin
-
right
:
12
px
;
}
.
footer
{
.
box
-
head2
{
height
:
100
%
;
width
:
100
%
;
padding
-
top
:
10
px
;
display
:
flex
;
justify
-
content
:
space
-
between
;
.
box3
{
width
:
792
px
;
height
:
360
px
;
.
map
-
box
-
left
{
width
:
20
px
;
flex
:
auto
;
height
:
100
%
;
.
header
-
btn
-
box
{
.
map
-
box
-
left
-
item
{
display
:
flex
;
align
-
items
:
center
;
height
:
36
px
;
margin
-
left
:
20
px
;
.
btn
{
margin
-
left
:
8
px
;
height
:
28
px
;
padding
:
0
8
px
;
box
-
sizing
:
border
-
box
;
border
:
1
px
solid
rgba
(
230
,
231
,
232
,
1
);
border
-
radius
:
4
px
;
background
:
rgba
(
255
,
255
,
255
,
1
);
.
map
-
box
-
left
-
item
-
left
{
width
:
24
px
;
height
:
24
px
;
border
-
radius
:
12
px
;
background
:
#
e7f3ff
;
margin
-
right
:
12
px
;
color
:
#
0
a57a6
;
text
-
align
:
center
;
line
-
height
:
28
px
;
color
:
rgba
(
59
,
65
,
75
,
1
);
font
-
family
:
Microsoft
YaHei
;
font
-
size
:
16
px
;
font
-
weight
:
400
;
cursor
:
pointer
;
}
.
btnActive
{
border
:
1
px
solid
var
(
--
color
-
main
-
active
);
background
:
rgba
(
246
,
250
,
255
,
1
);
color
:
var
(
--
color
-
main
-
active
);
}
}
.
box3
-
main
{
height
:
263
px
;
}
.
box3
-
main1
{
height
:
263
px
;
display
:
flex
;
.
box3
-
main1
-
left
{
padding
-
top
:
24
px
;
width
:
380
px
;
height
:
263
px
;
// overflow-y: auto;
overflow
-
x
:
hidden
;
.
box3
-
main1
-
left
-
item
{
display
:
flex
;
height
:
36
px
;
margin
-
left
:
20
px
;
.
box3
-
main1
-
left
-
item
-
left
{
width
:
24
px
;
height
:
24
px
;
border
-
radius
:
12
px
;
margin
-
left
:
12
px
;
margin
-
top
:
6
px
;
background
:
#
e7f3ff
;
color
:
#
0
a57a6
;
text
-
align
:
center
;
line
-
height
:
24
px
;
}
.
box3
-
main1
-
left
-
item
-
center
{
height
:
36
px
;
line
-
height
:
36
px
;
width
:
220
px
;
margin
-
left
:
12
px
;
}
.
box3
-
main1
-
left
-
item
-
right
{
width
:
80
px
;
box
-
sizing
:
border
-
box
;
padding
-
right
:
10
px
;
text
-
align
:
right
;
}
}
line
-
height
:
24
px
;
}
.
box3
-
main1
-
right
{
width
:
390
px
;
height
:
263
px
;
box
-
sizing
:
border
-
box
;
padding
-
top
:
24
px
;
padding
-
right
:
24
px
;
.
map
-
box
-
left
-
item
-
center
{
height
:
36
px
;
line
-
height
:
36
px
;
width
:
20
px
;
flex
:
auto
;
}
.
box3
-
footer
{
height
:
40
px
;
.
map
-
box
-
left
-
item
-
right
{
min
-
width
:
80
px
;
padding
-
right
:
10
px
;
text
-
align
:
right
;
}
}
}
.
box4
{
width
:
792
px
;
height
:
360
px
;
.
box4
-
main
{
height
:
263
px
;
box
-
sizing
:
border
-
box
;
padding
:
0
24
px
;
}
.
box4
-
footer
{
height
:
40
px
;
}
.
map
-
box
-
right
{
width
:
450
px
;
height
:
100
%
;
}
}
}
...
...
src/views/marketAccessRestrictions/marketAccessLayout/overview/337/utils/barChart.js
浏览文件 @
86617244
...
...
@@ -43,7 +43,7 @@ const getBarChart = (nameList, valueList) => {
data
:
valueList
,
label
:
{
show
:
true
,
position
:
[
4
80
,
0
],
position
:
[
4
34
,
0
],
formatter
:
function
(
params
)
{
return
params
.
value
+
' 次'
},
...
...
src/views/marketAccessRestrictions/pages/reportOriginal.vue
0 → 100644
浏览文件 @
86617244
<
template
>
<div
class=
"page-box"
>
<div
class=
"page-top"
>
<div
class=
"head-box"
>
<div
class=
"head-icon"
>
<img
:src=
"codeInfo.sortImageUrl || Img337"
alt=
""
/>
</div>
<div
class=
"head-info"
>
<div
class=
"head-name one-line-ellipsis"
>
{{
baseInfo
.
SEARCHNAME
}}
</div>
<div
class=
"head-text"
>
{{
baseInfo
.
SEARCHDATE
}}
</div>
</div>
<div
:class=
"`item-tag tag-$
{codeInfo.sortCode}`">
{{
codeInfo
.
sortName
}}
</div>
</div>
</div>
<div
class=
"main"
>
<div
class=
"main-header"
>
<div>
市场准入限制报告原文
</div>
<div
class=
"btn-box"
>
<div
class=
"translate"
>
<div
class=
"search-input-wrap"
v-if=
"showSearchInput"
>
<input
v-model=
"searchKeywordText"
class=
"search-input"
placeholder=
"回车查询"
@
keyup
.
enter=
"handleSearchInPdf"
/>
<div
class=
"search-match-count"
>
{{
matchInfo
.
current
}}
/
{{
matchInfo
.
total
}}
</div>
<button
class=
"search-nav-btn"
type=
"button"
@
click=
"handlePrevMatch"
:disabled=
"matchInfo.total === 0 || matchInfo.current
<
=
1
"
>
上一个
</button>
<button
class=
"search-nav-btn"
type=
"button"
@
click=
"handleNextMatch"
:disabled=
"matchInfo.total === 0 || matchInfo.current >= matchInfo.total"
>
下一个
</button>
</div>
<div
class=
"switch"
>
<el-switch
v-model=
"valueSwitch"
/>
</div>
<div
class=
"translate-image"
>
<img
class=
"translate-icon"
src=
"@/views/thinkTank/ReportDetail/images/image-translate.png"
alt=
""
style=
"width: 16px; height: 16px; max-width: 16px; max-height: 16px; display: block; object-fit: contain;"
/>
</div>
<div
class=
"translate-text"
>
{{
"显示原文"
}}
</div>
</div>
<div
class=
"btn"
@
click=
"handleDownload"
>
<div
class=
"icon"
>
<img
src=
"@/views/thinkTank/ReportDetail/images/image-pdf.png"
alt=
""
/>
</div>
<div
class=
"text"
>
{{
"下载"
}}
</div>
</div>
</div>
</div>
<div
class=
"report-box"
>
<div
class=
"pdf-pane-wrap"
v-if=
"valueSwitch && reportUrlEnWithPage"
>
<pdf
ref=
"leftPdfRef"
:pdfUrl=
"reportUrlEnWithPage"
class=
"pdf-pane-inner"
/>
</div>
<div
class=
"pdf-pane-wrap"
:class=
"
{ 'is-full': !valueSwitch }" v-if="reportUrlWithPage">
<pdf
:key=
"`right-pdf-$
{valueSwitch ? 'split' : 'full'}`" ref="rightPdfRef" :pdfUrl="reportUrlWithPage"
class="pdf-pane-inner" />
</div>
</div>
</div>
</div>
</
template
>
<
script
setup
>
import
{
computed
,
ref
,
onMounted
,
watch
,
reactive
}
from
"vue"
;
import
pdf
from
"@/views/thinkTank/reportOriginal/pdf.vue"
;
import
{
getSurvyInfo
,
getOriginalUrl
}
from
"@/api/marketAccessRestrictions/index.js"
;
import
{
useRoute
}
from
"vue-router"
;
const
route
=
useRoute
();
const
reportUrl
=
ref
(
''
)
const
reportUrlEn
=
ref
(
''
)
const
thinkInfo
=
ref
({})
const
defaultPdfPage
=
ref
(
1
)
const
buildPdfPageUrl
=
url
=>
{
if
(
!
url
)
return
''
return
`
${
url
}
#page=
${
defaultPdfPage
.
value
}
`
}
const
reportUrlWithPage
=
computed
(()
=>
buildPdfPageUrl
(
reportUrl
.
value
))
const
reportUrlEnWithPage
=
computed
(()
=>
buildPdfPageUrl
(
reportUrlEn
.
value
))
const
valueSwitch
=
ref
(
true
)
const
showSearchInput
=
ref
(
true
)
const
searchKeywordText
=
ref
(
''
)
const
leftPdfRef
=
ref
(
null
)
const
rightPdfRef
=
ref
(
null
)
const
matchInfo
=
ref
({
current
:
0
,
total
:
0
})
const
activePdfRef
=
ref
(
null
)
const
clearPdfSearchState
=
()
=>
{
activePdfRef
.
value
=
null
matchInfo
.
value
=
{
current
:
0
,
total
:
0
}
const
leftPdf
=
leftPdfRef
.
value
const
rightPdf
=
rightPdfRef
.
value
if
(
leftPdf
&&
typeof
leftPdf
.
clearSearch
===
'function'
)
{
leftPdf
.
clearSearch
()
}
if
(
rightPdf
&&
typeof
rightPdf
.
clearSearch
===
'function'
)
{
rightPdf
.
clearSearch
()
}
}
const
updateMatchInfo
=
()
=>
{
const
pdf
=
activePdfRef
.
value
if
(
pdf
&&
typeof
pdf
.
getMatchInfo
===
'function'
)
{
matchInfo
.
value
=
pdf
.
getMatchInfo
()
return
}
matchInfo
.
value
=
{
current
:
0
,
total
:
0
}
}
watch
(
()
=>
searchKeywordText
.
value
,
(
val
)
=>
{
const
keyword
=
String
(
val
??
''
).
trim
()
if
(
!
keyword
)
{
clearPdfSearchState
()
}
}
)
watch
(
()
=>
valueSwitch
.
value
,
()
=>
{
// 切换「显示原文」会导致 PDF 重新挂载/布局变化:清空搜索与计数,回到初始状态
searchKeywordText
.
value
=
''
clearPdfSearchState
()
}
)
const
handleSearchInPdf
=
async
()
=>
{
const
keyword
=
searchKeywordText
.
value
?.
trim
()
if
(
!
keyword
)
return
activePdfRef
.
value
=
null
matchInfo
.
value
=
{
current
:
0
,
total
:
0
}
const
leftPdf
=
leftPdfRef
.
value
const
rightPdf
=
rightPdfRef
.
value
let
page
=
0
let
targetRef
=
null
if
(
leftPdf
&&
typeof
leftPdf
.
searchKeyword
===
'function'
)
{
page
=
await
leftPdf
.
searchKeyword
(
keyword
)
if
(
page
)
targetRef
=
leftPdf
}
if
(
!
page
&&
rightPdf
&&
typeof
rightPdf
.
searchKeyword
===
'function'
)
{
page
=
await
rightPdf
.
searchKeyword
(
keyword
)
if
(
page
)
targetRef
=
rightPdf
}
if
(
page
&&
targetRef
&&
typeof
targetRef
.
goToPage
===
'function'
)
{
targetRef
.
goToPage
(
page
)
activePdfRef
.
value
=
targetRef
updateMatchInfo
()
}
else
{
try
{
const
{
ElMessage
}
=
await
import
(
'element-plus'
)
ElMessage
.
warning
(
'未找到包含该关键词的页面'
)
}
catch
(
_
)
{
}
}
}
const
handlePrevMatch
=
()
=>
{
const
pdf
=
activePdfRef
.
value
if
(
!
pdf
||
typeof
pdf
.
prevMatch
!==
'function'
)
return
pdf
.
prevMatch
()
updateMatchInfo
()
}
const
handleNextMatch
=
()
=>
{
const
pdf
=
activePdfRef
.
value
if
(
!
pdf
||
typeof
pdf
.
nextMatch
!==
'function'
)
return
pdf
.
nextMatch
()
updateMatchInfo
()
}
// 下载:中英文都下载,与政令原文页相同的 fetch → blob → a 标签触发下载
const
downloadOnePdf
=
async
(
url
,
filename
)
=>
{
const
response
=
await
fetch
(
url
,
{
method
:
'GET'
,
headers
:
{
'Content-Type'
:
'application/pdf'
},
})
if
(
!
response
.
ok
)
throw
new
Error
(
`HTTP error! status:
${
response
.
status
}
`
)
const
blob
=
await
response
.
blob
()
const
blobUrl
=
window
.
URL
.
createObjectURL
(
blob
)
const
link
=
document
.
createElement
(
'a'
)
link
.
href
=
blobUrl
link
.
download
=
filename
document
.
body
.
appendChild
(
link
)
link
.
click
()
document
.
body
.
removeChild
(
link
)
window
.
URL
.
revokeObjectURL
(
blobUrl
)
}
const
handleDownload
=
async
()
=>
{
const
urlZh
=
reportUrl
.
value
?
String
(
reportUrl
.
value
).
split
(
'#'
)[
0
]
:
''
const
urlEn
=
reportUrlEn
.
value
?
String
(
reportUrlEn
.
value
).
split
(
'#'
)[
0
]
:
''
if
(
!
urlZh
&&
!
urlEn
)
{
try
{
const
{
ElMessage
}
=
await
import
(
'element-plus'
)
ElMessage
.
warning
(
'暂无下载链接'
)
}
catch
(
_
)
{
}
return
}
const
baseName
=
(
thinkInfo
.
value
?.
name
||
'报告原文'
).
replace
(
/
[/\\
?%*:|"<>
]
/g
,
'-'
)
const
{
ElMessage
}
=
await
import
(
'element-plus'
)
try
{
if
(
urlZh
)
{
await
downloadOnePdf
(
urlZh
,
`
${
baseName
}
_中文.pdf`
)
}
if
(
urlEn
)
{
if
(
urlZh
)
await
new
Promise
(
r
=>
setTimeout
(
r
,
300
))
await
downloadOnePdf
(
urlEn
,
`
${
baseName
}
_英文.pdf`
)
}
if
(
urlZh
||
urlEn
)
{
ElMessage
.
success
(
urlZh
&&
urlEn
?
'已下载中文、英文两份 PDF'
:
'下载成功'
)
}
}
catch
(
error
)
{
console
.
error
(
'下载失败:'
,
error
)
ElMessage
.
error
(
'PDF 下载失败,请稍后重试'
)
}
}
// 获取调查信息
const
codeInfo
=
reactive
({
sortCode
:
route
.
query
.
id
,
sortName
:
""
,
sortImageUrl
:
""
,
})
const
onSurvyInfo
=
async
()
=>
{
try
{
const
res
=
await
getSurvyInfo
({
sortCode
:
route
.
query
.
id
});
console
.
log
(
"获取调查信息"
,
res
);
if
(
res
.
code
==
200
)
{
Object
.
assign
(
codeInfo
,
res
.
data
)
}
}
catch
(
error
)
{
console
.
error
(
"获取调查信息error"
,
error
);
}
};
//获取原文
const
baseInfo
=
reactive
({
SEARCHNAME
:
"调查详情"
,
SEARCHDATE
:
""
,
})
const
onOriginalUrl
=
async
()
=>
{
try
{
const
res
=
await
getOriginalUrl
({
id
:
route
.
query
.
searchId
});
console
.
log
(
"获取原文"
,
res
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
reportUrl
.
value
=
res
.
data
.
urlZh
reportUrlEn
.
value
=
res
.
data
.
url
baseInfo
.
SEARCHNAME
=
res
.
data
.
investTitleZh
baseInfo
.
SEARCHDATE
=
res
.
data
.
investDate
}
document
.
title
=
baseInfo
.
SEARCHNAME
;
}
catch
(
error
)
{
console
.
error
(
"获取原文error"
,
error
);
}
};
onMounted
(()
=>
{
onSurvyInfo
()
onOriginalUrl
()
});
</
script
>
<
style
lang=
"scss"
scoped
>
.page-box
{
width
:
100%
;
height
:
100%
;
display
:
flex
;
flex-direction
:
column
;
background-color
:
#f7f8f9
;
.page-top
{
width
:
100%
;
box-sizing
:
border-box
;
background-color
:
white
;
.head-box
{
width
:
1600px
;
display
:
flex
;
margin
:
0
auto
;
padding
:
30px
0
20px
;
.head-icon
{
width
:
54px
;
height
:
54px
;
font-size
:
0px
;
margin-right
:
16px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.head-info
{
width
:
20px
;
flex
:
auto
;
.head-name
{
width
:
100%
;
height
:
26px
;
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
20px
;
font-weight
:
bold
;
line-height
:
26px
;
}
.head-text
{
margin-top
:
4px
;
width
:
100%
;
height
:
24px
;
color
:
rgba
(
95
,
101
,
108
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
24px
;
}
}
.item-tag
{
height
:
24px
;
line-height
:
24px
;
padding
:
0
8px
;
border-radius
:
4px
;
font-weight
:
bold
;
font-size
:
16px
;
letter-spacing
:
2px
;
}
.tag-337
{
border
:
1px
solid
#91caff
;
background
:
#e6f4ff
;
color
:
#055fc2
;
}
.tag-232
{
border
:
1px
solid
#b37feb
;
background
:
#f9f0ff
;
color
:
#722ed1
;
}
.tag-301
{
border
:
1px
solid
#ffd591
;
background
:
#fff7e6
;
color
:
#fa8c16
;
}
.head-button
{
margin-left
:
100px
;
width
:
120px
;
height
:
36px
;
border-radius
:
6px
;
background
:
var
(
--
color-main-active
);
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
cursor
:
pointer
;
.button-icon
{
width
:
16px
;
height
:
16px
;
font-size
:
0
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.button-text
{
margin-left
:
8px
;
color
:
rgba
(
255
,
255
,
255
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
}
}
}
}
.main
{
margin
:
0
auto
;
background
:
rgb
(
255
,
255
,
255
);
width
:
1600px
;
height
:
20px
;
flex
:
auto
;
border
:
1px
,
solid
,
rgb
(
234
,
236
,
238
);
box-shadow
:
0
0
20px
0
rgba
(
25
,
69
,
130
,
0
.1
);
display
:
flex
;
flex-direction
:
column
;
.main-header
{
height
:
64px
;
border-bottom
:
1px
solid
rgb
(
234
,
236
,
238
);
background
:
rgb
(
255
,
255
,
255
);
margin
:
0
70px
;
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
"Source Han Sans CN"
;
font-style
:
Bold
;
font-size
:
20px
;
font-weight
:
700
;
line-height
:
26px
;
letter-spacing
:
0px
;
width
:
1456px
;
text-align
:
left
;
display
:
flex
;
justify-content
:
space-between
;
align-items
:
center
;
overflow
:
visible
;
.btn-box
{
display
:
flex
;
align-items
:
center
;
gap
:
8px
;
flex-shrink
:
0
;
.translate
{
display
:
flex
;
flex-wrap
:
nowrap
;
align-items
:
center
;
height
:
24px
;
margin-right
:
16px
;
flex-shrink
:
0
;
:deep
(
.el-switch
)
{
width
:
22px
!
important
;
height
:
14px
!
important
;
margin-bottom
:
5px
;
margin-right
:
8px
;
}
:deep
(
.el-switch__core
)
{
width
:
22px
!
important
;
height
:
14px
!
important
;
min-width
:
22px
!
important
;
}
:deep
(
.el-switch__button
),
:deep
(
.el-switch__action
)
{
width
:
10px
!
important
;
height
:
10px
!
important
;
}
/* 打开时圆球从左边移到最右边:轨道 22px - 圆球 10px = 12px */
:deep
(
.el-switch.is-checked
.el-switch__button
),
:deep
(
.el-switch.is-checked
.el-switch__action
)
{
transform
:
translateX
(
6px
)
!
important
;
}
.translate-image
{
display
:
flex
;
width
:
16px
;
height
:
16px
;
overflow
:
hidden
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.translate-text
{
font-size
:
14px
;
font-weight
:
400
;
line-height
:
22px
;
}
}
.btn
{
width
:
88px
;
height
:
32px
;
border
:
1px
solid
rgba
(
230
,
231
,
232
,
1
);
border-radius
:
6px
;
background
:
rgba
(
255
,
255
,
255
,
1
);
display
:
flex
;
gap
:
8px
;
cursor
:
pointer
;
;
.icon
{
width
:
16px
;
height
:
16px
;
display
:
inline-flex
;
margin-top
:
8px
;
margin-left
:
16px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
.text
{
margin-top
:
4px
;
width
:
32px
;
height
:
24px
;
color
:
rgb
(
59
,
65
,
75
);
font-family
:
"Source Han Sans CN"
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
24px
;
letter-spacing
:
0px
;
text-align
:
left
;
}
}
.search-btn
{
cursor
:
pointer
;
}
.search-input-wrap
{
display
:
inline-flex
;
align-items
:
center
;
gap
:
8px
;
margin-left
:
4px
;
flex-shrink
:
0
;
}
.search-input
{
width
:
160px
;
height
:
24px
;
border
:
1px
solid
rgba
(
231
,
243
,
255
,
1
);
background
:
rgba
(
246
,
250
,
255
,
1
);
border-radius
:
4px
;
padding
:
0
10px
;
font-family
:
"Source Han Sans CN"
;
font-size
:
14px
;
line-height
:
22px
;
outline
:
none
;
}
.search-match-count
{
font-family
:
"Source Han Sans CN"
;
font-weight
:
400
;
font-size
:
14px
;
line-height
:
22px
;
min-width
:
48px
;
text-align
:
center
;
flex-shrink
:
0
;
}
.search-nav-btn
{
width
:
68px
;
height
:
24px
;
border
:
1px
solid
rgba
(
231
,
243
,
255
,
1
);
background
:
rgba
(
246
,
250
,
255
,
1
);
border-radius
:
4px
;
font-family
:
"Source Han Sans CN"
;
font-weight
:
400
;
font-size
:
14px
;
line-height
:
22px
;
cursor
:
pointer
;
padding
:
0
;
flex-shrink
:
0
;
white-space
:
nowrap
;
}
.search-nav-btn
:disabled
{
opacity
:
0
.45
;
cursor
:
not
-
allowed
;
}
}
}
.report-box
{
height
:
20px
;
flex
:
auto
;
margin-left
:
70px
;
width
:
1456px
;
display
:
flex
;
overflow-y
:
auto
;
/* 右侧统一滚动条,控制两侧原文+译文一起滚动 */
overflow-x
:
hidden
;
}
.pdf-pane-wrap
{
flex
:
0
0
50%
;
max-width
:
50%
;
height
:
100%
;
min-width
:
0
;
}
.pdf-pane-wrap.is-full
{
flex
:
0
0
100%
;
max-width
:
100%
;
}
.pdf-pane-inner
{
width
:
100%
;
height
:
100%
;
}
}
}
</
style
>
\ No newline at end of file
src/views/marketAccessRestrictions/singleCaseLayout/deepdig/232/index.vue
浏览文件 @
86617244
...
...
@@ -2,10 +2,8 @@
<div
class=
"wrapper"
>
<AnalysisBox
title=
"行业背景"
:showAllBtn=
"false"
height=
"auto"
>
<div
class=
"box1-main"
>
<div
class=
"data-list"
>
<div
class=
"data-item"
v-for=
"(bg, index) in bgList"
:key=
"index"
>
{{
bg
.
title
}}
</div>
</div>
<AiTips
tips=
"钒作为被美国列为对经济与国家安全至关重要且供应链易受中断的关键矿产,广泛应用于国防、关键基础设施等多个领域,美国钒产业以二次生产为主、产业高度集中且依赖进口原料,同时通过征收反倾销税、加征关税及签订国际合作协议等方式管控钒进口。"
></AiTips>
<Level2List
:list=
"bgList"
></Level2List>
<!--
<AiTips
tips=
"钒作为被美国列为对经济与国家安全至关重要且供应链易受中断的关键矿产,广泛应用于国防、关键基础设施等多个领域,美国钒产业以二次生产为主、产业高度集中且依赖进口原料,同时通过征收反倾销税、加征关税及签订国际合作协议等方式管控钒进口。"
></AiTips>
-->
</div>
</AnalysisBox>
<SurveyConclusion
title=
"市场需求"
:listData=
"demandList"
tips=
"美国钒市场年均表观消费量约 8590 吨且进口依赖度超 80%,需求主要集中在钢铁产业(占 90%),钛产业和非冶金领域各占 5%,2020 年受新冠疫情冲击需求下滑;全球钒需求以钢铁产业为主(90%-93%),中国是最大消费国,航空航天领域需求稳定、钒液流电池为新兴增长点,化工领域提供稳定补充。"
></SurveyConclusion>
...
...
@@ -17,7 +15,7 @@
<div
class=
"data-item"
v-for=
"(item, index) in suggestionList"
:key=
"index"
>
<div
class=
"item-head"
>
<div
class=
"item-name"
>
{{
item
.
title
}}
</div>
<div
class=
"button-box"
>
<div
class=
"button-box"
@
click=
"onNavigateTo()"
>
<div
class=
"button-icon"
>
<img
src=
"@/views/marketAccessRestrictions/assets/icons/open.png"
alt=
""
/>
</div>
...
...
@@ -26,16 +24,14 @@
</div>
<div
class=
"item-down"
>
<div
class=
"content-item"
v-for=
"(val, idx) in item.data"
:key=
"idx"
>
<div
class=
"content-item-title"
>
{{
val
.
title
}}
</div>
<div
class=
"content-item-title"
>
{{
val
.
TITLE
}}
</div>
<div
class=
"content-item-info"
>
<div
class=
"desc"
>
{{
val
.
info
.
desc
}}
</div>
<div
class=
"info-bill"
v-if=
"val.info.bill"
>
<div
class=
"info-bill-box"
>
<div
class=
"info-bill-left"
>
{{
"法案"
}}
</div>
<div
class=
"info-bill-center"
>
{{
val
.
info
.
bill
}}
</div>
<div
class=
"info-bill-right"
>
<img
src=
"@/assets/icons/box-footer-right-icon.png"
alt=
""
/>
</div>
<Level2List
:list=
"val.CONTENT"
></Level2List>
<div
class=
"info-bill-box"
v-if=
"val.BILLNAME && val.BILLID"
@
click=
"onNavigateToBill(val)"
>
<div
class=
"info-bill-left"
>
{{
"法案"
}}
</div>
<div
class=
"info-bill-center"
>
{{
val
.
BILLNAME
}}
</div>
<div
class=
"info-bill-right"
>
<img
src=
"@/assets/icons/box-footer-right-icon.png"
alt=
""
/>
</div>
</div>
</div>
...
...
@@ -43,7 +39,7 @@
</div>
</div>
</div>
<
AiTips
tips=
"美国为降低盟友及自身在钕铁硼磁体价值链对中国的依赖、保障国家安全,一方面推动关键矿物多边及双边合作,另一方面通过支持相关税收抵免法案、分配额外资金等立法与政策举措,强化稀土及非稀土磁体相关国内供应链建设。"
></AiTips
>
<
!--
<AiTips
tips=
"美国为降低盟友及自身在钕铁硼磁体价值链对中国的依赖、保障国家安全,一方面推动关键矿物多边及双边合作,另一方面通过支持相关税收抵免法案、分配额外资金等立法与政策举措,强化稀土及非稀土磁体相关国内供应链建设。"
></AiTips>
--
>
</div>
</AnalysisBox>
</div>
...
...
@@ -52,9 +48,11 @@
<
script
setup
>
import
{
ref
,
onMounted
}
from
"vue"
;
import
{
useRoute
}
from
"vue-router"
;
import
router
from
"@/router"
;
import
{
getReportAnalyze
}
from
"@/api/marketAccessRestrictions/index.js"
;
import
SurveyConclusion
from
"@/views/marketAccessRestrictions/com/SurveyConclusion.vue"
;
import
AiTips
from
"@/views/marketAccessRestrictions/com/AiTips.vue"
;
import
Level2List
from
"@/views/marketAccessRestrictions/com/Level2List.vue"
;
const
route
=
useRoute
();
const
searchId
=
route
.
query
.
searchId
||
"232"
;
...
...
@@ -65,14 +63,19 @@ const supplyList = ref([]);
const
box4List
=
ref
([]);
const
suggestionList
=
ref
([]);
const
onNavigateTo
=
()
=>
{
const
page
=
router
.
resolve
({
name
:
"MarketSingleReportOriginal"
,
query
:
{
...
route
.
query
}
});
window
.
open
(
page
.
href
,
"_blank"
);
}
const
getData
=
async
()
=>
{
// 行业背景
getReportAnalyze
({
searchId
,
type
:
"01"
}).
then
((
res
)
=>
{
if
(
res
.
data
)
{
bgList
.
value
=
res
.
data
.
map
((
item
)
=>
({
title
:
item
.
CONTENT
}));
}
console
.
log
(
'行业背景'
,
res
)
if
(
res
.
data
)
bgList
.
value
=
res
.
data
.
flatMap
(
item
=>
item
.
CONTENT
);
});
// 市场需求
...
...
@@ -81,7 +84,7 @@ const getData = async () => {
demandList
.
value
=
res
.
data
.
map
(
item
=>
{
return
{
title
:
item
.
TITLE
,
data
:
item
.
CONTENT
?.
split
(
/
\r\n
|
\n
/
).
filter
(
line
=>
line
.
trim
())
||
[],
data
:
item
.
CONTENT
||
[],
};
});
}
...
...
@@ -93,7 +96,7 @@ const getData = async () => {
supplyList
.
value
=
res
.
data
.
map
(
item
=>
{
return
{
title
:
item
.
TITLE
,
data
:
item
.
CONTENT
?.
split
(
/
\r\n
|
\n
/
).
filter
(
line
=>
line
.
trim
())
||
[],
data
:
item
.
CONTENT
||
[],
};
});
}
...
...
@@ -105,7 +108,7 @@ const getData = async () => {
box4List
.
value
=
res
.
data
.
map
(
item
=>
{
return
{
title
:
item
.
TITLE
,
data
:
item
.
CONTENT
?.
split
(
/
\r\n
|
\n
/
).
filter
(
line
=>
line
.
trim
())
||
[],
data
:
item
.
CONTENT
||
[],
};
});
}
...
...
@@ -113,27 +116,20 @@ const getData = async () => {
// 调查建议
getReportAnalyze
({
searchId
,
type
:
"05"
}).
then
((
res
)
=>
{
if
(
res
.
data
)
{
console
.
log
(
'调查建议'
,
res
)
if
(
res
.
code
==
200
&&
res
.
data
)
{
suggestionList
.
value
=
groupSuggestionData
(
res
.
data
);
}
});
};
const
groupData
=
(
data
)
=>
{
const
groups
=
{};
data
.
forEach
((
item
)
=>
{
const
title
=
item
.
TITLE
||
"其他"
;
if
(
!
groups
[
title
])
{
groups
[
title
]
=
[];
}
groups
[
title
].
push
({
title
:
item
.
CONTENT
});
// 跳转科技法案详情页
const
onNavigateToBill
=
(
item
)
=>
{
window
.
sessionStorage
.
setItem
(
"curTabName"
,
item
.
BILLNAME
);
const
route
=
router
.
resolve
({
path
:
"/billLayout"
,
query
:
{
billId
:
item
.
BILLID
}
});
return
Object
.
keys
(
groups
).
map
((
title
)
=>
({
title
,
data
:
groups
[
title
]
}));
window
.
open
(
route
.
href
,
"_blank"
);
};
const
groupSuggestionData
=
(
data
)
=>
{
...
...
@@ -143,13 +139,7 @@ const groupSuggestionData = (data) => {
if
(
!
groups
[
groupTitle
])
{
groups
[
groupTitle
]
=
[];
}
groups
[
groupTitle
].
push
({
title
:
item
.
TITLE
,
info
:
{
desc
:
item
.
CONTENT
,
bill
:
item
.
BILLNAME
}
});
groups
[
groupTitle
].
push
(
item
);
});
return
Object
.
keys
(
groups
).
map
((
title
)
=>
({
title
,
...
...
@@ -173,22 +163,6 @@ onMounted(() => {
.box1-main
{
padding
:
0
22px
20px
;
.data-list
{
margin-bottom
:
16px
;
border-top
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
.data-item
{
letter-spacing
:
1px
;
padding
:
12px
20px
12px
40px
;
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
Source
Han
Sans
CN
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
30px
;
letter-spacing
:
0px
;
text-align
:
justify
;
border-bottom
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
}
}
}
.box5-main
{
...
...
@@ -217,6 +191,7 @@ onMounted(() => {
display
:
flex
;
align-items
:
center
;
margin-left
:
50px
;
cursor
:
pointer
;
.button-icon
{
width
:
16px
;
height
:
16px
;
...
...
@@ -240,7 +215,7 @@ onMounted(() => {
margin-bottom
:
10px
;
.content-item
{
.content-item-title
{
padding
:
12px
23px
12px
44
px
;
padding
:
12px
23px
12px
30
px
;
box-sizing
:
border-box
;
border-bottom
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
color
:
rgba
(
59
,
65
,
75
,
1
);
...
...
@@ -252,63 +227,52 @@ onMounted(() => {
text-align
:
justify
;
}
.content-item-info
{
padding
:
12px
23px
12px
44px
;
box-sizing
:
border-box
;
border-bottom
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
.desc
{
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
Source
Han
Sans
CN
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
30px
;
letter-spacing
:
0px
;
text-align
:
justify
;
padding-left
:
15px
;
:deep
(
.item-info
)
{
padding-left
:
70px
;
.item-num
{
left
:
46px
;
}
}
.info-bill
{
.info-bill-box
{
cursor
:
pointer
;
margin
:
10px
44px
;
display
:
inline-flex
;
height
:
32px
;
border-radius
:
4px
;
display
:
inline-block
;
background
:
rgba
(
246
,
250
,
255
,
1
);
.info-bill-box
{
display
:
flex
;
margin-top
:
4px
;
height
:
32px
;
gap
:
16px
;
align-items
:
center
;
padding
:
0
8px
;
.info-bill-left
{
height
:
22px
;
padding
:
0
4px
;
border-radius
:
4px
;
background
:
rgba
(
246
,
250
,
255
,
1
);
gap
:
16px
;
align-items
:
center
;
padding
:
0
8px
;
.info-bill-left
{
height
:
22px
;
padding
:
0
4px
;
border-radius
:
4px
;
background
:
rgba
(
231
,
243
,
255
,
1
);
color
:
rgba
(
5
,
95
,
194
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
14px
;
font-weight
:
400
;
line-height
:
22px
;
letter-spacing
:
0px
;
text-align
:
left
;
}
.info-bill-center
{
height
:
24px
;
color
:
rgba
(
5
,
95
,
194
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
24px
;
letter-spacing
:
0px
;
text-align
:
left
;
}
.info-bill-right
{
width
:
20px
;
height
:
20px
;
cursor
:
pointer
;
img
{
width
:
100%
;
height
:
100%
;
}
background
:
rgba
(
231
,
243
,
255
,
1
);
color
:
rgba
(
5
,
95
,
194
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
14px
;
font-weight
:
400
;
line-height
:
22px
;
letter-spacing
:
0px
;
text-align
:
left
;
}
.info-bill-center
{
height
:
24px
;
color
:
rgba
(
5
,
95
,
194
,
1
);
font-family
:
Microsoft
YaHei
;
font-size
:
16px
;
font-weight
:
400
;
line-height
:
24px
;
letter-spacing
:
0px
;
text-align
:
left
;
}
.info-bill-right
{
width
:
20px
;
height
:
20px
;
img
{
width
:
100%
;
height
:
100%
;
}
}
}
...
...
src/views/marketAccessRestrictions/singleCaseLayout/deepdig/337/index.vue
浏览文件 @
86617244
...
...
@@ -14,18 +14,11 @@
</div>
<div
class=
"box-content"
>
<div
class=
"filter-row"
>
<el-select
v-model=
"selectedArea"
placeholder=
"全部领域"
class=
"area-select"
clearable
@
change=
"
fetchEnterpriseList
"
>
<el-select
v-model=
"selectedArea"
placeholder=
"全部领域"
class=
"area-select"
clearable
@
change=
"
onEnterpriseList()
"
>
<el-option
label=
"全部领域"
value=
""
/>
<el-option
v-for=
"item in areaOptions"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
/>
</el-select>
<el-input
v-model=
"searchText"
placeholder=
"搜索实体"
class=
"search-input"
:suffix-icon=
"Search"
clearable
@
input=
"handleSearchInput"
/>
<el-input
v-model=
"searchText"
placeholder=
"搜索实体"
class=
"search-input"
:suffix-icon=
"Search"
clearable
@
keyup
.
enter=
"onEnterpriseList()"
/>
</div>
<div
class=
"enterprise-list"
v-loading=
"listLoading"
>
<div
class=
"list-label"
>
企业名称
</div>
...
...
@@ -179,7 +172,7 @@ const businessLabels = ref([]);
const
businessData
=
ref
([]);
// 获取企业列表
const
fetch
EnterpriseList
=
async
()
=>
{
const
on
EnterpriseList
=
async
()
=>
{
listLoading
.
value
=
true
;
try
{
const
params
=
{
...
...
@@ -278,14 +271,6 @@ const updateBusinessChart = () => {
}
};
let
searchTimer
=
null
;
const
handleSearchInput
=
()
=>
{
if
(
searchTimer
)
clearTimeout
(
searchTimer
);
searchTimer
=
setTimeout
(()
=>
{
fetchEnterpriseList
();
},
500
);
};
const
handleEnterpriseClick
=
(
item
,
index
)
=>
{
activeIndex
.
value
=
index
;
if
(
item
.
ORGID
)
{
...
...
@@ -432,7 +417,7 @@ const handleBusinessToggle = (type) => {
};
onMounted
(()
=>
{
fetch
EnterpriseList
();
on
EnterpriseList
();
nextTick
(()
=>
{
initCharts
();
window
.
addEventListener
(
'resize'
,
()
=>
{
...
...
@@ -571,6 +556,9 @@ onMounted(() => {
.search-input
{
flex
:
auto
;
width
:
20px
;
background-color
:
#fff
;
border
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
border-radius
:
4px
;
}
}
...
...
src/views/marketAccessRestrictions/singleCaseLayout/index.vue
浏览文件 @
86617244
...
...
@@ -12,15 +12,19 @@
<div
:class=
"`item-tag tag-$
{codeInfo.sortCode}`">
{{
codeInfo
.
sortName
}}
</div>
</div>
<div
class=
"page-tabs"
>
<div
:class=
"['tab-item',
{'tab-active': activeName==
item.name}]" v-for="(item, index) in tabList" :key="index" @click="handleClickBtn(item
)">
<div
:class=
"['tab-item',
{'tab-active': activeName==
1}]" @click="handleClickBtn(1
)">
<div
class=
"icon"
>
<img
:src=
"item.activeIcon"
alt=
""
v-if=
"activeName==item.name"
/>
<img
:src=
"item.icon"
alt=
""
v-else
/>
<img
:src=
"activeName==2 ? NavIcon1Active : NavIcon1"
alt=
""
/>
</div>
<div
class=
"text"
:class=
"
{ textActive: activeName==item.name }">
{{
item
.
name
}}
<div
class=
"text"
:class=
"
{ textActive: activeName==1 }">调查概况
</div>
</div>
<div
:class=
"['tab-item',
{'tab-active': activeName==2}]" @click="handleClickBtn(2)" v-if="codeInfo.sortCode==337 || codeInfo.sortCode==232">
<div
class=
"icon"
>
<img
:src=
"activeName==2 ? NavIcon3Active : NavIcon3"
alt=
""
/>
</div>
<div
class=
"text"
:class=
"
{ textActive: activeName==2 }">
{{
codeInfo
.
sortCode
==
337
?
'影响分析'
:
'报告解析'
}}
</div>
</div>
<div
style=
"width:20px; flex:auto;"
></div>
<div
class=
"head-button"
>
<div
class=
"button-icon"
>
...
...
@@ -48,26 +52,12 @@ import { getSurvyInfo, getSearchBlurb } from "@/api/marketAccessRestrictions/ind
import
{
useRoute
}
from
"vue-router"
;
const
route
=
useRoute
();
const
tabList
=
ref
([
{
name
:
"调查概况"
,
icon
:
NavIcon1
,
activeIcon
:
NavIcon1Active
,
path
:
"/marketSingleCaseLayout/overview"
},
{
name
:
"影响分析"
,
icon
:
NavIcon3
,
activeIcon
:
NavIcon3Active
,
path
:
"/marketSingleCaseLayout/deepdig"
}
]);
const
activeName
=
ref
(
"调查案件"
);
const
handleClickBtn
=
i
tem
=>
{
activeName
.
value
=
i
tem
.
name
;
const
activeName
=
ref
(
1
);
const
handleClickBtn
=
i
ndex
=>
{
activeName
.
value
=
i
ndex
;
router
.
push
({
path
:
item
.
path
,
path
:
[
''
,
"/marketSingleCaseLayout/overview"
,
"/marketSingleCaseLayout/deepdig"
][
index
]
,
query
:
{
...
route
.
query
}
});
};
...
...
@@ -102,10 +92,10 @@ const onSearchBlurb = async () => {
onMounted
(()
=>
{
onSurvyInfo
()
onSearchBlurb
()
if
(
route
.
path
===
"/marketSingleCaseLayout/
deepdig
"
)
{
activeName
.
value
=
"影响分析"
;
if
(
route
.
path
===
"/marketSingleCaseLayout/
overview
"
)
{
activeName
.
value
=
1
;
}
else
{
activeName
.
value
=
"调查概况"
;
activeName
.
value
=
2
;
}
});
</
script
>
...
...
src/views/marketAccessRestrictions/singleCaseLayout/overview/232/index.vue
浏览文件 @
86617244
...
...
@@ -113,20 +113,16 @@ const tips = "美国 232 调查认定,钕铁硼永磁体(关键领域核心
const
route
=
useRoute
();
const
loading
=
ref
(
false
);
const
box2Loading
=
ref
(
false
);
const
box3Loading
=
ref
(
false
);
const
baseInfo
=
ref
({
}
);
const
reasonList
=
ref
([]);
const
timeLineList
=
ref
([]);
const
surveyResult
=
ref
([]);
const
handleGetSearchBlurb
=
async
()
=>
{
loading
.
value
=
true
;
try
{
const
res
=
await
getSearchBlurb
({
searchId
:
route
.
query
.
searchId
,
sortCode
:
"232"
}
);
const
res
=
await
getSearchBlurb
({
searchId
:
route
.
query
.
searchId
,
sortCode
:
"232"
}
);
console
.
log
(
'获取基本信息'
,
res
)
if
(
res
.
code
===
200
&&
res
.
data
)
{
const
data
=
res
.
data
;
baseInfo
.
value
=
data
;
...
...
@@ -139,42 +135,42 @@ const handleGetSearchBlurb = async () => {
}
}
}
catch
(
error
)
{
console
.
error
(
"获取调查详情失败"
,
error
);
}
finally
{
loading
.
value
=
false
;
console
.
error
(
"获取基本信息失败"
,
error
);
}
loading
.
value
=
false
;
}
;
const
handleGetSearchContext
=
async
()
=>
{
box2Loading
.
value
=
true
;
try
{
const
res
=
await
getSearchContext
({
searchId
:
route
.
query
.
searchId
}
);
if
(
res
.
code
===
200
&&
res
.
data
)
{
timeLineList
.
value
=
res
.
data
.
map
(
item
=>
({
time
:
item
.
CONTTIME
,
content
:
item
.
CONTDESC
}
));
}
}
catch
(
error
)
{
console
.
error
(
"获取事件脉络失败"
,
error
);
}
finally
{
box2Loading
.
value
=
false
;
}
}
;
// const box2Loading = ref(false);
// const timeLineList = ref([]);
// const handleGetSearchContext = async () =>
{
// box2Loading.value = true;
// try
{
// const res = await getSearchContext(
{
// searchId: route.query.searchId
//
}
);
// if (res.code === 200 && res.data)
{
// timeLineList.value = res.data.map(item => (
{
// time: item.CONTTIME,
// content: item.CONTDESC
//
}
));
//
}
//
}
catch
(
error
)
{
// console.error("获取事件脉络失败", error);
//
}
finally
{
// box2Loading.value = false;
//
}
//
}
;
const
handleGetSearchConclusion
=
async
()
=>
{
box3Loading
.
value
=
true
;
try
{
const
res
=
await
getSearchConclusion
({
searchId
:
route
.
query
.
searchId
}
);
const
res
=
await
getSearchConclusion
({
searchId
:
route
.
query
.
searchId
}
);
console
.
log
(
'获取调查结论'
,
res
)
if
(
res
.
code
===
200
)
{
surveyResult
.
value
=
res
.
data
.
map
(
item
=>
{
return
{
title
:
item
.
TITLE
,
data
:
item
.
CONTENT
?.
split
(
/
\r\n
|
\n
/
).
filter
(
line
=>
line
.
trim
())
||
[],
data
:
item
.
CONTENT
||
[],
}
;
}
);
}
...
...
@@ -189,9 +185,8 @@ const handleGetSearchConclusion = async () => {
const
eventList
=
ref
([])
const
handleGetRelatedEvents
=
async
()
=>
{
try
{
const
res
=
await
getRelatedEvents
({
searchId
:
route
.
query
.
searchId
}
);
const
res
=
await
getRelatedEvents
({
searchId
:
route
.
query
.
searchId
}
);
console
.
log
(
'获取相关行政举措'
,
res
)
if
(
res
.
code
===
200
)
eventList
.
value
=
res
.
data
||
[];
}
catch
(
error
)
{
console
.
error
(
"获取相关行政举措失败"
,
error
);
...
...
@@ -201,7 +196,7 @@ const handleGetRelatedEvents = async () => {
onMounted
(()
=>
{
handleGetSearchBlurb
();
handleGetRelatedEvents
();
handleGetSearchContext
();
//
handleGetSearchContext();
handleGetSearchConclusion
();
}
);
<
/script
>
...
...
@@ -240,8 +235,6 @@ onMounted(() => {
font
-
size
:
16
px
;
font
-
weight
:
700
;
line
-
height
:
24
px
;
margin
-
top
:
3
px
;
margin
-
bottom
:
3
px
;
}
.
box1
-
item
-
right
{
width
:
346
px
;
...
...
src/views/marketAccessRestrictions/singleCaseLayout/overview/301/index.vue
浏览文件 @
86617244
<
template
>
<div
class=
"wrapper"
>
<div
class=
"left"
>
<div
class=
"
page-
left"
>
<AnalysisBox
title=
"基本信息"
:showAllBtn=
"false"
height=
"auto"
>
<div
class=
"box1-main"
>
<div
class=
"box1-item"
>
...
...
@@ -19,7 +19,7 @@
<div
class=
"icon"
>
<img
src=
"./assets/images/icon1.png"
alt=
""
/>
</div>
<div
class=
"text"
>
{{
(
baseInfo
.
SEARCHORG
||
'-'
)
+
" >"
}}
</div>
<div
class=
"text"
style=
"cursor: pointer;"
@
click=
"onNavigateToORG()"
>
{{
(
baseInfo
.
SEARCHORG
||
'-'
)
+
" >"
}}
</div>
</div>
</div>
<div
class=
"box1-item"
>
...
...
@@ -46,7 +46,7 @@
<div
class=
"box1-item-right3"
>
<template
v-if=
"baseInfo.AdminstrativeData && baseInfo.AdminstrativeData.length"
>
<div
v-for=
"(item, index) in baseInfo.AdminstrativeData"
:key=
"index"
>
{{
item
.
ORDERNAME
+
" >"
}}
<div
style=
"cursor: pointer;"
@
click=
"onNavigateToDecree(item)"
>
{{
item
.
ORDERNAME
+
" >"
}}
</div>
</div>
</
template
>
<
template
v-else
>
-
</
template
>
...
...
@@ -56,7 +56,7 @@
</AnalysisBox>
<SurveyAffiche
title=
"调查公告"
:listData=
"box2Data"
></SurveyAffiche>
</div>
<div
class=
"right"
>
<div
class=
"
page-
right"
>
<AnalysisBox
:showAllBtn=
"false"
height=
"auto"
>
<
template
#
custom-title
>
<div
class=
"btn-box"
>
...
...
@@ -88,24 +88,7 @@
</div>
</div>
<div
class=
"box3-main2"
v-else
>
<div
class=
"box3-main2-item"
v-for=
"(item, index) in box3Data2"
:key=
"index"
>
<div
class=
"box3-main2-item-header"
>
<div
class=
"title"
>
{{ item.title }}
</div>
<div
class=
"more"
>
<div
class=
"icon"
>
<img
src=
"./assets/images/open-active.png"
alt=
""
/>
</div>
<div
class=
"text"
>
{{ "跳转原文" }}
</div>
</div>
</div>
<div
class=
"box3-main2-item-content"
>
<div
class=
"item"
v-for=
"(val, idx) in item.data"
:key=
"idx"
>
{{ idx+1 + "." + val.content }}
</div>
</div>
</div>
<Level1List
:list=
"box3Data2"
></Level1List>
</div>
</div>
</AnalysisBox>
...
...
@@ -116,6 +99,7 @@
<
script
setup
>
import
{
ref
,
onMounted
}
from
"vue"
;
import
{
useRoute
}
from
"vue-router"
;
import
router
from
"@/router"
;
import
{
getSearchBlurb
,
getRelatedEvents
,
...
...
@@ -124,6 +108,7 @@ import {
}
from
"@/api/marketAccessRestrictions"
;
import
RelatedEvent
from
"@/views/marketAccessRestrictions/com/RelatedEvent.vue"
;
import
SurveyAffiche
from
"@/views/marketAccessRestrictions/com/SurveyAffiche.vue"
;
import
Level1List
from
"@/views/marketAccessRestrictions/com/Level1List.vue"
;
const
route
=
useRoute
();
...
...
@@ -137,6 +122,23 @@ const handleClickBox3Btn = btn => {
box3BtnActive
.
value
=
btn
;
};
// 跳转到机构详情页
const
onNavigateToORG
=
()
=>
{
const
page
=
router
.
resolve
({
path
:
"/institution"
,
query
:
{
id
:
baseInfo
.
value
.
SEARCHORGID
}
});
window
.
open
(
page
.
href
,
"_blank"
);
}
// 跳转到政令详情页
const
onNavigateToDecree
=
(
item
)
=>
{
const
page
=
router
.
resolve
({
path
:
"/decreeLayout"
,
query
:
{
id
:
item
.
ORDERID
}
});
window
.
open
(
page
.
href
,
"_blank"
);
}
const
box2Data
=
ref
([]);
const
handleGetSearchBlurb
=
async
()
=>
{
try
{
...
...
@@ -184,26 +186,23 @@ const box3Data1 = ref([]);
const
handleGetSearchContext
=
async
()
=>
{
try
{
const
res
=
await
getSearchContext
({
searchId
:
route
.
query
.
searchId
});
console
.
log
(
'事件脉络'
,
res
.
data
)
console
.
log
(
'事件脉络'
,
res
)
if
(
res
.
code
===
200
)
box3Data1
.
value
=
res
.
data
;
}
catch
(
error
)
{
console
.
error
(
"获取事件脉络失败"
,
error
);
}
}
catch
(
error
)
{}
}
// 报复性措施
const
box3Data2
=
ref
([]);
const
handleGetSearchMeasures
=
async
()
=>
{
try
{
const
res
=
await
getSearchMeasures
({
searchId
:
route
.
query
.
searchId
});
console
.
log
(
'报复性措施'
,
res
)
if
(
res
.
code
===
200
&&
res
.
data
)
{
box3Data2
.
value
=
res
.
data
.
map
(
item
=>
({
title
:
item
.
TITLE
,
data
:
[{
content
:
item
.
CONTENT
}]
data
:
item
.
CONTENT
}));
}
}
catch
(
error
)
{
console
.
error
(
"获取报复性措施失败"
,
error
);
}
}
catch
(
error
)
{}
};
onMounted
(()
=>
{
handleGetSearchBlurb
();
...
...
@@ -218,13 +217,13 @@ onMounted(() => {
width
:
1600px
;
margin
:
20px
auto
;
display
:
flex
;
.left
{
.
page-
left
{
width
:
520px
;
display
:
flex
;
flex-direction
:
column
;
gap
:
16px
;
}
.right
{
.
page-
right
{
width
:
20px
;
flex
:
auto
;
display
:
flex
;
...
...
@@ -247,8 +246,6 @@ onMounted(() => {
font-size
:
16px
;
font-weight
:
700
;
line-height
:
24px
;
margin-top
:
3px
;
margin-bottom
:
3px
;
}
.box1-item-right
{
width
:
346px
;
...
...
@@ -336,7 +333,7 @@ onMounted(() => {
padding
:
15px
20px
;
.box3-main1
{
.box3-main1-item
{
margin-bottom
:
2
0px
;
margin-bottom
:
3
0px
;
display
:
flex
;
.left
{
width
:
10px
;
...
...
@@ -358,7 +355,6 @@ onMounted(() => {
.right
{
margin-left
:
17px
;
.header
{
height
:
24px
;
display
:
flex
;
gap
:
16px
;
color
:
var
(
--
color-main-active
);
...
...
@@ -366,18 +362,15 @@ onMounted(() => {
font-style
:
Bold
;
font-size
:
18px
;
font-weight
:
700
;
line-height
:
24
px
;
line-height
:
30
px
;
letter-spacing
:
0px
;
text-align
:
justify
;
padding-bottom
:
10px
;
}
.content
{
border-top
:
1px
solid
#eaecee
;
margin-top
:
10px
;
margin-bottom
:
36px
;
padding
:
10px
0
;
padding-top
:
10px
;
width
:
971px
;
max-height
:
60px
;
min-height
:
0
;
color
:
rgba
(
59
,
65
,
75
,
1
);
font-family
:
Microsoft
YaHei
;
font-style
:
Regular
;
...
...
@@ -422,9 +415,11 @@ onMounted(() => {
justify-content
:
flex-end
;
align-items
:
center
;
gap
:
7px
;
cursor
:
pointer
;
.icon
{
width
:
12px
;
height
:
12px
;
font-size
:
0
;
img
{
width
:
100%
;
height
:
100%
;
...
...
@@ -432,13 +427,10 @@ onMounted(() => {
}
.text
{
color
:
rgba
(
5
,
95
,
194
,
1
);
font-family
:
Microsoft
YaHei
;
font-style
:
Regular
;
font-size
:
12px
;
font-weight
:
400
;
line-height
:
1
4
px
;
line-height
:
1
2
px
;
letter-spacing
:
0px
;
text-align
:
justify
;
}
}
}
...
...
src/views/marketAccessRestrictions/singleCaseLayout/overview/337/index.vue
浏览文件 @
86617244
...
...
@@ -42,10 +42,10 @@
<AnalysisBox
title=
"原告信息"
:showAllBtn=
"false"
height=
"auto"
>
<div
class=
"box2-main"
>
<div
class=
"data-head"
>
<div
class=
"data-icon"
>
{{
baseInfo
.
ORGNAME
?.
substring
(
0
,
3
)
}}
</div>
<div
class=
"data-icon"
>
{{
baseInfo
.
orgAbb
}}
</div>
<div
class=
"data-right"
>
<div
class=
"data-name"
>
{{
baseInfo
.
ORGNAME
}}
</div>
<div
class=
"data-desc"
>
{{
""
}}
</div>
<div
class=
"data-name"
>
{{
baseInfo
.
orgNameEn
}}
</div>
<div
class=
"data-desc"
>
{{
baseInfo
.
ORGNAME
}}
</div>
</div>
</div>
<div
class=
"data-text"
>
{{
baseInfo
.
ORGBLURB
||
'-'
}}
</div>
...
...
@@ -110,7 +110,7 @@ const handleGetSearchBlurb = async () => {
if
(
data
.
defendantOrg
)
{
const
groups
=
{};
data
.
defendantOrg
.
forEach
(
item
=>
{
const
companyName
=
item
.
COMPANYNAM
E
||
"其他相关企业"
;
const
companyName
=
item
.
COMPANYNAM
||
"其他相关企业"
;
if
(
!
groups
[
companyName
])
{
groups
[
companyName
]
=
{
title
:
companyName
+
(
companyName
!==
"其他"
?
"及相关企业"
:
""
),
...
...
@@ -118,7 +118,7 @@ const handleGetSearchBlurb = async () => {
};
}
groups
[
companyName
].
companyList
.
push
({
name
:
item
.
COMNAM
E
,
name
:
item
.
COMNAM
,
logo
:
""
// API 不提供 logo
});
});
...
...
@@ -276,8 +276,6 @@ onMounted(() => {
font-size
:
16px
;
font-weight
:
700
;
line-height
:
24px
;
margin-top
:
3px
;
margin-bottom
:
3px
;
}
.box1-item-right
{
width
:
346px
;
...
...
src/views/marketAccessRestrictions/
marketAccessHome/utils/multi
LineChart.js
→
src/views/marketAccessRestrictions/
utils/base
LineChart.js
浏览文件 @
86617244
import
*
as
echarts
from
'echarts'
import
{
MUTICHARTCOLORS
}
from
'@/common/constant'
const
getMultiLineChart
=
(
data
)
=>
{
// 十六进制颜色转 rgba 的工具函数
function
hexToRgba
(
hex
,
alpha
)
{
const
r
=
parseInt
(
hex
.
slice
(
1
,
3
),
16
);
const
g
=
parseInt
(
hex
.
slice
(
3
,
5
),
16
);
const
b
=
parseInt
(
hex
.
slice
(
5
,
7
),
16
);
return
`rgba(
${
r
}
,
${
g
}
,
${
b
}
,
${
alpha
}
)`
;
}
const
getSerie
=
(
data
,
index
)
=>
{
return
{
name
:
data
.
name
,
type
:
'line'
,
smooth
:
true
,
symbol
:
'emptyCircle'
,
symbolSize
:
6
,
areaStyle
:
{
color
:
new
echarts
.
graphic
.
LinearGradient
(
0
,
0
,
0
,
1
,
[{
offset
:
0
,
color
:
hexToRgba
(
MUTICHARTCOLORS
[
index
],
0.7
)
},
{
offset
:
1
,
color
:
hexToRgba
(
MUTICHARTCOLORS
[
index
],
0
)
}])
},
emphasis
:
{
focus
:
'series'
},
data
:
data
.
value
}
}
const
createLineChart
=
(
chartDom
,
data
,
option
=
{})
=>
{
if
(
!
chartDom
.
value
)
return
;
// 先销毁之前的实例
const
existingChart
=
echarts
.
getInstanceByDom
(
chartDom
.
value
);
if
(
existingChart
)
existingChart
.
dispose
();
// 获取容器宽度/高度
const
containerWidth
=
chartDom
.
value
.
clientWidth
;
const
containerHeight
=
chartDom
.
value
.
clientHeight
;
const
myChart
=
echarts
.
init
(
chartDom
.
value
);
myChart
.
setOption
({
color
:
MUTICHARTCOLORS
,
tooltip
:
{
trigger
:
'item'
,
axisPointer
:
{
type
:
'cross'
,
label
:
{
backgroundColor
:
'#6a7985'
}
label
:
{
backgroundColor
:
'#6a7985'
}
}
},
grid
:
{
width
:
'95%'
,
height
:
'83%'
,
top
:
'15%'
,
left
:
'1%'
,
top
:
40
,
bottom
:
0
,
right
:
26
,
left
:
12
,
containLabel
:
true
},
legend
:
{
show
:
true
,
show
:
data
?.
list
?.
length
>
1
,
top
:
10
,
icon
:
'circle'
,
textStyle
:
{
...
...
@@ -28,7 +68,6 @@ const getMultiLineChart = (data) => {
fontSize
:
'14px'
,
}
},
color
:
[
'#0A57A6'
,
'#FA8C16'
,
'#722ED1'
],
xAxis
:
[
{
type
:
'category'
,
...
...
@@ -54,14 +93,14 @@ const getMultiLineChart = (data) => {
{
type
:
'value'
,
position
:
'left'
,
name
:
'数量'
,
name
:
"项"
,
nameLocation
:
'end'
,
nameGap
:
12
,
nameTextStyle
:
{
color
:
'#666'
,
fontSize
:
14
,
fontWeight
:
400
,
padding
:
[
0
,
0
,
6
,
-
2
0
]
padding
:
[
0
,
0
,
6
,
-
2
6
]
},
axisLabel
:
{
formatter
:
'{value}'
,
...
...
@@ -78,69 +117,9 @@ const getMultiLineChart = (data) => {
},
}
],
series
:
[
{
name
:
data
.
data
[
0
]?.
name
,
type
:
'line'
,
smooth
:
true
,
symbol
:
'emptyCircle'
,
symbolSize
:
6
,
areaStyle
:
{
color
:
new
echarts
.
graphic
.
LinearGradient
(
0
,
0
,
0
,
1
,
[{
offset
:
0
,
color
:
'rgba(10, 87, 166, 0.7)'
// 起始颜色
},
{
offset
:
1
,
color
:
'rgba(10, 87, 166, 0)'
// 结束颜色
}])
},
emphasis
:
{
focus
:
'series'
},
data
:
data
.
data
[
0
]?.
value
},
{
name
:
data
.
data
[
1
]?.
name
,
type
:
'line'
,
smooth
:
true
,
symbol
:
'emptyCircle'
,
symbolSize
:
6
,
areaStyle
:
{
color
:
new
echarts
.
graphic
.
LinearGradient
(
0
,
0
,
0
,
1
,
[{
offset
:
0
,
color
:
'rgba(255, 172, 77, 0.7)'
// 起始颜色
},
{
offset
:
1
,
color
:
'rgba(255, 172, 77, 0)'
// 结束颜色
}])
},
emphasis
:
{
focus
:
'series'
},
data
:
data
.
data
[
1
]?.
value
,
},
{
name
:
data
.
data
[
2
]?.
name
,
type
:
'line'
,
smooth
:
true
,
symbol
:
'emptyCircle'
,
symbolSize
:
6
,
areaStyle
:
{
color
:
new
echarts
.
graphic
.
LinearGradient
(
0
,
0
,
0
,
1
,
[{
offset
:
0
,
color
:
'rgba(114, 46, 209, 0.7)'
// 起始颜色
},
{
offset
:
1
,
color
:
'rgba(114, 46, 209, 0)'
// 结束颜色
}])
},
emphasis
:
{
focus
:
'series'
},
data
:
data
.
data
[
2
]?.
value
,
}
]
}
series
:
data
.
list
.
map
(
getSerie
)
})
return
myChart
}
export
default
getMultiLineChart
\ No newline at end of file
export
default
createLineChart
\ No newline at end of file
src/views/marketAccessRestrictions/
marketAccessHome/utils/p
iechart.js
→
src/views/marketAccessRestrictions/
utils/baseP
iechart.js
浏览文件 @
86617244
const
getPieChart
=
(
data
)
=>
{
const
colorList
=
[
'#69B1FF'
,
'#FF7875'
,
'#B37FEB'
,
'#FFC069'
,
'#1677FF'
,
'#87E8DE'
,
'#ADC6FF'
,
'#FFBB96'
,
'#BAE0FF'
,
'#FFD591'
,]
let
option
=
{
color
:
colorList
,
import
*
as
echarts
from
'echarts'
import
{
MUTICHARTCOLORS
}
from
'@/common/constant'
const
truncateLabel
=
(
value
,
maxLen
=
6
)
=>
{
if
(
value
===
null
||
value
===
undefined
)
return
''
const
str
=
String
(
value
)
const
chars
=
Array
.
from
(
str
)
if
(
chars
.
length
<=
maxLen
)
return
str
return
`
${
chars
.
slice
(
0
,
maxLen
).
join
(
''
)}
...`
}
const
formatLabel
=
(
node
,
type
)
=>
{
if
(
type
==
1
)
{
const
name
=
truncateLabel
(
node
.
name
,
6
)
return
`{name|
${
name
}
}\n{time|
${
node
.
percent
||
0
}
%}`
}
return
`{name|
${
node
.
name
}
} {time|
${
node
.
value
}
项
${
node
.
percent
||
0
}
%}\n`
}
const
createPieChart
=
(
chartDom
,
data
=
[],
option
=
{})
=>
{
if
(
!
chartDom
.
value
)
return
;
// 先销毁之前的实例
const
existingChart
=
echarts
.
getInstanceByDom
(
chartDom
.
value
);
if
(
existingChart
)
existingChart
.
dispose
();
// 获取容器宽度
const
containerWidth
=
chartDom
.
value
.
clientWidth
;
const
myChart
=
echarts
.
init
(
chartDom
.
value
);
myChart
.
setOption
({
color
:
MUTICHARTCOLORS
,
tooltip
:
{
formatter
:
node
=>
`
${
node
.
name
}
:
${
node
.
value
}
项 (
${
node
.
percent
||
0
}
%)`
,
},
series
:
[
{
type
:
'pie'
,
radius
:
[
7
5
,
100
],
radius
:
[
7
0
,
100
],
height
:
'100%'
,
left
:
'center'
,
width
:
'100%'
,
left
:
'center'
,
itemStyle
:
{
borderColor
:
'#fff'
,
borderWidth
:
1
},
label
:
{
alignTo
:
'edge'
,
formatter
:
'{name|{b}}
\
n{time|{c} 条 {d}%}'
,
formatter
:
(
node
)
=>
formatLabel
(
node
,
option
.
labelType
)
,
minMargin
:
5
,
edgeDistance
:
10
,
lineHeight
:
2
5
,
lineHeight
:
2
2
,
rich
:
{
name
:
{
color
:
'rgba(59, 65, 75, 1)'
,
fontFamily
:
'Microsoft YaHei'
,
fontSize
:
16
,
fontWeight
:
'bold'
,
padding
:
[
10
,
0
,
10
,
0
]
},
time
:
{
fontSize
:
16
,
color
:
'rgba(95, 101, 108, 1)'
,
fontFamily
:
'Microsoft YaHei'
,
color
:
'#rgba(95, 101, 108, 1)'
fontSize
:
16
,
padding
:
[
10
,
0
,
10
,
0
]
}
}
},
labelLine
:
{
length
:
15
,
length2
:
0
,
maxSurfaceAngle
:
8
0
maxSurfaceAngle
:
8
8
},
labelLayout
:
function
(
params
)
{
const
isLeft
=
params
.
labelRect
.
x
<
556
/
2
;
const
isLeft
=
params
.
labelRect
.
x
<
containerWidth
/
2
;
const
points
=
params
.
labelLinePoints
;
// Update the end point.
points
[
2
][
0
]
=
isLeft
?
params
.
labelRect
.
x
:
params
.
labelRect
.
x
+
params
.
labelRect
.
width
;
return
{
labelLinePoints
:
points
};
// 调整引导线终点
if
(
isLeft
)
{
points
[
2
][
0
]
=
params
.
labelRect
.
x
;
// 左对齐
}
else
{
points
[
2
][
0
]
=
params
.
labelRect
.
x
+
params
.
labelRect
.
width
;
// 右对齐
}
return
{
labelLinePoints
:
points
};
},
data
:
data
}]
}
return
option
}
]
});
return
myChart
}
export
default
getPieChart
;
\ No newline at end of file
export
default
createPieChart
;
\ No newline at end of file
src/views/marketAccessRestrictions/utils/index.ts
0 → 100644
浏览文件 @
86617244
/**
* 数字转中文(支持 0-99 整数)
* @param num 需要转化的数字
*/
export
const
onNumToChinese
=
(
num
:
number
)
=>
{
// 1. 基础校验:只处理 0-99 的整数
if
(
!
Number
.
isInteger
(
num
)
||
num
<
0
||
num
>
99
)
return
'100'
;
// 2. 定义基础字符
const
singleChars
=
[
'零'
,
'一'
,
'二'
,
'三'
,
'四'
,
'五'
,
'六'
,
'七'
,
'八'
,
'九'
];
const
tenChar
=
'十'
;
// 3. 核心转换逻辑
if
(
num
<
10
)
{
// 0-9 直接返回对应字符
return
singleChars
[
num
];
}
else
if
(
num
===
10
)
{
// 10 特殊处理
return
tenChar
;
}
else
if
(
num
<
20
)
{
// 11-19:十 + 个位(如十一、十九)
return
tenChar
+
singleChars
[
num
-
10
];
}
else
{
// 20-99:十位 + 十 + 个位(个位为0则省略,如二十、二十九)
const
ten
=
Math
.
floor
(
num
/
10
);
// 十位数字
const
unit
=
num
%
10
;
// 个位数字
return
singleChars
[
ten
]
+
tenChar
+
(
unit
===
0
?
''
:
singleChars
[
unit
]);
}
}
/**
* 获取 n 天前的日期,格式:YYYY-MM-DD
* @param num 往前推的天数
*/
export
const
getDateBefore
=
(
num
:
number
)
=>
{
const
now
=
new
Date
();
const
targetTime
=
now
.
getTime
()
-
num
*
24
*
60
*
60
*
1000
;
const
targetDate
=
new
Date
(
targetTime
);
const
year
=
targetDate
.
getFullYear
();
const
month
=
String
(
targetDate
.
getMonth
()
+
1
).
padStart
(
2
,
'0'
);
const
day
=
String
(
targetDate
.
getDate
()).
padStart
(
2
,
'0'
);
return
`
${
year
}
-
${
month
}
-
${
day
}
`
;
}
/**
* 获取最近年份列表
* @param num 需要几年前的列表
*/
export
const
getNearYearList
=
(
num
=
6
)
=>
{
const
currentYear
=
new
Date
().
getFullYear
();
const
yearOptions
=
[];
for
(
let
i
=
0
;
i
<
num
;
i
++
)
{
const
year
=
currentYear
-
i
;
yearOptions
.
push
({
label
:
year
.
toString
()
+
'年'
,
value
:
year
.
toString
()
});
}
return
yearOptions
;
};
/**
* AI智能总结
* @param data 需要分析的数据
*/
export
const
getAIReport
=
async
(
data
:
any
)
=>
{
let
word
=
""
// 👇 新增:超时 + 终止请求(只加这一段)
const
controller
=
new
AbortController
();
const
timeout
=
setTimeout
(()
=>
controller
.
abort
(),
10
*
1000
);
// 10秒超时
try
{
const
res
=
await
fetch
(
'/aiAnalysis/chart_interpretation'
,
{
method
:
'POST'
,
headers
:
{
"X-API-Key"
:
"aircasKEY19491001"
,
'Content-Type'
:
'application/json'
,
},
body
:
JSON
.
stringify
({
text
:
JSON
.
stringify
(
data
)}),
signal
:
controller
.
signal
// 👇 新增:绑定中断信号
});
clearTimeout
(
timeout
);
// 👇 新增:请求成功清除定时器
if
(
!
res
.
ok
)
throw
new
Error
(
`HTTP 错误
${
res
.
status
}
`
);
const
reader
=
res
.
body
.
getReader
();
const
decoder
=
new
TextDecoder
();
let
buffer
=
''
;
let
summarize
=
''
;
while
(
true
)
{
const
{
done
,
value
}
=
await
reader
.
read
();
if
(
done
)
break
;
buffer
+=
decoder
.
decode
(
value
,
{
stream
:
true
});
const
lines
=
buffer
.
split
(
'
\
n'
);
buffer
=
lines
.
pop
()
||
''
;
for
(
const
line
of
lines
)
{
if
(
line
.
startsWith
(
'data: '
))
{
const
content
=
line
.
substring
(
6
);
const
textMatch
=
content
.
match
(
/"解读":
\s
*"
([^
"
]
*
)
"/
);
if
(
textMatch
&&
textMatch
[
1
])
summarize
=
textMatch
[
1
];
}
}
}
word
=
summarize
}
catch
(
err
)
{
word
=
"系统异常,生成失败"
;
}
return
word
}
\ No newline at end of file
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论