Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
R
risk-monitor
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
蔡建
risk-monitor
Commits
581d2dec
提交
581d2dec
authored
3月 24, 2026
作者:
安云鹏
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
思维导图,写报
上级
d3d19811
显示空白字符变更
内嵌
并排
正在显示
11 个修改的文件
包含
1669 行增加
和
63 行删除
+1669
-63
ai-logo-color.png
src/assets/icons/aiBox/ai-logo-color.png
+0
-0
search.png
src/assets/icons/aiBox/search.png
+0
-0
writtingAsstaintStore.js
src/stores/writtingAsstaintStore.js
+454
-10
index.vue
src/views/home/index.vue
+5
-3
WrittingBottom.vue
src/views/writtingAsstaint/components/WrittingBottom.vue
+37
-8
WrittingHeader.vue
src/views/writtingAsstaint/components/WrittingHeader.vue
+14
-7
WrittingMainBox.vue
src/views/writtingAsstaint/components/WrittingMainBox.vue
+3
-3
WrittingMessage.vue
src/views/writtingAsstaint/components/WrittingMessage.vue
+0
-0
WrittingMind.vue
src/views/writtingAsstaint/components/WrittingMind.vue
+971
-5
WrittingTranslate.vue
src/views/writtingAsstaint/components/WrittingTranslate.vue
+176
-18
index.vue
src/views/writtingAsstaint/index.vue
+9
-9
没有找到文件。
src/assets/icons/aiBox/ai-logo-color.png
0 → 100644
浏览文件 @
581d2dec
816 Bytes
src/assets/icons/aiBox/search.png
0 → 100644
浏览文件 @
581d2dec
399 Bytes
src/stores/writtingAsstaintStore.js
浏览文件 @
581d2dec
...
@@ -52,6 +52,7 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
...
@@ -52,6 +52,7 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
},
},
// ====头
// ====头
isSsearchFor
:
false
,
//list
//list
tabList
:[
tabList
:[
{
{
...
@@ -63,7 +64,6 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
...
@@ -63,7 +64,6 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
type
:
'mind'
,
type
:
'mind'
,
name
:
'思维导图'
,
name
:
'思维导图'
,
active
:
false
active
:
false
},
},
{
{
type
:
'message'
,
type
:
'message'
,
...
@@ -76,7 +76,9 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
...
@@ -76,7 +76,9 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
bottomProgressNum
:
0
,
//文档解析 假进度
bottomProgressNum
:
0
,
//文档解析 假进度
resultWriteData
:
null
,
//文档分析结束之后 写报使用
resultWriteData
:
null
,
//文档分析结束之后 写报使用
// 写报
// 写报
isWriteStart
:
false
,
// 写报以进行中
isWriteStart
:
false
,
// 写报进行中
processWriteLog
:
''
,
//写报步骤
writeProgressNum
:
0
,
//写报 假进度
}),
}),
getters
:
{
getters
:
{
...
@@ -105,6 +107,7 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
...
@@ -105,6 +107,7 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
this
.
searchData
.
containerRef
=
containerRef
this
.
searchData
.
containerRef
=
containerRef
},
},
resetGenerateState
()
{
resetGenerateState
()
{
this
.
isGenerating
=
false
;
this
.
isGenerating
=
false
;
this
.
isShowProcess
=
false
;
this
.
isShowProcess
=
false
;
this
.
isShowSteps
=
false
;
this
.
isShowSteps
=
false
;
...
@@ -117,6 +120,19 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
...
@@ -117,6 +120,19 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
this
.
isShowOriginal
=
true
;
this
.
isShowOriginal
=
true
;
this
.
abortController
?.
abort
();
this
.
abortController
?.
abort
();
this
.
abortController
=
null
;
this
.
abortController
=
null
;
this
.
headerTabType
=
'translate'
,
// 底部
this
.
bottomProgressNum
=
0
,
//文档解析 假进度
this
.
resultWriteData
=
null
,
//文档分析结束之后 写报使用
// 写报
this
.
isWriteStart
=
false
,
// 写报进行中
this
.
processWriteLog
=
''
,
//写报步骤
this
.
writeProgressNum
=
0
,
//写报 假进度
this
.
tabList
[
1
].
active
=
false
this
.
tabList
[
2
].
active
=
false
},
},
backToInputAndClear
()
{
backToInputAndClear
()
{
...
@@ -159,9 +175,409 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
...
@@ -159,9 +175,409 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
async
handleHeaderTab
(
type
){
async
handleHeaderTab
(
type
){
this
.
headerTabType
=
type
this
.
headerTabType
=
type
},
},
// 关闭搜索栏
handleIsSsearchFor
(){
this
.
isSsearchFor
=!
this
.
isSsearchFor
console
.
log
(
this
.
isSsearchFor
)
},
// 智能写报
// 智能写报
async
generateWrite
(){
async
generateWrite
(){
this
.
isWriteStart
=
true
this
.
isWriteStart
=
true
const
obj
=
{
"query"
:
""
,
"desc"
:
""
,
"topic"
:
"政令"
,
"result"
:
{
"报告标题"
:
"美国对华科技政令分析报告(2025-14218)"
,
"政令概览"
:
{
"基本情况"
:
{
"政令名称"
:
"促进美国人工智能技术栈的出口"
,
"政令编号"
:
"14320"
,
"颁布机构"
:
"白宫"
,
"签署日期"
:
"2025-07-23"
,
"颁布日期"
:
"2025-07-28"
},
"政令背景"
:
{
"content"
:
[
"中国在人工智能技术栈的多个关键环节取得快速发展,成为美国在全球AI领域保持主导地位的主要竞争者。"
],
"source_section_num"
:
[
"2"
,
"4"
,
"1"
,
"3"
]
},
"政令简介"
:
{
"source_section_num"
:
[
"1"
,
"2"
,
"3"
,
"4"
],
"content"
:
"《促进美国人工智能技术栈的出口》要求美国商务部联合国务院、科技政策办公室等机构,建立美国人工智能出口计划,系统性推动包含AI芯片、数据中心、数据管道、模型系统、安全机制及行业应用的全栈技术包向全球出口,重点拓展对华技术替代市场,通过联邦融资工具与外交协同强化美国AI标准与基础设施的国际渗透,以巩固其在全球人工智能治理与供应链中的主导地位。"
},
"法律依据"
:
[
"《美国法典》第3编第301条"
,
"《2019年通过外交推动美国商业卓越法案》第708条"
,
"《美国法典》第50编第58章"
],
"数据概览"
:
[
{
"名称"
:
"条款总数"
,
"数值"
:
5
,
"单位"
:
"条"
},
{
"名称"
:
"科技条款总数"
,
"数值"
:
4
,
"单位"
:
"条"
},
{
"名称"
:
"涉华科技条款总数"
,
"数值"
:
3
,
"单位"
:
"条"
},
{
"名称"
:
"政令涉及领域"
,
"数值"
:
1
,
"单位"
:
"个"
,
"细节"
:
[
"人工智能"
]
}
]
},
"政令深度分析"
:
{
"条款分析"
:
{
"科技条款领域分布"
:
{
"type"
:
"柱状图"
,
"name"
:
"科技条款领域分布情况"
,
"data"
:
[
{
"domain_type"
:
"人工智能"
,
"count"
:
4
}
]
},
"科技条款内容"
:
[
{
"领域名称"
:
"人工智能"
,
"核心条款内容"
:
[
"建立美国人工智能出口计划,支持全栈美国人工智能技术包的开发与部署"
,
"美国人工智能出口计划要求提交的提案必须包含优化的AI硬件(如芯片、服务器、加速器)、数据中心存储、云服务和网络设施,并说明其在美国的制造程度"
,
"美国人工智能出口计划要求提案必须包含数据管道与标注系统"
,
"美国人工智能出口计划要求提案必须包含AI模型与系统"
,
"美国人工智能出口计划要求提案必须包含保障AI模型与系统安全与网络安全的措施"
,
"美国人工智能出口计划要求提案必须包含针对特定应用场景的AI应用(如软件工程、教育、医疗、农业或交通)"
,
"美国人工智能出口计划要求提案必须明确指定目标出口国家或区域 bloc"
,
"美国人工智能出口计划要求提案必须描述数据中枢及相关基础设施的建设、所有与运营的商业与运营模式"
,
"美国人工智能出口计划要求提案必须详细说明所申请的联邦激励与支持机制"
,
"美国人工智能出口计划要求提案必须遵守所有适用的美国出口管制制度、对外投资法规和最终用户政策,包括《美国法典》第50编第58章及商务部工业与安全局的相关指引"
,
"美国人工智能出口计划由商务部长在与国务卿和科技政策办公室主任协商后于本命令发布后90天内建立并实施"
,
"商务部长应在发布公开征集提案后90天内接收提案,并对提案进行滚动评估以纳入计划"
,
"被选定为优先人工智能出口包的提案,须经商务部长与国务卿、国防部长、能源部长及科技政策办公室主任共同评估确定"
,
"优先人工智能出口包将获得本命令第4节所列工具的优先访问权"
,
"成立经济外交行动组(EDAG),协调联邦融资工具以支持优先人工智能出口包"
,
"经济外交行动组由国务卿主持,成员可由小企业管理局局长和科技政策办公室主任根据《2019年通过外交促进美国商业法案》第708(c)(3)条任命"
,
"国务卿负责制定并执行统一的联邦战略,以促进美国人工智能技术与标准的出口"
,
"国务卿负责协调技术、金融与外交资源,加速优先人工智能出口包的部署"
,
"国务卿负责协调美国参与多边倡议及国别伙伴关系,以推动人工智能部署与出口推广"
,
"联邦机构应利用现有工具(包括直接贷款、贷款担保、股权投资、联合融资、政治风险保险、信用担保、技术援助与可行性研究)最大限度支持优先人工智能出口包"
],
"领域举措"
:
{
"type"
:
"思维导图"
,
"name"
:
"人工智能领域举措一览"
,
"data"
:
{
"node"
:
[
{
"id"
:
"1-1"
,
"name"
:
"人工智能领域举措"
,
"depth"
:
0
},
{
"id"
:
"2-1"
,
"name"
:
"商务部"
,
"depth"
:
1
},
{
"id"
:
"2-2"
,
"name"
:
"美国贸易代表办公室"
,
"depth"
:
1
},
{
"id"
:
"2-3"
,
"name"
:
"经济外交行动组"
,
"depth"
:
1
},
{
"id"
:
"2-4"
,
"name"
:
"小企业管理局"
,
"depth"
:
1
},
{
"id"
:
"2-5"
,
"name"
:
"白宫科学和技术政策办公室"
,
"depth"
:
1
},
{
"id"
:
"2-6"
,
"name"
:
"能源部"
,
"depth"
:
1
},
{
"id"
:
"2-7"
,
"name"
:
"国务院"
,
"depth"
:
1
},
{
"id"
:
"2-8"
,
"name"
:
"国防部"
,
"depth"
:
1
},
{
"id"
:
"3-1"
,
"name"
:
"建立协调的国家努力,通过促进全栈美国人工智能技术包的出口来支持美国人工智能产业。"
,
"depth"
:
2
},
{
"id"
:
"3-2"
,
"name"
:
"支持美国原产人工智能技术的全球部署,以减少对竞争对手开发的人工智能技术的依赖。"
,
"depth"
:
2
},
{
"id"
:
"3-3"
,
"name"
:
"商务部长应在90天内联合国务卿和科技政策办公室主任,建立并实施美国人工智能出口计划,征集由行业联盟提交的全栈AI出口包提案,提案须包含AI优化硬件、数据管道、AI模型、安全措施和应用场景,并明确目标出口国家或地区、运营模式及所需联邦支持。"
,
"depth"
:
2
},
{
"id"
:
"3-4"
,
"name"
:
"商务部须评估所提交的提案,与国务卿、国防部长、能源部长和科技政策办公室主任协商,选定优先AI出口包,并给予其优先获取本命令第4节所列工具的支持。"
,
"depth"
:
2
},
{
"id"
:
"3-5"
,
"name"
:
"由国务卿牵头,协调经济外交行动组(EDAG),制定并执行统一的联邦战略,促进美国人工智能技术与标准的出口,整合技术、金融与外交资源加优先AI出口包的部署,并支持多边倡议与国别合作。"
,
"depth"
:
2
},
{
"id"
:
"3-6"
,
"name"
:
"授权小企业管理局局长与白宫科技政策办公室主任依据CABDA第708(c)(3)条,任命其部门和机构的高级官员担任EDAG成员。"
,
"depth"
:
2
},
{
"id"
:
"3-7"
,
"name"
:
"EDAG成员应最大限度利用现有联邦融资工具支持优先AI出口包,包括直接贷款与贷款担保、股权融资、联合融资、政治风险保险、信用担保、技术援助与可行性研究。"
,
"depth"
:
2
},
{
"id"
:
"3-8"
,
"name"
:
"支持伙伴国家建立有利于创新的监管、数据和基础设施环境,以促进美国AI系统的部署,并分析阻碍美国AI产品市场准入的技术性贸易壁垒与监管措施。"
,
"depth"
:
2
},
{
"id"
:
"3-9"
,
"name"
:
"与小企业管理局的投资与创新办公室协调,促进在适用法律允许范围内,对美国中小企业投资,以支持其开发美国人工智能技术及制造AI基础设施、硬件和系统。"
,
"depth"
:
2
}
],
"links"
:
[
{
"source"
:
"1-1"
,
"target"
:
"2-1"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-2"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-3"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-4"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-5"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-6"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-7"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-8"
,
"value"
:
10
},
{
"source"
:
"2-1"
,
"target"
:
"3-1"
,
"value"
:
10
},
{
"source"
:
"2-1"
,
"target"
:
"3-2"
,
"value"
:
10
},
{
"source"
:
"2-1"
,
"target"
:
"3-3"
,
"value"
:
10
},
{
"source"
:
"2-5"
,
"target"
:
"3-3"
,
"value"
:
10
},
{
"source"
:
"2-7"
,
"target"
:
"3-3"
,
"value"
:
10
},
{
"source"
:
"2-1"
,
"target"
:
"3-4"
,
"value"
:
10
},
{
"source"
:
"2-5"
,
"target"
:
"3-4"
,
"value"
:
10
},
{
"source"
:
"2-6"
,
"target"
:
"3-4"
,
"value"
:
10
},
{
"source"
:
"2-7"
,
"target"
:
"3-4"
,
"value"
:
10
},
{
"source"
:
"2-8"
,
"target"
:
"3-4"
,
"value"
:
10
},
{
"source"
:
"2-1"
,
"target"
:
"3-5"
,
"value"
:
10
},
{
"source"
:
"2-2"
,
"target"
:
"3-5"
,
"value"
:
10
},
{
"source"
:
"2-3"
,
"target"
:
"3-5"
,
"value"
:
10
},
{
"source"
:
"2-4"
,
"target"
:
"3-5"
,
"value"
:
10
},
{
"source"
:
"2-5"
,
"target"
:
"3-5"
,
"value"
:
10
},
{
"source"
:
"2-7"
,
"target"
:
"3-5"
,
"value"
:
10
},
{
"source"
:
"2-4"
,
"target"
:
"3-6"
,
"value"
:
10
},
{
"source"
:
"2-5"
,
"target"
:
"3-6"
,
"value"
:
10
},
{
"source"
:
"2-3"
,
"target"
:
"3-7"
,
"value"
:
10
},
{
"source"
:
"2-3"
,
"target"
:
"3-8"
,
"value"
:
10
},
{
"source"
:
"2-7"
,
"target"
:
"3-8"
,
"value"
:
10
},
{
"source"
:
"2-4"
,
"target"
:
"3-9"
,
"value"
:
10
},
{
"source"
:
"2-7"
,
"target"
:
"3-9"
,
"value"
:
10
}
]
}
},
"source_section_num"
:
[
"1"
,
"2"
,
"3"
,
"4"
]
}
]
}
},
"附录"
:
{
"政令条款内容"
:
[
{
"section_num"
:
"1"
,
"section_text"
:
"目的。人工智能(AI)是一项基础性技术,将在未来数十年内决定经济增长、国家安全和全球竞争力的走向。美国不仅必须在开发通用型和前沿人工智能能力方面保持领先,还必须确保美国的人工智能技术、标准和治理模式在全球范围内得到采纳,以加强与盟友的关系并保障我们持续的技术主导地位。本命令确立了一项协调一致的国家努力,通过促进全套美国人工智能技术包的出口来支持美国人工智能产业。"
},
{
"section_num"
:
"2"
,
"section_text"
:
"美国的政策是保持并扩大美国在人工智能领域的领导地位,并通过支持美国原产人工智能技术的全球部署,减少对我国竞争对手所开发的人工智能技术的国际依赖。"
},
{
"section_num"
:
"3"
,
"section_text"
:
"(ii)确定具体的出口目标国家或区域集团;
\
n(iii)描述商业和运营模式,从宏观层面说明哪些实体将建设、拥有和运营数据中心及相关基础设施;
\
n(iv)详细说明所申请的联邦激励措施和支持机制;
\
n(v)遵守所有相关的美国出口管制制度、对外投资法规和最终用户政策,包括《美国法典》第50编第58章以及商务部工业与安全局发布的相关指南。
\
n
\
n(c)商务部应要求提案在公开征集提案发布后90天内提交,并应按滚动方式对提案进行审核,以纳入本计划。
\
n
\
n(d)商务部长应会同国务卿、国防部长、能源部长和总统科技政策办公室主任,评估所提交的提案以纳入本计划。经商务部长会同国务卿、国防部长、能源部长和总统科技政策办公室主任选定的提案,将被指定为优先人工智能出口包,并根据适用法律,获得本命令第4节所列工具的优先使用权。"
},
{
"section_num"
:
"4"
,
"section_text"
:
"联邦融资工具的动员。(a) 根据2024年6月21日总统备忘录设立的经济外交行动组(Economic Diplomacy Action Group, EDAG),由国务卿担任主席,并与商务部长和美国贸易代表协商,依据《2019年通过外交促进美国商业法案》第708条(《2019年公共法116-94》第J分编第VII标题)(以下简称“CABDA”),负责协调动员联邦融资工具以支持优先的人工智能出口项目。(b) 我依据CABDA第708(c)(3)条,授权小企业管理局局长和科技政策办公室主任任命其各自行政部门和机构的高级官员作为EDAG成员。(c) 国务卿应与EDAG协商,负责:(i) 制定并实施联邦政府统一战略,以促进美国人工智能技术及标准的出口;(ii) 整合技术、金融和外交资源,加推进计划下优先人工智能出口项目的部署;(iii) 协调美国参与多边倡议及针对特定国家的人工智能部署与出口促进伙伴关系;(iv) 支持伙伴国家建立有利于美国人工智能系统部署的促进创新的监管、数据和基础设施环境;(v) 分析市场准入情况,包括可能阻碍美国产品竞争力的技术性贸易壁垒和监管措施;以及(vi) 与小企业管理局投资与创新办公室协调,在适用法律允许的范围内,促进对美国中小企业投资,以支持美国人工智能技术的研发及人工智能基础设施、硬件和系统的制造。(d) EDAG成员应尽最大可能依法动用现有联邦工具,支持被选入本计划的优先出口项目,包括直接贷款和贷款担保(12 U.S.C. 635);股权投资、联合融资、政治风险保险和信用担保(22 U.S.C. 9621);以及技术援助和可行性研究(22 U.S.C. 2421(b))。"
},
{
"section_num"
:
"5"
,
"section_text"
:
"一般规定。(a) 本命令的任何内容均不得被解释为削弱或以其他方式影响:(i) 任何行政部门或机构及其负责人根据法律所享有的权力;或(ii) 行政管理和预算局局长在预算、行政或立法提案方面的职能。(b) 本命令的实施应符合适用法律,并受可用拨款的限制。(c) 本命令无意且并未创设任何可由任何一方对美国、其部门、机构或实体、其官员、雇员或代理人,或任何其他人,在法律或衡平法上强制执行的权利或利益,无论是实体性还是程序性的。(d) 本命令的出版费用由商务部承担。白宫,2025年7月23日。[FR Doc. 2025-14218 归档日期:2025年7月25日 上午8:45;公布日期:2025年7月28日]"
}
]
}
}
}
// await this.fetchReportData(obj);
await
this
.
fetchReportData
({
await
this
.
fetchReportData
({
query
:
this
.
writtingTitle
,
query
:
this
.
writtingTitle
,
desc
:
this
.
descText
,
desc
:
this
.
descText
,
...
@@ -169,6 +585,14 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
...
@@ -169,6 +585,14 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
result
:
this
.
resultWriteData
result
:
this
.
resultWriteData
});
});
},
},
// 停止写报
writeGenerateState
(){
// this.bottomProgressNum=100
this
.
writeProgressNum
=
0
this
.
processWriteLog
=
''
this
.
abortController
.
abort
()
},
// ========== 路由参数处理 ==========
// ========== 路由参数处理 ==========
async
setRouteParams
(
query
)
{
async
setRouteParams
(
query
)
{
...
@@ -320,8 +744,8 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
...
@@ -320,8 +744,8 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
this
.
abortController
=
new
AbortController
();
this
.
abortController
=
new
AbortController
();
this
.
processLog
=
''
;
this
.
processLog
=
''
;
// 进度初始化
0
// 进度初始化
1
this
.
bottomProgressNum
=
0
this
.
bottomProgressNum
=
1
try
{
try
{
const
formData
=
new
FormData
();
const
formData
=
new
FormData
();
formData
.
append
(
'pdf'
,
selectedFile
);
formData
.
append
(
'pdf'
,
selectedFile
);
...
@@ -394,8 +818,8 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
...
@@ -394,8 +818,8 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
)
)
this
.
bottomProgressNum
=
100
// 假进度完成
this
.
bottomProgressNum
=
100
// 假进度完成
this
.
tabList
[
2
].
active
=
true
//有结果之后放开写报按钮
this
.
resultWriteData
=
jsonData
//给写报使用
this
.
resultWriteData
=
jsonData
//给写报使用
this
.
tabList
[
1
].
active
=
true
// await this.fetchReportData({
// await this.fetchReportData({
// query: this.writtingTitle,
// query: this.writtingTitle,
// desc: this.descText,
// desc: this.descText,
...
@@ -442,6 +866,9 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
...
@@ -442,6 +866,9 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
if
(
this
.
abortController
)
this
.
abortController
.
abort
();
if
(
this
.
abortController
)
this
.
abortController
.
abort
();
this
.
abortController
=
new
AbortController
();
this
.
abortController
=
new
AbortController
();
this
.
processLog
=
''
;
this
.
processLog
=
''
;
this
.
processWriteLog
=
''
this
.
writeProgressNum
=
1
// 用于把 SSE 的分片内容先聚合,再按“句子/段落边界”一次性提交到 reportContent
// 用于把 SSE 的分片内容先聚合,再按“句子/段落边界”一次性提交到 reportContent
// 这样可以还原老版“一句完整再显示”的渲染效果,避免分片逐条渲染
// 这样可以还原老版“一句完整再显示”的渲染效果,避免分片逐条渲染
...
@@ -514,6 +941,7 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
...
@@ -514,6 +941,7 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
const
str
=
msgData
.
data
||
''
;
const
str
=
msgData
.
data
||
''
;
if
(
msgData
.
event_type
===
'stream_agent_out'
)
{
if
(
msgData
.
event_type
===
'stream_agent_out'
)
{
if
(
str
!==
'[DONE]'
)
{
if
(
str
!==
'[DONE]'
)
{
// SSE 分片先进入 buffer(仅用于报文内容)
// SSE 分片先进入 buffer(仅用于报文内容)
...
@@ -525,7 +953,11 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
...
@@ -525,7 +953,11 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
flushToReport
(
true
);
flushToReport
(
true
);
this
.
isGenerating
=
false
;
this
.
isGenerating
=
false
;
this
.
isShowSteps
=
false
;
// 报文生成结束后关闭步骤侧边栏
this
.
isShowSteps
=
false
;
// 报文生成结束后关闭步骤侧边栏
ElMessage
.
success
(
'报文生成结束'
);
ElMessage
.
success
(
'报文生成结束0'
);
this
.
tabList
[
2
].
active
=
true
//写报生成之后放开写报按钮
this
.
writeProgressNum
=
100
//写报假进度
// 这里不再调用 resetGenerateState,因为可能需要保留翻译内容
// 这里不再调用 resetGenerateState,因为可能需要保留翻译内容
}
}
}
else
if
(
msgData
.
event_type
===
'workflow_complete'
)
{
}
else
if
(
msgData
.
event_type
===
'workflow_complete'
)
{
...
@@ -533,7 +965,11 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
...
@@ -533,7 +965,11 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
flushToReport
(
true
);
flushToReport
(
true
);
this
.
isGenerating
=
false
;
this
.
isGenerating
=
false
;
this
.
isShowSteps
=
false
;
// 报文生成结束后关闭步骤侧边栏
this
.
isShowSteps
=
false
;
// 报文生成结束后关闭步骤侧边栏
ElMessage
.
success
(
'报文生成结束'
);
ElMessage
.
success
(
'报文生成结束1'
);
this
.
tabList
[
2
].
active
=
true
//写报生成之后放开写报按钮
this
.
writeProgressNum
=
100
//写报假进度
}
else
if
((
msgData
.
event_type
||
''
).
toLowerCase
().
includes
(
'error'
))
{
}
else
if
((
msgData
.
event_type
||
''
).
toLowerCase
().
includes
(
'error'
))
{
// 优先从 data.error 获取详细错误描述
// 优先从 data.error 获取详细错误描述
const
errorMsg
=
msgData
.
data
?.
error
||
str
||
'生成失败'
;
const
errorMsg
=
msgData
.
data
?.
error
||
str
||
'生成失败'
;
...
@@ -542,7 +978,12 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
...
@@ -542,7 +978,12 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
// 老版 --index.vue 行为:步骤栏直接追加服务端发来的完整步骤内容,不加时间戳、不强行换行
// 老版 --index.vue 行为:步骤栏直接追加服务端发来的完整步骤内容,不加时间戳、不强行换行
// 这样可以避免 SSE 分片导致的“步骤破碎”(一条步骤被拆成多条显示)
// 这样可以避免 SSE 分片导致的“步骤破碎”(一条步骤被拆成多条显示)
if
(
str
)
{
if
(
str
)
{
this
.
processLog
+=
str
;
// this.processLog += str;
this
.
processWriteLog
+=
str
;
if
(
this
.
writeProgressNum
<=
90
){
this
.
writeProgressNum
+=
0.05
}
console
.
log
(
this
.
writeProgressNum
)
}
}
this
.
curAgentTool
=
msgData
.
tool
||
'无'
;
this
.
curAgentTool
=
msgData
.
tool
||
'无'
;
}
}
...
@@ -564,11 +1005,11 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
...
@@ -564,11 +1005,11 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
// ========== 业务入口 ==========
// ========== 业务入口 ==========
async
generateReport
()
{
async
generateReport
()
{
if
(
Object
.
keys
(
this
.
routeQuery
).
length
!==
0
)
{
// 路由参数优先
// 路由参数优先
this
.
isGenerating
=
true
;
this
.
isGenerating
=
true
;
this
.
isShowProcess
=
true
;
this
.
isShowProcess
=
true
;
if
(
Object
.
keys
(
this
.
routeQuery
).
length
!==
0
)
{
const
{
fileId
}
=
this
.
routeQuery
;
const
{
fileId
}
=
this
.
routeQuery
;
// 外部跳转:根据 topic 决定调用哪种数据获取接口,再触发生成
// 外部跳转:根据 topic 决定调用哪种数据获取接口,再触发生成
...
@@ -605,6 +1046,9 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
...
@@ -605,6 +1046,9 @@ export const useWrittingAsstaintStore = defineStore('writtingAsstaint', {
}
}
await
this
.
fetchPdfData
(
rawFile
);
await
this
.
fetchPdfData
(
rawFile
);
}
else
{
}
else
{
// 路由参数优先
this
.
isGenerating
=
true
;
this
.
isShowProcess
=
true
;
const
params
=
{
const
params
=
{
query
:
this
.
writtingTitle
,
query
:
this
.
writtingTitle
,
desc
:
this
.
descText
,
desc
:
this
.
descText
,
...
...
src/views/home/index.vue
浏览文件 @
581d2dec
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
<router-view
/>
<router-view
/>
</div>
</div>
</div>
</div>
<div
class=
"right-btn"
@
click=
"handleClickToolBox"
>
<div
class=
"right-btn"
@
click=
"handleClickToolBox"
v-if=
"route.path!='/writtingAsstaint'"
>
<div
class=
"item"
>
<div
class=
"item"
>
<div
class=
"icon"
>
<div
class=
"icon"
>
<img
src=
"@/assets/icons/overview/domain.png"
alt=
""
/>
<img
src=
"@/assets/icons/overview/domain.png"
alt=
""
/>
...
@@ -22,7 +22,7 @@
...
@@ -22,7 +22,7 @@
</div>
</div>
</div>
</div>
<div
class=
"tool-box"
>
<div
class=
"tool-box"
v-if=
"route.path!='/writtingAsstaint'"
>
<!--
<div
class=
"tool-item"
>
<!--
<div
class=
"tool-item"
>
<img
src=
"@/assets/icons/tool-item-icon1.png"
alt=
""
/>
<img
src=
"@/assets/icons/tool-item-icon1.png"
alt=
""
/>
</div>
</div>
...
@@ -96,7 +96,6 @@ import { ElMessage } from "element-plus";
...
@@ -96,7 +96,6 @@ import { ElMessage } from "element-plus";
const
router
=
useRouter
();
const
router
=
useRouter
();
const
route
=
useRoute
();
const
route
=
useRoute
();
const
isShowAiBox
=
ref
(
false
);
const
isShowAiBox
=
ref
(
false
);
const
closeAiBox
=
()
=>
{
const
closeAiBox
=
()
=>
{
...
@@ -804,4 +803,7 @@ body {
...
@@ -804,4 +803,7 @@ body {
cursor
:
not
-
allowed
;
cursor
:
not
-
allowed
;
pointer-events
:
none
;
pointer-events
:
none
;
}
}
</
style
>
</
style
>
src/views/writtingAsstaint/components/WrittingBottom.vue
浏览文件 @
581d2dec
<
template
>
<
template
>
<div
class=
"writtingBottom"
>
<div
class=
"writtingBottom"
>
<div
class=
"parsed"
v-if=
"store.isGenerating"
>
<!-- 文档停止解析 -->
<div
class=
"parsed"
v-if=
"store.bottomProgressNum>0&&store.bottomProgressNum
<100
"
>
<div
class=
"analysis"
@
click=
"store.resetGenerateState"
>
<div
class=
"analysis"
@
click=
"store.resetGenerateState"
>
<div
class=
"icon"
></div>
<div
class=
"icon"
></div>
<span
class=
"text-tip-2-bold"
>
停止
</span>
<span
class=
"text-tip-2-bold"
>
停止
</span>
...
@@ -15,12 +17,18 @@
...
@@ -15,12 +17,18 @@
</div>
</div>
</div>
</div>
</div>
</div>
<div
class=
"parsed"
v-else-if=
"store.isShowSteps&&store.bottomProgressNum>=100"
>
<div
class=
"analysis"
v-if=
"store.isWriteStart"
@
click=
"store.resetGenerateState"
>
<!-- 开始写报 -->
<!-- -->
<div
class=
"parsed"
v-else-if=
"store.bottomProgressNum>=100"
>
<div
class=
"analysis"
v-if=
"store.isWriteStart&&store.writeProgressNum
<100
"
@
click=
"store.writeGenerateState"
>
<div
class=
"icon"
></div>
<div
class=
"icon"
></div>
<span
class=
"text-tip-2-bold"
>
停止
</span>
<span
class=
"text-tip-2-bold"
>
停止
</span>
</div>
</div>
<div
class=
"analysis"
v-else-if=
"store.writeProgressNum>=100"
@
click=
"store.resetGenerateState"
>
<img
src=
"@/assets/icons/aiBox/ai-logo-color.png"
alt=
""
>
<span
class=
"text-tip-1"
>
重新上传
</span>
</div>
<div
class=
"notAnalysis"
v-else
@
click=
"onWriteClick()"
>
<div
class=
"notAnalysis"
v-else
@
click=
"onWriteClick()"
>
<img
src=
"@/assets/icons/aiBox/ai-logo.png"
alt=
""
>
<img
src=
"@/assets/icons/aiBox/ai-logo.png"
alt=
""
>
<span
class=
"text-tip-1"
>
智能写报
</span>
<span
class=
"text-tip-1"
>
智能写报
</span>
...
@@ -28,14 +36,15 @@
...
@@ -28,14 +36,15 @@
<div
class=
"progress"
>
<div
class=
"progress"
>
<div
class=
"login"
>
<div
class=
"login"
>
<el-progress
type=
"circle"
:percentage=
"store.
bottom
ProgressNum"
:width=
"24"
:height=
"24"
style=
"margin-right: 15px;"
:show-text=
"false"
color=
"rgb(5, 95, 194)"
/>
<el-progress
type=
"circle"
:percentage=
"store.
write
ProgressNum"
:width=
"24"
:height=
"24"
style=
"margin-right: 15px;"
:show-text=
"false"
color=
"rgb(5, 95, 194)"
/>
<span
class=
"text-tip-2-bold"
>
文档翻译
中
</span>
<span
class=
"text-tip-2-bold"
>
智能写报
中
</span>
</div>
</div>
<div
class=
"text-tip-2"
>
<div
class=
"text-tip-2"
>
<div
ref=
"process
ContainerRef"
v-html=
"renderedProcess"
>
</div>
<div
ref=
"process
WriteLogRef"
v-html=
"renderedProcess"
>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 开始解析文档 -->
<div
class=
"parsed"
v-else
>
<div
class=
"parsed"
v-else
>
<div
class=
"notAnalysis"
@
click=
"onAnalysisClick()"
>
<div
class=
"notAnalysis"
@
click=
"onAnalysisClick()"
>
<img
src=
"@/assets/icons/aiBox/ai-logo.png"
alt=
""
>
<img
src=
"@/assets/icons/aiBox/ai-logo.png"
alt=
""
>
...
@@ -75,15 +84,30 @@ const processContainerRef = ref(null);
...
@@ -75,15 +84,30 @@ const processContainerRef = ref(null);
watch
(
watch
(
()
=>
store
.
processLog
,
()
=>
store
.
processLog
,
async
(
newLog
)
=>
{
async
(
newLog
)
=>
{
console
.
log
(
newLog
)
if
(
newLog
!==
undefined
&&
newLog
!==
null
)
{
if
(
newLog
!==
undefined
&&
newLog
!==
null
)
{
await
updateProcess
(
newLog
,
processContainerRef
.
value
);
await
updateProcess
(
newLog
,
processContainerRef
.
value
);
}
}
},
},
{
immediate
:
true
}
{
immediate
:
true
}
);
);
defineExpose
({
defineExpose
({
processContainerRef
processContainerRef
});
});
const
processWriteLogRef
=
ref
(
null
)
watch
(
()
=>
store
.
processWriteLog
,
async
(
newLog
)
=>
{
if
(
newLog
!==
undefined
&&
newLog
!==
null
)
{
const
lines
=
newLog
.
split
(
'
\
n'
).
filter
(
newLog
=>
newLog
.
trim
());
const
lastLine
=
lines
[
lines
.
length
-
1
];
await
updateProcess
(
lastLine
?
lastLine
:
''
,
processWriteLogRef
.
value
);
}
},
{
immediate
:
true
}
);
</
script
>
</
script
>
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
.writtingBottom
{
.writtingBottom
{
...
@@ -129,7 +153,7 @@ defineExpose({
...
@@ -129,7 +153,7 @@ defineExpose({
.analysis
{
.analysis
{
border
:
1px
solid
var
(
--
color-primary-100
);
border
:
1px
solid
var
(
--
color-primary-100
);
background-color
:
#fff
;
background-color
:
rgb
(
246
,
250
,
255
)
;
color
:
var
(
--
color-primary-100
);
color
:
var
(
--
color-primary-100
);
width
:
437px
;
width
:
437px
;
height
:
36px
;
height
:
36px
;
...
@@ -145,6 +169,11 @@ defineExpose({
...
@@ -145,6 +169,11 @@ defineExpose({
background-color
:
var
(
--
color-primary-100
);
background-color
:
var
(
--
color-primary-100
);
margin-right
:
12px
;
margin-right
:
12px
;
}
}
img
{
width
:
21px
;
height
:
16px
;
margin-right
:
12px
;
}
}
}
.progress
{
.progress
{
display
:
flex
;
display
:
flex
;
...
...
src/views/writtingAsstaint/components/WrittingHeader.vue
浏览文件 @
581d2dec
<
template
>
<
template
>
<div
class=
"headerBox"
>
<div
class=
"headerBox"
>
<div
class=
"tabBox"
v-if=
"store.isGenerating||store.isShowSteps
"
>
<div
class=
"tabBox"
v-if=
"store.bottomProgressNum>0
"
>
<div
class=
"fileName"
>
<div
class=
"fileName"
>
<img
src=
"@/assets/icons/pdf-icon.png"
alt=
" "
>
<img
src=
"@/assets/icons/pdf-icon.png"
alt=
" "
>
<span
class=
"text-tip-1-bold"
>
{{
store
.
uploadFileList
[
0
]?.
name
||
'文件错误'
}}
</span>
<span
class=
"text-tip-1-bold"
>
{{
store
.
uploadFileList
[
0
]?.
name
||
'文件错误'
}}
</span>
...
@@ -10,13 +10,17 @@
...
@@ -10,13 +10,17 @@
:style="!item.active?'color:#bfbfbf;cursor: no-drop;':''"
:style="!item.active?'color:#bfbfbf;cursor: no-drop;':''"
@click="onTabListClick(item.type,item.active)">
{{
item
.
name
}}
</div>
@click="onTabListClick(item.type,item.active)">
{{
item
.
name
}}
</div>
</div>
</div>
<div
class=
"switch"
>
<div
class=
"switch"
v-if=
"store.headerTabType=='translate'"
>
<el-switch
v-model=
"store.isShowOriginal"
/>
<el-switch
v-model=
"store.isShowOriginal"
/>
<div
class=
"iconBOx"
>
<div
class=
"iconBOx"
>
<img
src=
"@/assets/icons/translate-icon.png"
alt=
""
>
<img
src=
"@/assets/icons/translate-icon.png"
alt=
""
>
<span
class=
"text-tip-1"
>
显示原文
</span>
<span
class=
"text-tip-1"
>
显示原文
</span>
</div>
</div>
<el-button
@
click=
"onSearchClick"
>
查找
</el-button>
<el-button
@
click=
"store.handleIsSsearchFor"
><img
style=
"width: 16px;"
src=
"@/assets/icons/aiBox/search.png"
alt=
""
>
查找
</el-button>
</div>
<div
v-else
>
<el-button
@
click=
"store.exportContent"
>
导出
</el-button>
</div>
</div>
</div>
</div>
...
@@ -24,12 +28,11 @@
...
@@ -24,12 +28,11 @@
<img
src=
"@/assets/icons/tool-item-icon1.png"
alt=
""
>
<img
src=
"@/assets/icons/tool-item-icon1.png"
alt=
""
>
<span
class=
"text-title-3-bold"
>
智能写库
</span>
<span
class=
"text-title-3-bold"
>
智能写库
</span>
</div>
</div>
</div>
</div>
</
template
>
</
template
>
<
script
setup
>
<
script
setup
>
import
{
onMounted
,
onUnmounted
,
ref
,
nextTick
}
from
"vue"
;
import
{
onMounted
,
onUnmounted
,
ref
,
nextTick
,
computed
,
watch
}
from
"vue"
;
import
{
useRoute
}
from
"vue-router"
;
import
{
useRoute
}
from
"vue-router"
;
import
{
ElMessage
}
from
"element-plus"
;
import
{
ElMessage
}
from
"element-plus"
;
import
{
useWrittingAsstaintStore
}
from
"@/stores/writtingAsstaintStore"
;
import
{
useWrittingAsstaintStore
}
from
"@/stores/writtingAsstaintStore"
;
...
@@ -42,8 +45,7 @@ const onTabListClick= (type,active)=>{
...
@@ -42,8 +45,7 @@ const onTabListClick= (type,active)=>{
console
.
log
(
1
)
console
.
log
(
1
)
store
.
handleHeaderTab
(
type
)
store
.
handleHeaderTab
(
type
)
}
}
// 查找
const
onSearchClick
=
()
=>
{}
</
script
>
</
script
>
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
...
@@ -118,4 +120,8 @@ const onSearchClick=()=>{}
...
@@ -118,4 +120,8 @@ const onSearchClick=()=>{}
}
}
}
}
</
style
>
</
style
>
\ No newline at end of file
src/views/writtingAsstaint/components/WrittingMainBox.vue
浏览文件 @
581d2dec
...
@@ -103,7 +103,7 @@ watch(
...
@@ -103,7 +103,7 @@ watch(
}
}
.content-box
{
.content-box
{
width
:
10
69px
;
width
:
10
0%
;
height
:
100%
;
height
:
100%
;
overflow-y
:
auto
;
overflow-y
:
auto
;
padding
:
20px
80px
;
padding
:
20px
80px
;
...
@@ -111,8 +111,8 @@ watch(
...
@@ -111,8 +111,8 @@ watch(
font-size
:
16px
;
font-size
:
16px
;
box-sizing
:
border-box
;
box-sizing
:
border-box
;
border
:
1px
solid
rgba
(
234
,
236
,
238
,
1
);
//
border: 1px solid rgba(234, 236, 238, 1);
border-radius
:
10px
;
//
border-radius: 10px;
background
:
rgba
(
255
,
255
,
255
,
1
);
background
:
rgba
(
255
,
255
,
255
,
1
);
margin
:
17px
auto
0
auto
;
margin
:
17px
auto
0
auto
;
...
...
src/views/writtingAsstaint/components/WrittingMessage.vue
浏览文件 @
581d2dec
src/views/writtingAsstaint/components/WrittingMind.vue
浏览文件 @
581d2dec
<
template
>
<
template
>
<div
>
<div
class=
"mind-map-container"
>
我是思维导图
<div
ref=
"containerRef"
class=
"mind-map"
></div>
</div>
</div>
</
template
>
</
template
>
<
script
setup
>
<
script
setup
>
import
{
ref
,
watch
,
onMounted
,
onUnmounted
}
from
"vue"
;
import
{
ref
,
onMounted
,
onUnmounted
}
from
'vue'
import
G6
from
'@antv/g6'
const
data
=
{
"报告标题"
:
"美国对华科技政令分析报告(2025-06836)"
,
"政令概览"
:
{
"基本情况"
:
{
"政令名称"
:
"通过确保国家安全和经济韧性"
,
"政令编号"
:
"14272"
,
"颁布机构"
:
"白宫"
,
"签署日期"
:
"2025-04-15"
,
"颁布日期"
:
"2025-04-18"
},
"政令背景"
:
{
"content"
:
[
"中国在全球 processed critical minerals 及其衍生产品供应链中占据主导地位,且被指存在价格操纵、出口限制等市场扭曲行为,导致美国在关键矿物供应上高度依赖中国。"
],
"source_section_num"
:
[
"2"
,
"1"
,
"3"
]
},
"政令简介"
:
{
"source_section_num"
:
[
"1"
,
"2"
,
"3"
],
"content"
:
"《通过确保国家安全和经济韧性》法案要求对加工关键矿物及其衍生产品的进口展开国家安全审查,重点评估中国等国家在稀土元素与加工矿物供应链中的主导地位、市场操纵行为及对美国国防工业和高科技制造业的系统性依赖风险,并推动建立本土加工能力与供应链韧性,以降低对特定地缘政治实体的战略性资源依赖。"
},
"法律依据"
:
[
"1962年贸易扩展法"
,
"《国际紧急经济权力法》"
,
"《1962年贸易扩展法》第232条"
,
"《1962年贸易扩展法》第1862(d)条"
],
"数据概览"
:
[
{
"名称"
:
"条款总数"
,
"数值"
:
4
,
"单位"
:
"条"
},
{
"名称"
:
"科技条款总数"
,
"数值"
:
3
,
"单位"
:
"条"
},
{
"名称"
:
"涉华科技条款总数"
,
"数值"
:
2
,
"单位"
:
"条"
},
{
"名称"
:
"政令涉及领域"
,
"数值"
:
3
,
"单位"
:
"个"
,
"细节"
:
[
"先进制造"
,
"新材料"
,
"新能源"
]
}
]
},
"政令深度分析"
:
{
"条款分析"
:
{
"科技条款领域分布"
:
{
"type"
:
"柱状图"
,
"name"
:
"科技条款领域分布情况"
,
"data"
:
[
{
"domain_type"
:
"先进制造"
,
"count"
:
3
},
{
"domain_type"
:
"新材料"
,
"count"
:
3
},
{
"domain_type"
:
"新能源"
,
"count"
:
2
}
]
},
"科技条款内容"
:
[
{
"领域名称"
:
"先进制造"
,
"核心条款内容"
:
[
" processed critical minerals及其衍生产品对美国经济安全和国家安全至关重要,是关键产业、技术创新和基础设施的核心投入品"
,
"processed critical minerals包括从矿石提取后经氧化物浓缩、分离为氧化物、转化为金属、金属粉末或母合金的矿物"
,
"衍生产品包括所有将processed critical minerals作为投入品的货物,如半导体晶圆、阳极、阴极、永磁体、电机、电动汽车、电池、智能手机、微处理器、雷达系统、风力涡轮机及其组件和先进光学设备"
,
"关键矿物包括美国地质调查局根据《2020年能源法案》发布的“关键矿物清单”所列矿物,以及铀"
,
"稀土元素包括美国能源部2020年4月报告中认定的17种元素,以及美国地质调查局或能源部后续官方报告中新增的元素"
,
"美国在processed critical minerals及其衍生产品上高度依赖外国进口,存在供应链脆弱性和市场扭曲风险"
,
"外国供应商通过价格操纵、产能过剩、任意出口限制和供应链主导地位,扭曲全球市场并获取对美国的地缘政治和经济杠杆"
,
"美国制造业和国防工业基地对外国processed critical minerals的依赖,可能导致供应中断并影响产品制造能力"
,
"全球供应链易受地缘政治紧张、战争、自然灾害、大流行病和贸易冲突的破坏"
,
"过度依赖少数地理区域加剧了地缘政治不稳定和区域中断带来的风险"
,
"美国商务部应根据《1930年关税法》第232条启动调查,评估processed critical minerals及其衍生产品进口对国家安全的影响"
,
"调查需评估美国对processed critical minerals及其衍生产品的进口量、来源国占比、具体风险及高风险国家"
,
"调查需分析出口国对processed critical minerals实施的掠夺性经济策略、定价操纵和市场扭曲行为对美国国内投资和生产 viability 的影响"
,
"调查需评估美国及全球对processed critical minerals的需求来源,特别是来自高风险国家的需求比例"
,
"调查需审查processed critical minerals及其衍生产品的全球供应链并进行风险评估"
,
"调查需分析美国当前和潜在的processed critical minerals及其衍生产品加工能力"
,
"调查需评估processed critical minerals及其衍生产品的进口总价值及其来源国分布"
,
"商务部应在本命令发布后90天内提交中期报告草案,180天内向总统提交最终报告和建议"
,
"商务部在提出建议时应考虑征收关税、其他进口限制、防止规避措施、激励国内生产加工与回收的政策,以及依据《国际紧急经济权力法》采取的其他措施"
,
"processed critical minerals及其衍生产品是军事基础设施、能源基础设施和先进国防系统与技术的基础构件"
],
"领域举措"
:
{
"type"
:
"思维导图"
,
"name"
:
"先进制造领域举措一览"
,
"data"
:
{
"node"
:
[
{
"id"
:
"1-1"
,
"name"
:
"先进制造领域举措"
,
"depth"
:
0
},
{
"id"
:
"2-1"
,
"name"
:
"商务部"
,
"depth"
:
1
},
{
"id"
:
"2-2"
,
"name"
:
"白宫经济政策助理"
,
"depth"
:
1
},
{
"id"
:
"2-3"
,
"name"
:
"美国贸易代表办公室"
,
"depth"
:
1
},
{
"id"
:
"2-4"
,
"name"
:
"总统贸易与制造高级顾问"
,
"depth"
:
1
},
{
"id"
:
"2-5"
,
"name"
:
"财政部"
,
"depth"
:
1
},
{
"id"
:
"2-6"
,
"name"
:
"美国地质调查局"
,
"depth"
:
1
},
{
"id"
:
"2-7"
,
"name"
:
"能源部"
,
"depth"
:
1
},
{
"id"
:
"2-8"
,
"name"
:
"国防部"
,
"depth"
:
1
},
{
"id"
:
"3-1"
,
"name"
:
"根据《1962年贸易扩展法》第232条,启动调查以确定进口加工关键矿物及其衍生产品是否威胁损害美国国家安全。"
,
"depth"
:
2
},
{
"id"
:
"3-2"
,
"name"
:
"明确关键矿物、稀土元素、加工关键矿物及衍生产品的定义,以统一联邦机构在供应链管理、贸易政策和产业支持中的标准和执行依据。"
,
"depth"
:
2
},
{
"id"
:
"3-3"
,
"name"
:
"商务部应根据19 U.S.C. 1862(d)所列因素,调查进口加工关键矿物及其衍生物对国家安全的影响,包括识别进口来源、分析外国市场操纵行为、评估全球供应链风险、分析美国本土加工能力等。"
,
"depth"
:
2
},
{
"id"
:
"3-4"
,
"name"
:
"商务部应在90天内向财政部、国防部、美国贸易代表、总统经济政策助理和总统贸易与制造高级顾问提交中期报告草案供内部审查和评论。"
,
"depth"
:
2
},
{
"id"
:
"3-5"
,
"name"
:
"相关官员应在收到中期报告草案后15天内向商务部提供评论意见。"
,
"depth"
:
2
},
{
"id"
:
"3-6"
,
"name"
:
"商务部在考虑是否建议采取行动时,应评估征收关税、其他进口限制、规避防范措施、激励国内生产与回收的政策,以及依据《国际紧急经济权力法》可能采取的其他措施。"
,
"depth"
:
2
}
],
"links"
:
[
{
"source"
:
"1-1"
,
"target"
:
"2-1"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-2"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-3"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-4"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-5"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-6"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-7"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-8"
,
"value"
:
10
},
{
"source"
:
"2-1"
,
"target"
:
"3-1"
,
"value"
:
10
},
{
"source"
:
"2-1"
,
"target"
:
"3-2"
,
"value"
:
10
},
{
"source"
:
"2-6"
,
"target"
:
"3-2"
,
"value"
:
10
},
{
"source"
:
"2-7"
,
"target"
:
"3-2"
,
"value"
:
10
},
{
"source"
:
"2-1"
,
"target"
:
"3-3"
,
"value"
:
10
},
{
"source"
:
"2-1"
,
"target"
:
"3-4"
,
"value"
:
10
},
{
"source"
:
"2-2"
,
"target"
:
"3-5"
,
"value"
:
10
},
{
"source"
:
"2-3"
,
"target"
:
"3-5"
,
"value"
:
10
},
{
"source"
:
"2-4"
,
"target"
:
"3-5"
,
"value"
:
10
},
{
"source"
:
"2-5"
,
"target"
:
"3-5"
,
"value"
:
10
},
{
"source"
:
"2-8"
,
"target"
:
"3-5"
,
"value"
:
10
},
{
"source"
:
"2-1"
,
"target"
:
"3-6"
,
"value"
:
10
}
]
}
},
"source_section_num"
:
[
"1"
,
"2"
,
"3"
]
},
{
"领域名称"
:
"新材料"
,
"核心条款内容"
:
[
"关键矿物包括美国地质调查局根据2020年能源法发布的关键矿物清单中所列矿物,以及铀"
,
"稀土元素指能源部2020年4月报告中确定的17种元素,以及美国地质调查局或能源部后续官方报告中认定为稀土元素的任何其他元素"
,
"加工关键矿物指从矿石开采后经过转化为氧化物浓缩物、分离为氧化物、并转化为金属、金属粉末或母合金的所有加工活动"
,
"衍生产品包括所有将加工关键矿物作为投入品的货物,包括半成品(如半导体晶圆、阳极、阴极)和最终产品(如永磁体、电机、电动汽车、电池、智能手机、微处理器、雷达系统、风力涡轮机及其组件、先进光学设备)"
,
"美国商业和国防制造基地严重依赖外国来源的加工关键矿物及其衍生产品"
,
"加工关键矿物及其衍生产品是经济安全和韧性的基础,支撑关键产业、推动技术创新并支持现代美国经济的关键基础设施"
,
"加工关键矿物及其衍生产品是国家安全的基础,构成军事基础设施、能源基础设施和先进防御系统与技术的核心组成部分"
,
"美国对加工关键矿物进口的依赖可能对经济安全、国防准备、价格稳定和经济繁荣构成严重国家安全风险"
,
"全球供应链易受地缘政治紧张、战争、自然灾害、大流行病和贸易冲突的干扰"
,
"主要外国加工关键矿物生产国存在广泛的价格操纵、产能过剩、任意出口限制及利用供应链主导地位扭曲全球市场以获取地缘经济杠杆的行为"
,
"美国必须确保对可负担、有韧性、可持续的加工关键矿物供应的稳定获取,以制造衍生产品"
,
"建立有韧性和可持续的衍生产品制造基础对于创造加工关键矿物的稳定需求至关重要"
,
"过度依赖少数地理区域加剧了地缘政治不稳定和区域中断带来的风险"
,
"商务部长应根据第232条启动调查,以评估加工关键矿物及其衍生产品进口对国家安全的影响"
,
"调查需评估19 U.S.C. 1862(d)所列因素,包括国内国防生产能力和外国竞争对国内产业经济福利的影响"
,
"调查需分析美国所有加工关键矿物及衍生产品进口的来源国占比、体积、具体风险及高风险国家"
,
"调查需分析出口至美国的加工关键矿物生产国所采用的掠夺性经济、定价和市场操纵策略及其对国内投资、美国生产可行性及衍生产品市场价格的扭曲效应"
,
"调查需评估美国国内加工关键矿物及其衍生产品的当前和潜在能力"
,
"商务部长应在调查启动后180天内向总统提交最终报告和建议"
,
"在考虑是否建议采取行动时,应评估征收关税、其他进口限制、规避防范措施、激励国内生产加工与回收的政策,以及依据《国际紧急经济权力法》可能采取的其他措施"
],
"领域举措"
:
{
"type"
:
"思维导图"
,
"name"
:
"新材料领域举措一览"
,
"data"
:
{
"node"
:
[
{
"id"
:
"1-1"
,
"name"
:
"新材料领域举措"
,
"depth"
:
0
},
{
"id"
:
"2-1"
,
"name"
:
"商务部"
,
"depth"
:
1
},
{
"id"
:
"2-2"
,
"name"
:
"白宫经济政策助理"
,
"depth"
:
1
},
{
"id"
:
"2-3"
,
"name"
:
"美国贸易代表办公室"
,
"depth"
:
1
},
{
"id"
:
"2-4"
,
"name"
:
"总统贸易与制造高级顾问"
,
"depth"
:
1
},
{
"id"
:
"2-5"
,
"name"
:
"财政部"
,
"depth"
:
1
},
{
"id"
:
"2-6"
,
"name"
:
"美国地质调查局"
,
"depth"
:
1
},
{
"id"
:
"2-7"
,
"name"
:
"能源部"
,
"depth"
:
1
},
{
"id"
:
"2-8"
,
"name"
:
"国防部"
,
"depth"
:
1
},
{
"id"
:
"3-1"
,
"name"
:
"根据《1962年贸易扩展法》第232条,启动调查以确定进口加工关键矿物及其衍生产品是否威胁损害美国国家安全。"
,
"depth"
:
2
},
{
"id"
:
"3-2"
,
"name"
:
"明确关键矿物、稀土元素、加工关键矿物及衍生产品的定义,以统一联邦机构在供应链管理、贸易政策和产业支持中的标准和执行依据。"
,
"depth"
:
2
},
{
"id"
:
"3-3"
,
"name"
:
"商务部应根据19 U.S.C. 1862(d)所列因素,调查进口加工关键矿物及其衍生物对国家安全的影响,包括识别进口来源、分析外国市场操纵行为、评估全球供应链风险、分析美国本土加工能力等。"
,
"depth"
:
2
},
{
"id"
:
"3-4"
,
"name"
:
"商务部应在90天内向财政部、国防部、美国贸易代表、总统经济政策助理和总统贸易与制造高级顾问提交中期报告草案供内部审查和评论。"
,
"depth"
:
2
},
{
"id"
:
"3-5"
,
"name"
:
"相关官员应在收到中期报告草案后15天内向商务部提供评论意见。"
,
"depth"
:
2
},
{
"id"
:
"3-6"
,
"name"
:
"商务部在考虑是否建议采取行动时,应评估征收关税、其他进口限制、规避防范措施、激励国内生产与回收的政策,以及依据《国际紧急经济权力法》可能采取的其他措施。"
,
"depth"
:
2
}
],
"links"
:
[
{
"source"
:
"1-1"
,
"target"
:
"2-1"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-2"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-3"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-4"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-5"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-6"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-7"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-8"
,
"value"
:
10
},
{
"source"
:
"2-1"
,
"target"
:
"3-1"
,
"value"
:
10
},
{
"source"
:
"2-1"
,
"target"
:
"3-2"
,
"value"
:
10
},
{
"source"
:
"2-6"
,
"target"
:
"3-2"
,
"value"
:
10
},
{
"source"
:
"2-7"
,
"target"
:
"3-2"
,
"value"
:
10
},
{
"source"
:
"2-1"
,
"target"
:
"3-3"
,
"value"
:
10
},
{
"source"
:
"2-1"
,
"target"
:
"3-4"
,
"value"
:
10
},
{
"source"
:
"2-2"
,
"target"
:
"3-5"
,
"value"
:
10
},
{
"source"
:
"2-3"
,
"target"
:
"3-5"
,
"value"
:
10
},
{
"source"
:
"2-4"
,
"target"
:
"3-5"
,
"value"
:
10
},
{
"source"
:
"2-5"
,
"target"
:
"3-5"
,
"value"
:
10
},
{
"source"
:
"2-8"
,
"target"
:
"3-5"
,
"value"
:
10
},
{
"source"
:
"2-1"
,
"target"
:
"3-6"
,
"value"
:
10
}
]
}
},
"source_section_num"
:
[
"1"
,
"2"
,
"3"
]
},
{
"领域名称"
:
"新能源"
,
"核心条款内容"
:
[
"关键矿物包括美国地质调查局根据2020年能源法第7002(c)条发布的《关键矿物清单》中所列矿物,以及铀"
,
"稀土元素包括能源部在2020年4月发布的《关键材料:稀土供应链》中认定的17种元素,以及美国地质调查局或能源部后续官方报告中新增的元素"
,
"加工后的关键矿物指从矿石开采后至转化为金属、金属粉末或母合金所经历的全部加工活动,起始于矿石转化为氧化物浓缩物、分离为氧化物并转化为金属、金属粉末和母合金的阶段"
,
"衍生产品包括所有将加工后的关键矿物作为投入品的货物,包括半成品(如半导体晶圆、阳极、阴极)和最终产品(如永磁体、电机、电动汽车、电池、智能手机、微处理器、雷达系统、风力涡轮机及其组件、先进光学设备)"
,
"商务部长应依据第232条启动调查,评估进口加工后的关键矿物及其衍生产品对国家安全的影响"
,
"在开展第232条调查时,商务部长应评估《美国法典》第19编第1862(d)条所列因素,包括国内生产对国防的影响及外国竞争对国内产业经济福利的影响"
,
"在第232条调查中,需评估美国进口的所有加工后关键矿物及其衍生产品的来源国占比、数量、具体风险类型及被认定为重大风险的国家"
,
"在第232条调查中,需分析出口至美国的国家在关键矿物加工领域所采用的掠夺性经济、定价和市场操纵策略及其对国内投资、生产可行性及衍生产品市场价格的扭曲效应"
,
"在第232条调查中,需分析美国及全球衍生产品制造商对加工后关键矿物的需求量,并评估其需求是否源自被认定为高风险的国家"
,
"在第232条调查中,需审查和评估全球加工后关键矿物及其衍生产品的供应链风险"
,
"在第232条调查中,需分析美国当前及潜在的加工关键矿物及其衍生产品的能力"
,
"在第232条调查中,需统计美国进口所有加工后关键矿物及其衍生产品的总价值及按出口国划分的金额"
,
"商务部长应在本命令发布后90天内提交中期报告草案供财政部长、国防部长、美国贸易代表、总统经济政策助理及总统贸易与制造事务高级顾问内部审阅和评论"
,
"在中期报告草案提交后15天内,相关官员须向商务部长提供评论意见"
,
"商务部长应在调查启动后180天内向总统提交最终报告和建议"
,
"在依据第232条提出建议时,商务部长应考虑征收关税及其他进口限制措施及其适当水平"
,
"在依据第232条提出建议时,商务部长应考虑实施保障措施以防止规避行为及削弱第232条措施的效果"
,
"在依据第232条提出建议时,商务部长应考虑激励国内生产、加工和回收的政策"
,
"在依据第232条提出建议时,商务部长应考虑根据《国际紧急经济权力法》采取其他适当措施以缓解美国国家安全风险"
,
"加工后的关键矿物的定义涵盖从氧化物浓缩物开始的转化过程,包括分离为氧化物、转化为金属、金属粉末和母合金"
],
"领域举措"
:
{
"type"
:
"思维导图"
,
"name"
:
"新能源领域举措一览"
,
"data"
:
{
"node"
:
[
{
"id"
:
"1-1"
,
"name"
:
"新能源领域举措"
,
"depth"
:
0
},
{
"id"
:
"2-1"
,
"name"
:
"商务部"
,
"depth"
:
1
},
{
"id"
:
"2-2"
,
"name"
:
"白宫经济政策助理"
,
"depth"
:
1
},
{
"id"
:
"2-3"
,
"name"
:
"美国贸易代表办公室"
,
"depth"
:
1
},
{
"id"
:
"2-4"
,
"name"
:
"总统贸易与制造高级顾问"
,
"depth"
:
1
},
{
"id"
:
"2-5"
,
"name"
:
"财政部"
,
"depth"
:
1
},
{
"id"
:
"2-6"
,
"name"
:
"美国地质调查局"
,
"depth"
:
1
},
{
"id"
:
"2-7"
,
"name"
:
"能源部"
,
"depth"
:
1
},
{
"id"
:
"2-8"
,
"name"
:
"国防部"
,
"depth"
:
1
},
{
"id"
:
"3-1"
,
"name"
:
"明确关键矿物、稀土元素、加工关键矿物及衍生产品的定义,以统一联邦机构在供应链管理、贸易政策和产业支持中的标准和执行依据。"
,
"depth"
:
2
},
{
"id"
:
"3-2"
,
"name"
:
"商务部应根据19 U.S.C. 1862(d)所列因素,调查进口加工关键矿物及其衍生物对国家安全的影响,包括识别进口来源、分析外国市场操纵行为、评估全球供应链风险、分析美国本土加工能力等。"
,
"depth"
:
2
},
{
"id"
:
"3-3"
,
"name"
:
"商务部应在90天内向财政部、国防部、美国贸易代表、总统经济政策助理和总统贸易与制造高级顾问提交中期报告草案供内部审查和评论。"
,
"depth"
:
2
},
{
"id"
:
"3-4"
,
"name"
:
"相关官员应在收到中期报告草案后15天内向商务部提供评论意见。"
,
"depth"
:
2
},
{
"id"
:
"3-5"
,
"name"
:
"商务部在考虑是否建议采取行动时,应评估征收关税、其他进口限制、规避防范措施、激励国内生产与回收的政策,以及依据《国际紧急经济权力法》可能采取的其他措施。"
,
"depth"
:
2
}
],
"links"
:
[
{
"source"
:
"1-1"
,
"target"
:
"2-1"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-2"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-3"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-4"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-5"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-6"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-7"
,
"value"
:
10
},
{
"source"
:
"1-1"
,
"target"
:
"2-8"
,
"value"
:
10
},
{
"source"
:
"2-1"
,
"target"
:
"3-1"
,
"value"
:
10
},
{
"source"
:
"2-6"
,
"target"
:
"3-1"
,
"value"
:
10
},
{
"source"
:
"2-7"
,
"target"
:
"3-1"
,
"value"
:
10
},
{
"source"
:
"2-1"
,
"target"
:
"3-2"
,
"value"
:
10
},
{
"source"
:
"2-1"
,
"target"
:
"3-3"
,
"value"
:
10
},
{
"source"
:
"2-2"
,
"target"
:
"3-4"
,
"value"
:
10
},
{
"source"
:
"2-3"
,
"target"
:
"3-4"
,
"value"
:
10
},
{
"source"
:
"2-4"
,
"target"
:
"3-4"
,
"value"
:
10
},
{
"source"
:
"2-5"
,
"target"
:
"3-4"
,
"value"
:
10
},
{
"source"
:
"2-8"
,
"target"
:
"3-4"
,
"value"
:
10
},
{
"source"
:
"2-1"
,
"target"
:
"3-5"
,
"value"
:
10
}
]
}
},
"source_section_num"
:
[
"2"
,
"3"
]
}
]
}
},
"附录"
:
{
"政令条款内容"
:
[
{
"section_num"
:
"1"
,
"section_text"
:
"相关风险源于多种因素。首先,全球供应链容易受到地缘政治紧张局势、战争、自然灾害、大流行病和贸易冲突的干扰。其次,全球主要的加工关键矿物外国生产商普遍存在价格操纵、产能过剩、任意出口限制等行为,并利用其在供应链中的主导地位扭曲全球市场,从而对依赖加工关键矿物制造对其经济和国家安全及国防至关重要的衍生产品的美国及其他竞争对手获取地缘政治和经济杠杆。因此,美国对来自外国来源的加工关键矿物的进口依赖,可能对美国经济和国防准备构成严重国家安全风险。第三,美国对加工关键矿物的进口依赖所引发的风险,还延伸至对美国经济、经济安全和国家安全至关重要的衍生产品。为了制造衍生产品,美国必须能够获得价格合理、具有韧性且可持续的加工关键矿物供应。同时,建立一个具有韧性和可持续性的衍生产品制造基础,对于创造加工关键矿物的稳定需求基础至关重要。二者必须并存,以确保经济稳定与国家安全。最后,过度依赖少数地理区域会加剧地缘政治不稳定和区域中断所带来的风险。鉴于上述风险与现实,有必要依据《法案》第232条(第232条)开展调查,以确定加工关键矿物及其衍生产品的进口是否威胁损害美国的国家安全。"
},
{
"section_num"
:
"2"
,
"section_text"
:
"定义。在本命令中:(a)“关键矿物”是指美国地质调查局(USGS)根据《2020年能源法》第7002(c)条(30 U.S.C. 1606)在87 FR 10381中发布的“关键矿物清单”所列的矿物,或任何后续此类清单。术语“关键矿物”也包括铀。(b)“稀土元素”是指美国能源部(DOE)在2020年4月发布的题为《关键材料:稀土供应链》的出版物中确定的17种稀土元素。该术语还包括美国地质调查局或美国能源部在任何后续官方报告或出版物中确定应视为稀土元素的任何其他元素。(c)“加工后的关键矿物”是指在从矿山开采出关键矿物矿石后,直至其转化为金属、金属粉末或母合金过程中所经历的活动。这些活动具体始于矿石转化为氧化物浓缩物、分离为氧化物,并转化为金属、金属粉末和母合金的阶段。(d)“衍生产品”包括所有将加工后的关键矿物作为投入品的货物。这些货物包括半成品(如半导体晶圆、阳和阴)以及最终产品(如永磁体、电机、电动汽车、电池、智能手机、微处理器、雷达系统、风力涡轮机及其组件、先进光学器件)。"
},
{
"section_num"
:
"3"
,
"section_text"
:
"第232条调查。(a) 商务部长应根据第232条启动一项调查,以确定进口的加工关键矿物及其衍生产品的国家安全影响。(b) 在进行本款(a)项所述的调查时,商务部长应评估《美国法典》第19卷第1862(d)条所列因素,即“国内国防生产;外国竞争对国内产业经济福利的影响”,以及其他相关因素,包括:(i) 识别美国进口的所有加工关键矿物及含有此类加工关键矿物的衍生产品;(ii) 各国在加工关键矿物进口及衍生产品进口中的占比和数量,各来源国可能关联的具体风险类型,以及被认定为具有重大风险的来源国;(iii) 分析向美国出口加工关键矿物的国家所采用的掠夺性经济、定价和市场操纵策略与做法所造成的扭曲效应,包括对国内投资和美国生产的可行性的影响,以及评估此类策略和做法如何使这些国家维持其对关键矿物加工行业的控制并扭曲美国衍生产品的市场价格;(iv) 分析美国及全球衍生产品制造商对加工关键矿物的需求,包括评估此类制造商对加工关键矿物的需求中有多少源自本款(b)(ii)和(b)(iii)项所确定的国家;(v) 对加工关键矿物及其衍生产品的全球供应链进行审查与风险评估;(vi) 分析美国当前及潜在的加工关键矿物及其衍生产品的能力;以及(vii) 按总价值和出口国统计的当前所有加工关键矿物及衍生产品进口的美元价值。(c) 商务部长应依照适用法律,迅开展上述调查:"
},
{
"section_num"
:
"4"
,
"section_text"
:
"一般规定。(a) 本命令的任何内容均不得被解释为损害或以其他方式影响:
\
n (i) 法律授予各行政部门或机构及其负责人之权力;或
\
n
\
n (ii) 管理和预算办公室主任在预算、行政或立法提案方面的职能。
\
n
\
n(b) 本命令的实施应符合适用法律,并受可用拨款的限制。
\
n
\
n(c) 本命令无意且并未创建任何可由任何一方对美国、其部门、机构或实体、其官员、雇员或代理人,或任何其他人,在法律或衡平法上强制执行的权利或利益,无论是实体性还是程序性的。白宫,2025年4月15日。[联邦登记号2025-06836,于2025年4月17日8:45am归档;公布日期:2025年4月18日]"
}
]
}
}
const
mindMapData
=
{
id
:
'root'
,
label
:
'名称'
,
children
:
[
]
}
// 核心:绝对不重复
let
idCounter
=
10
;
// 从1000开始自增,纯数字
// 自增ID:永远不重复、长度最短、纯数字、最安全
function
getUniqueId
()
{
return
idCounter
++
;
}
const
list
=
data
.
政令深度分析
.
条款分析
.
科技条款内容
;
const
treeData
=
list
.
map
(
item
=>
{
const
raw
=
item
.
领域举措
.
data
;
mindMapData
.
label
=
item
.
领域举措
.
name
// console.log(item.领域举措.name)
return
convertMindMap
(
raw
);
});
function
convertMindMap
(
rawData
)
{
const
nodeMap
=
{};
// 生成 自增ID(纯数字 4位起,永不重复)
rawData
.
node
.
forEach
(
n
=>
{
nodeMap
[
n
.
id
]
=
{
id
:
getUniqueId
()
+
'-'
+
n
.
id
,
// 👈 纯数字 ID
label
:
n
.
name
,
children
:
[]
};
});
// 建立父子关系
rawData
.
links
.
forEach
(
link
=>
{
const
p
=
nodeMap
[
link
.
source
];
const
c
=
nodeMap
[
link
.
target
];
if
(
p
&&
c
)
p
.
children
.
push
(
c
);
});
const
root
=
rawData
.
node
.
find
(
n
=>
n
.
depth
===
0
);
return
nodeMap
[
root
.
id
];
}
mindMapData
.
children
=
treeData
console
.
log
(
treeData
,
6
);
// [ 制造树, 材料树, 能源树 ]
console
.
log
(
mindMapData
,
7
)
</
script
>
<
style
lang=
"scss"
scoped
>
const
containerRef
=
ref
(
null
)
// 你的 4 层数据(正常支持)
// const mindMapData = {
// id: 'root',
// label: '人工智能领域举措',
// children: [
// {
// id: 'dept1',
// label: '商务部',
// children: [
// {
// id: 'task1',
// label: '在本命令发布之日起90天内,商务部长应与国务卿和白宫科学技术政策办公室(OSTP)主任协商,建立并实施“美国人工智能出口计划”,支持全栈人工智能出口包开发部署。',
// children: [
// { id: 'task11', label: '在本命令发布之日起90天内,商务部长应与国务卿和白宫科学技术政策办公室(OSTP)主任协商,建立并实施“美国人工智能出口计划”,支持全栈人工智能出口包开发部署。' },
// { id: 'task22', label: '商务部长应向产业界主导联合体发布公开征集提案,需包含全栈AI技术包、目标出口国家、数据中心建设运营、所需联邦激励支持机制。' }
// ]
// },
// { id: 'task2', label: '商务部长应向产业界主导联合体发布公开征集提案,需包含全栈AI技术包、目标出口国家、数据中心建设运营、所需联邦激励支持机制。' }
// ]
// },
// {
// id: 'dept2',
// label: '国务院',
// children: [
// { id: 'task3', label: '配合商务部推进AI出口部署,协调外交资源与监管环境。' }
// ]
// }
// ]
// }
let
graph
=
null
// 文字换行(不溢出)
function
splitTextToLines
(
text
,
maxWidth
,
fontSize
)
{
const
canvas
=
document
.
createElement
(
'canvas'
)
const
ctx
=
canvas
.
getContext
(
'2d'
)
ctx
.
font
=
`
${
fontSize
}
px sans-serif`
const
lines
=
[]
let
currentLine
=
''
let
width
=
0
for
(
const
char
of
text
)
{
const
w
=
ctx
.
measureText
(
char
).
width
if
(
width
+
w
>
maxWidth
)
{
lines
.
push
(
currentLine
)
currentLine
=
char
width
=
w
}
else
{
currentLine
+=
char
width
+=
w
}
}
if
(
currentLine
)
lines
.
push
(
currentLine
)
const
lineHeight
=
fontSize
+
8
const
totalHeight
=
lineHeight
*
lines
.
length
+
24
return
{
lines
,
lineHeight
,
totalHeight
}
}
onMounted
(()
=>
{
const
el
=
containerRef
.
value
if
(
!
el
)
return
// 注册节点
G6
.
registerNode
(
'custom-node'
,
{
draw
(
cfg
,
group
)
{
const
isRoot
=
cfg
.
id
===
'root'
const
isDept
=
cfg
.
id
.
startsWith
(
'dept'
)
const
MAX_WIDTH
=
isRoot
?
280
:
isDept
?
240
:
400
const
fontSize
=
isRoot
?
16
:
isDept
?
15
:
14
const
fontWeight
=
isRoot
||
isDept
?
'bold'
:
'normal'
const
color
=
'rgba(5, 95, 194, 1)'
const
padding
=
16
const
{
lines
,
lineHeight
,
totalHeight
}
=
splitTextToLines
(
cfg
.
label
,
MAX_WIDTH
-
padding
*
2
,
fontSize
)
const
nodeW
=
MAX_WIDTH
const
nodeH
=
totalHeight
// 节点背景
group
.
addShape
(
'rect'
,
{
attrs
:
{
x
:
-
nodeW
/
2
,
y
:
-
nodeH
/
2
,
width
:
nodeW
,
height
:
nodeH
,
fill
:
'#f8fcff'
,
stroke
:
color
,
lineWidth
:
1
,
radius
:
6
}
})
// 文字居中
lines
.
forEach
((
line
,
i
)
=>
{
group
.
addShape
(
'text'
,
{
attrs
:
{
text
:
line
,
x
:
0
,
y
:
(
i
-
(
lines
.
length
-
1
)
/
2
)
*
lineHeight
,
textAlign
:
'center'
,
textBaseline
:
'middle'
,
fontSize
,
fontWeight
,
fill
:
color
}
})
})
return
group
},
getAnchorPoints
:
()
=>
[[
0
,
0.5
],
[
1
,
0.5
]]
},
'single-node'
)
// ✅ 恢复正常 TreeGraph,图表不会消失
graph
=
new
G6
.
TreeGraph
({
container
:
el
,
width
:
el
.
offsetWidth
,
height
:
el
.
offsetHeight
,
modes
:
{
default
:
[
'drag-canvas'
,
'zoom-canvas'
,
'collapse-expand'
]
},
defaultNode
:
{
type
:
'custom-node'
},
defaultEdge
:
{
type
:
'cubic-horizontal'
,
style
:
{
stroke
:
'rgba(5, 95, 194, 0.4)'
,
lineWidth
:
1
}
},
// ✅ 核心:固定节点宽度,强制所有层级间距相等
layout
:
{
type
:
'compactBox'
,
direction
:
'LR'
,
getWidth
:
()
=>
400
,
getHGap
:
()
=>
80
,
getVGap
:
()
=>
50
,
}
})
graph
.
data
(
mindMapData
)
graph
.
render
()
// 自适应显示
setTimeout
(()
=>
{
graph
.
fitCenter
()
graph
.
zoomTo
(
0.65
)
},
200
)
})
onUnmounted
(()
=>
graph
?.
destroy
())
</
script
>
<
style
scoped
>
.mind-map-container
{
width
:
100%
;
height
:
100vh
;
background
:
#f5f7fa
;
}
.mind-map
{
width
:
100%
;
height
:
100%
;
}
</
style
>
</
style
>
\ No newline at end of file
src/views/writtingAsstaint/components/WrittingTranslate.vue
浏览文件 @
581d2dec
<
template
>
<
template
>
<div
class=
"translation-content"
ref=
"translationContentRef"
>
<div
class=
"translation-content"
ref=
"translationContentRef"
>
<!-- :class="
{ active: store.highlightClauseId === item.payload?.clause_number }"
<!-- :class="
{ active: store.highlightClauseId === item.payload?.clause_number }"
:data-clause-number="item.payload?.clause_number" -->
:data-clause-number="item.payload?.clause_number" -->
<div
class=
"translation-item"
v-for=
"(item, index) in store.clauseTranslationMessages"
:key=
"index"
>
<!-- 查找 -->
<div
class=
"searchFor"
v-if=
"store.isSsearchFor"
>
<el-input
v-model=
"keyword"
style=
"width: 260px;"
placeholder=
"查找原文内容"
/>
<div
class=
"searchTextNum"
>
<span
v-if=
"total==0"
>
0
</span>
<span
v-else
>
{{
current
+
1
}}
</span>
/
{{
total
}}
</div>
<div
class=
"prev"
@
click=
"prev"
><el-icon><ArrowUp
/></el-icon></div>
<div
class=
"next"
@
click=
"next"
><el-icon><ArrowDown
/></el-icon></div>
<div
class=
"close"
@
click=
"closeClick"
><el-icon><CloseBold
/></el-icon></div>
</div>
<div
class=
"content-box"
ref=
"contentBox"
>
<div
class=
"translation-item"
v-for=
"(item, index) in renderList"
:key=
"index"
>
<div
class=
"item-body"
>
<div
class=
"item-body"
>
<div
class=
"original-text"
v-if=
"store.isShowOriginal"
>
<div
class=
"original-text"
v-if=
"store.isShowOriginal"
>
<span
class=
"index-badge"
>
{{
item
.
payload
?.
clause_section
}}
</span>
<template
v-for=
"(t, i) in item.fragments"
:key=
"i"
>
{{
item
.
payload
?.
clause_content
}}
<span
:class=
"
{ high: t.hit, current: t.hit
&&
currentGlobalIndex === t.globalIndex}">
{{
t
.
text
}}
</span>
</
template
>
</div>
</div>
<div
class=
"translated-text"
>
<div
class=
"translated-text"
>
<span
class=
"clause-title"
>
第
{{
getChineseNumber
(
item
.
payload
?.
clause_number
)
}}
节
</span>
<span
class=
"clause-title"
>
第{{ getChineseNumber(item.payload?.clause_number) }}节
</span>
{{ item.payload?.clause_content_zh }}
{{
item
.
payload
?.
clause_content_zh
}}
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
</template>
<
script
setup
>
<
script
setup
>
import
{
onMounted
,
onUnmounted
,
ref
,
nextTick
,
watch
}
from
"vue"
;
import
{
onMounted
,
onUnmounted
,
ref
,
nextTick
,
watch
,
computed
}
from
"vue"
;
import
{
useRoute
}
from
"vue-router"
;
import
{
useRoute
}
from
"vue-router"
;
import
{
ElMessage
}
from
"element-plus"
;
import
{
ElMessage
}
from
"element-plus"
;
import
{
useWrittingAsstaintStore
}
from
"@/stores/writtingAsstaintStore"
;
import
{
useWrittingAsstaintStore
}
from
"@/stores/writtingAsstaintStore"
;
...
@@ -42,13 +55,122 @@ const getChineseNumber = (num) => {
...
@@ -42,13 +55,122 @@ const getChineseNumber = (num) => {
}
}
return
num
;
return
num
;
};
};
const
closeClick
=
()
=>
{
store
.
handleIsSsearchFor
()
current
.
value
=
0
total
.
value
=
0
keyword
.
value
=
''
}
const
keyword
=
ref
(
''
)
const
contentBox
=
ref
(
null
)
const
current
=
ref
(
0
)
const
total
=
ref
(
0
)
// 渲染列表(不修改原数据,自动更新)
const
renderList
=
computed
(()
=>
{
const
key
=
keyword
.
value
.
trim
()
return
(
store
.
clauseTranslationMessages
||
[]).
map
(
item
=>
{
const
section
=
item
.
payload
?.
clause_section
||
''
const
content
=
item
.
payload
?.
clause_content
||
''
const
fullText
=
section
+
' '
+
content
if
(
!
key
)
{
return
{
...
item
,
fragments
:
[{
text
:
fullText
,
hit
:
false
,
globalIndex
:
-
1
}]
}
}
const
parts
=
fullText
.
split
(
new
RegExp
(
`(
${
key
}
)`
,
'g'
))
const
fragments
=
[]
parts
.
forEach
(
t
=>
{
fragments
.
push
({
text
:
t
,
hit
:
t
===
key
,
globalIndex
:
-
1
})
})
return
{
...
item
,
fragments
}
})
})
// 全局匹配列表(只计算一次,修复蓝色全部选中BUG)
const
globalMatchList
=
computed
(()
=>
{
const
arr
=
[]
renderList
.
value
.
forEach
(
item
=>
{
item
.
fragments
.
forEach
(
f
=>
{
if
(
f
.
hit
)
arr
.
push
(
f
)
})
})
return
arr
})
// 当前高亮的全局索引
const
currentGlobalIndex
=
computed
(()
=>
{
if
(
!
globalMatchList
.
value
.
length
)
return
-
1
return
globalMatchList
.
value
[
current
.
value
]?.
globalIndex
??
-
2
})
// 总数
watch
(
globalMatchList
,
(
val
)
=>
{
total
.
value
=
val
.
length
current
.
value
=
0
},
{
immediate
:
true
})
// 给每个命中项分配唯一 index
watch
([
renderList
,
globalMatchList
],
()
=>
{
let
idx
=
0
const
map
=
new
Map
()
globalMatchList
.
value
.
forEach
(
item
=>
{
map
.
set
(
item
,
idx
++
)
})
renderList
.
value
.
forEach
(
item
=>
{
item
.
fragments
.
forEach
(
f
=>
{
if
(
f
.
hit
)
f
.
globalIndex
=
map
.
get
(
f
)
})
})
})
function
doSearch
()
{
current
.
value
=
0
scrollTo
(
0
)
}
function
prev
()
{
if
(
!
total
.
value
)
return
current
.
value
=
(
current
.
value
-
1
+
total
.
value
)
%
total
.
value
console
.
log
(
current
.
value
)
scrollTo
(
current
.
value
)
}
function
next
()
{
if
(
!
total
.
value
)
return
current
.
value
=
(
current
.
value
+
1
)
%
total
.
value
scrollTo
(
current
.
value
)
}
function
scrollTo
(
idx
)
{
setTimeout
(()
=>
{
const
all
=
contentBox
.
value
?.
querySelectorAll
(
'.high'
)
if
(
all
?.[
idx
])
{
contentBox
.
value
.
scrollTo
({
top
:
all
[
idx
].
offsetTop
-
100
,
behavior
:
'smooth'
})
}
},
0
)
}
</
script
>
</
script
>
<
style
lang=
"scss"
scoped
>
<
style
lang=
"scss"
scoped
>
.
translation-content
{
.
content-box
{
overflow-y
:
auto
;
overflow-y
:
auto
;
margin-top
:
30px
;
margin-top
:
30px
;
height
:
calc
(
100
%
-
50px
);
height
:
calc
(
100
vh
-
2
50px
);
.translation-item
{
.translation-item
{
margin-bottom
:
24px
;
margin-bottom
:
24px
;
.item-body
{
.item-body
{
...
@@ -67,13 +189,48 @@ const getChineseNumber = (num) => {
...
@@ -67,13 +189,48 @@ const getChineseNumber = (num) => {
line-height
:
30px
;
line-height
:
30px
;
}
}
}
}
// .item-header{
// width: 48%;
// }
// .item-body{
// width: 48%;
// }
}
}
}
}
.searchFor
{
display
:
flex
;
align-items
:
center
;
width
:
430px
;
height
:
60px
;
padding
:
12px
0
;
border-radius
:
10px
;
background-color
:
#fff
;
border
:
1px
solid
rgb
(
234
,
236
,
238
);
position
:
fixed
;
top
:
120px
;
right
:
20px
;
:deep
(
.el-input__wrapper
)
{
background-color
:
#fff
;
}
.searchTextNum
{
width
:
70px
;
height
:
100%
;
border-right
:
1px
solid
rgb
(
234
,
236
,
238
);
line-height
:
40px
;
margin-right
:
16px
;
text-align
:
center
;
}
.prev
{
margin-right
:
12px
;
}
.next
{
margin-right
:
12px
;
}
// position: absolute;
}
.high
{
background
:
#ffeb3b
;
}
.current
{
background
:
#409eff
!
important
;
color
:
#fff
!
important
;
}
</
style
>
</
style
>
\ No newline at end of file
src/views/writtingAsstaint/index.vue
浏览文件 @
581d2dec
...
@@ -25,6 +25,7 @@
...
@@ -25,6 +25,7 @@
</div>
</div>
</div>
</div>
</div>
-->
</div>
-->
<IntelligenceLeftTabBar></IntelligenceLeftTabBar>
<IntelligenceLeftTabBar></IntelligenceLeftTabBar>
<!-- 主体区域:子组件 -->
<!-- 主体区域:子组件 -->
<div
style=
"width: 100%;"
>
<div
style=
"width: 100%;"
>
...
@@ -32,25 +33,24 @@
...
@@ -32,25 +33,24 @@
<div
class=
"writting-main"
>
<div
class=
"writting-main"
>
<!-- 左侧子组件:绑定ref -->
<!-- 左侧子组件:绑定ref -->
<!--
<writtingleftBox
ref=
"leftBoxRef"
@
generate=
"handleGenerate"
/>
-->
<!--
<writtingleftBox
ref=
"leftBoxRef"
@
generate=
"handleGenerate"
/>
-->
<writtingleftBox
ref=
"leftBoxRef"
/>
<!--
<writtingleftBox
ref=
"leftBoxRef"
/>
-->
<!-- 翻译 -->
<!-- 翻译 -->
<
WrittingTranslate
v-if=
"store.isShowClauseTranslation&&store.headerTabType=='translate'"
></WrittingTranslate
>
<
!--
<WrittingTranslate
v-if=
"store.isShowClauseTranslation&&store.headerTabType=='translate'"
></WrittingTranslate>
--
>
<!-- 思维导图 -->
<!-- 思维导图
v-else-if="store.isShowClauseTranslation&&store.headerTabType=='mind'"
-->
<WrittingMind
v-else-if=
"store.isShowClauseTranslation&&store.headerTabType=='mind'"
></WrittingMind>
<WrittingMind
></WrittingMind>
<!-- 写报 -->
<!-- 写报 -->
<
WrittingMessage
v-else-if=
"store.isShowClauseTranslation&&store.headerTabType=='message'"
></WrittingMessage
>
<
!--
<WrittingMessage
v-else-if=
"store.isShowClauseTranslation&&store.headerTabType=='message'"
></WrittingMessage>
--
>
<!-- 无数据时显示占位图 -->
<!-- 无数据时显示占位图 -->
<div
v-else
class=
"main-placeholder"
>
<
!--
<
div
v-else
class=
"main-placeholder"
>
<img
src=
"./assets/images/container-image.png"
alt=
"无数据占位图"
/>
<img
src=
"./assets/images/container-image.png"
alt=
"无数据占位图"
/>
<div
class=
"placeholder-text"
>
<div
class=
"placeholder-text"
>
<div
v-if=
"store.isGenerating"
>
智能体写报任务执行中...
</div>
<div
v-if=
"store.isGenerating"
>
智能体写报任务执行中...
</div>
<div
v-else
>
上传文件后点击“生成报文”开始写报...
</div>
<div
v-else
>
上传文件后点击“生成报文”开始写报...
</div>
</div>
</div>
</div>
</div>
-->
<!-- 右侧子组件:绑定ref -->
<!-- 右侧子组件:绑定ref -->
<!--
<writtingMainBox
v-show=
"!!store.reportContent"
ref=
"mainBoxRef"
:report-content=
"store.reportContent"
/>
-->
<!--
<writtingMainBox
v-show=
"!!store.reportContent"
ref=
"mainBoxRef"
:report-content=
"store.reportContent"
/>
-->
...
@@ -71,7 +71,7 @@ import writtingleftBox from "./components/WrittingLeftBox.vue";
...
@@ -71,7 +71,7 @@ import writtingleftBox from "./components/WrittingLeftBox.vue";
import
WrittingHeader
from
"./components/WrittingHeader.vue"
;
//头
import
WrittingHeader
from
"./components/WrittingHeader.vue"
;
//头
import
WrittingBottom
from
"./components/WrittingBottom.vue"
;
//底部
import
WrittingBottom
from
"./components/WrittingBottom.vue"
;
//底部
import
WrittingTranslate
from
"./components/WrittingTranslate.vue"
;
//翻译
import
WrittingTranslate
from
"./components/WrittingTranslate.vue"
;
//翻译
import
WrittingMind
from
"./components/Writting
Translate
.vue"
;
//思维导图
import
WrittingMind
from
"./components/Writting
Mind
.vue"
;
//思维导图
import
WrittingMessage
from
"./components/WrittingMessage.vue"
;
//写报
import
WrittingMessage
from
"./components/WrittingMessage.vue"
;
//写报
...
...
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论