提交 bb86a146 authored 作者: 张烨's avatar 张烨

feat:科技政令修改

上级 d8b5f5a0
<template>
<div class="wrapper">
<div class="box1">
<div class="box1" v-loading="entityInfo.loading">
<AnalysisBox title="受影响实体" :showAllBtn="false">
<div class="box1-main">
<div class="data-filter">
......@@ -49,7 +49,7 @@
</div>
</AnalysisBox>
</div>
<div class="box2">
<div class="box2" v-loading="box2Params.loading">
<AnalysisBox :showAllBtn="false">
<template #custom-title>
<div class="custom-title">
......@@ -80,7 +80,8 @@
<ChartChain :listData="fishbone.list" :baseData="fishbone.base" />
</div>
<div class="graph-box" v-if="contentType==2">
<GraphChart v-if="graphInfo.nodes?.length" :nodes="graphInfo.nodes" :links="graphInfo.links" layoutType="force" />
<!-- <GraphChart v-if="graphInfo.nodes?.length" :nodes="graphInfo.nodes" :links="graphInfo.links" layoutType="force" /> -->
<RelationChart v-if="graphInfo.nodes?.length" :graphData="graphInfo"></RelationChart>
<el-empty v-else style="height: 100%;" description="暂无数据" :image-size="100" />
</div>
</div>
......@@ -103,6 +104,7 @@ import {
import ChartChain from "./com/ChartChain.vue";
// import AiTips from "./com/AiTips.vue";
import GraphChart from "@/components/base/GraphChart/index.vue";
import RelationChart from "@/components/base/RelationChart/index.vue"
import defaultIcon2 from "@/assets/icons/default-icon2.png";
import noticeIcon from "./assets/images/notice-icon.png";
import icon422 from "./assets/images/icon422.png";
......@@ -134,6 +136,7 @@ const handleGetHylyList = async () => {
// 受影响实体
const entityInfo = reactive({
loading: false,
keyword: "",
pageSize: 10,
pageNum: 1,
......@@ -144,6 +147,7 @@ const entityInfo = reactive({
})
const onDecreeEntities = async (page=1) => {
entityInfo.pageNum = page;
entityInfo.loading = true;
try {
let params = {
id: route.query.id,
......@@ -154,19 +158,31 @@ const onDecreeEntities = async (page=1) => {
}
const res = await getDecreeEntities(params);
console.log("受影响实体:", res);
if (res.code === 200) {
if (res.code === 200 && res.data) {
entityInfo.list = res.data.companyInfos;
entityInfo.total = res.data.total;
if (entityInfo.total && entityInfo.list.every(item => item.id!=entityInfo.id)) {
headerChartData(entityInfo.list[0])
}
} else {
entityInfo.list = [];
entityInfo.total = 0;
fishbone.list = [];
graphInfo.nodes = [];
}
} catch (error) {
console.log("获取受影响实体失败", error);
entityInfo.list = [];
entityInfo.total = 0;
fishbone.list = [];
graphInfo.nodes = [];
}
entityInfo.loading = false;
};
const contentType = ref(1);
const box2Params = reactive({
loading: false,
})
const headerContentType = (type) => {
contentType.value = type;
if (!entityInfo.total) return;
......@@ -206,9 +222,7 @@ const onDecreeRelatedChain = async (id) => {
industryChain.list = res.data;
if (industryChain.list.length) onDecreeChainNodes(industryChain.list[0].id)
}
} catch (error) {
console.log("获取产业链失败", error);
}
} catch (error) {}
};
// 产业链鱼骨图
......@@ -217,6 +231,7 @@ const fishbone = reactive({
base: [],
})
const onDecreeChainNodes = async (id) => {
box2Params.loading = true;
industryChain.id = id;
try {
const res = await getDecreeChainNodes({ id });
......@@ -238,31 +253,57 @@ const onDecreeChainNodes = async (id) => {
return {...item, name: ['上游', '中游', '下游'][index]}
});
}
} catch (error) {
console.log("获取产业链鱼骨图失败", error);
}
} catch (error) {}
box2Params.loading = false;
};
// 实体关系
const graphInfo = reactive({
nodes: [],
links: [],
rootId: "",
});
const onDecreeRelatedEntitie = async (orgId) => {
box2Params.loading = true;
try {
const res = await getDecreeRelatedEntitie({ orgId, rule:false, withSanInfo:false });
console.log("实体关系:", res);
if (res.code === 200) {
let arr1 = res.data.parentOrgList.map(item => ({ ...item, level: 1 }))
let arr3 = res.data.childrenOrgList.map(item => ({ ...item, level: 3 }))
let arr1 = res.data.parentOrgList.map((item, index) => {
return {
id: `1-${index}`,
text: item.name,
description: item.description,
level: 1,
}
})
let arr3 = res.data.childrenOrgList.map((item, index) => {
return {
id: `3-${index}`,
text: item.name,
description: item.description,
level: 3,
}
})
graphInfo.links = [...arr1,...arr3].map(onFormatLink)
graphInfo.nodes = [...arr1,...arr3].map(onFormatNode)
graphInfo.nodes.unshift(onFormatNode({name:res.data.orgName, id:res.data.orgId}, -1))
graphInfo.links = [...arr1,...arr3].map((item => {
return {
from: '0-0',
to: item.id,
text: (item.level==1 ? '被' : '') + item.description,
fontColor: (item.level==1 ? '#ff954d' : '#218139'),
color: (item.level==1 ? '#fbf0e9' : '#e4eee7'),
textOffset_x: -20,
lineWidth: 5
}
}))
graphInfo.nodes = [...arr1,...arr3]
graphInfo.nodes.unshift({text:res.data.orgName, id:'0-0', level: 2})
graphInfo.rootId = '0-0'
console.log('graphInfo', graphInfo)
}
} catch (error) {
console.log("获取实体关系失败", error);
}
} catch (error) {}
box2Params.loading = false
}
const onFormatLink = (item, index) => {
return {
......
<template>
<div class="introduction-wrap">
<div class="left">
<div class="box1">
<div class="box1" v-loading="box1Params.loading">
<AnalysisBox title="提出背景" :showAllBtn="false">
<template #header-btn>
<div class="header-btn-box">
<div class="btn" :class="{ btnActive: box1ActiveBtn === 1 }" @click="handleClickBox1Btn(1)">涉华背景</div>
<div class="btn" :class="{ btnActive: box1ActiveBtn === 2 }" @click="handleClickBox1Btn(2)">全部背景</div>
<div class="btn" :class="{ btnActive: box1Params.active === 1 }" @click="handleClickBox1Btn(1)">涉华背景</div>
<div class="btn" :class="{ btnActive: box1Params.active === 2 }" @click="handleClickBox1Btn(2)">全部背景</div>
</div>
</template>
<div class="box1-container">
......@@ -20,11 +20,11 @@
</div> -->
</div>
</div>
<div class="box1-footer" v-if="backgroundListNum > 10">
<div class="box1-footer-left">{{ `共 ${backgroundListNum} 项` }}</div>
<div class="box1-footer-right">
<el-pagination :page-size="10" @current-change="handleCurrentChange" :current-page="currentPage"
background layout="prev, pager, next" :total="backgroundListNum" />
<div class="box-footer">
<div class="box-footer-left">{{ `共 ${box1Params.total} 项` }}</div>
<div class="box-footer-right">
<el-pagination :page-size="box1Params.size" @current-change="handleGetBackground" :current-page="box1Params.page"
background layout="prev, pager, next" :total="box1Params.total" />
</div>
</div>
</div>
......@@ -60,6 +60,13 @@
</el-collapse>
</div>
</div>
<div class="box-footer" style="padding: 0 18px 16px;">
<div class="box-footer-left">{{ `共 ${box2Params.total} 项` }}</div>
<div class="box-footer-right">
<el-pagination :page-size="box2Params.size" @current-change="handleGetLaws" :current-page="box2Params.page"
background layout="prev, pager, next" :total="box2Params.total" />
</div>
</div>
</AnalysisBox>
</div>
</div>
......@@ -126,56 +133,46 @@ const decodeMaybeBase64NumericId = (raw) => {
const decreeId = computed(() => decodeMaybeBase64NumericId(route.query.id));
// 提出背景
const box1ActiveBtn = ref(1);
const backgroundList = ref([]);
const box1Params = reactive({
loading: false,
size: 5,
page: 1,
total: 0,
active: 1,
})
const handleClickBox1Btn = btn => {
box1ActiveBtn.value = btn;
handleCurrentChange(1)
box1Params.active = btn;
handleGetBackground()
};
const backgroundListNum = ref(0);
const backgroundList = ref([
// {
// content: "认为人工智能(AI)是一项将决定未来几十年经济增长、国家安全和全球竞争力的基础性技术"
// },
// {
// content: "要求美国不仅必须在开发通用和前沿AI能力方面领先,还必须确保美国的人工智能技术、标准和治理模式在全球范围内被采用"
// },
]);
const currentPage = ref(1);
const handleCurrentChange = page => {
currentPage.value = page;
handleGetBackground();
};
const handleGetBackground = async () => {
const params = {
cRelated: box1ActiveBtn.value === 1,
currentPage: currentPage.value - 1,
pageSize: 10,
id: decreeId.value
};
const handleGetBackground = async (page = 1) => {
box1Params.page = page;
box1Params.loading = true;
try {
const res = await getDecreeBackground(params);
const res = await getDecreeBackground({
cRelated: box1Params.active == 1,
currentPage: box1Params.page - 1,
pageSize: box1Params.size,
id: decreeId.value
});
console.log("提出背景", res);
if (res.code === 200 && res.data) {
backgroundListNum.value = res.data.numberOfElements;
box1Params.total = res.data.numberOfElements;
backgroundList.value = res.data.content;
} else {
backgroundListNum.value = 0;
box1Params.total = 0;
backgroundList.value = [];
}
} catch (error) {
backgroundListNum.value = 0;
box1Params.total = 0;
backgroundList.value = [];
}
box1Params.loading = false;
};
// 前序政令
const prevList = ref([
// {
// proposeOrgName: "白宫",
// postDate: "2025-07-31",
// describe: "美商务部发布指南,警告全球企业使用华为昇腾芯片可能违反美国出口管制。意在限制中国AI产业发展,阻碍其获得先进算力。"
// },
]);
const prevList = ref([]);
const handleGetPrev = async () => {
try {
const res = await getDecreePrev({ id: decreeId.value });
......@@ -199,12 +196,6 @@ const handleToInstitution = item => {
}
});
window.open(curRoute.href, "_blank");
// router.push({
// path: "/institution",
// query: {
// id: item.orgId
// }
// })
};
// 跳转科技政令详情页
const handleClickDecree = item => {
......@@ -215,32 +206,37 @@ const handleClickDecree = item => {
}
});
window.open(route.href, "_blank");
// router.push({
// path: "/decreeLayout",
// query: {
// id: item.id
// }
// })
};
// 法律依据
const box2Params = reactive({
loading: false,
size: 5,
page: 1,
total: 0,
active: [],
list: [],
})
const handleGetLaws = async () => {
const handleGetLaws = async (page = 1) => {
box2Params.page = page;
box2Params.loading = true;
try {
const res = await getDecreeDepend({ id: decreeId.value });
const res = await getDecreeDepend({
id: decreeId.value,
currentPage: box2Params.page - 1,
pageSize: box2Params.size,
});
console.log("法律依据", res);
if (res.code === 200 && res.data) {
box2Params.list = res.data;
box2Params.total = 0
} else {
box2Params.list = [];
box2Params.total = 0
}
} catch (error) {
box2Params.list = [];
box2Params.total = 0
}
box2Params.loading = false;
};
......@@ -361,21 +357,6 @@ onMounted(() => {
background-color: rgba(247, 248, 249, 1);
}
}
.box1-footer {
display: flex;
justify-content: space-between;
margin-top: 10px;
.box1-footer-left {
height: 20px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 20px;
}
}
}
.box2 {
......@@ -507,4 +488,20 @@ onMounted(() => {
}
}
}
.box-footer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 10px;
.box-footer-left {
height: 20px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 20px;
}
}
</style>
\ No newline at end of file
......@@ -74,7 +74,7 @@
</div>
</AnalysisBox>
</div>
<div>
<div v-loading="relateParams.loading">
<AnalysisBox title="相关事件" :showAllBtn="false">
<div class="box2-main">
<el-empty v-if="!relatedData.length" description="暂无数据" :image-size="100" />
......@@ -90,6 +90,7 @@
<div class="content">{{ item.sjnr }}</div>
</div>
</div>
<SimplePagination v-model:current-page="relateParams.page" :page-size="relateParams.size" :total="relateParams.total" @page-change="onDecreeRelatedEvent" />
</div>
</AnalysisBox>
</div>
......@@ -106,12 +107,12 @@
<div class="box3">
<AnalysisBox title="发布机构" :showAllBtn="false">
<div class="box3-top">
<div class="box3-top-top" @click="handleToInstitution(box3TopTopData)">
<div class="box3-top-top">
<div class="left">
<img :src="box3TopTopData?.logo || DefaultIcon2" alt="" />
</div>
<div class="right">
<div class="name">{{ box3TopTopData.name + " >" }}</div>
<div class="name text-click-hover" @click="handleToInstitution(box3TopTopData)">{{ box3TopTopData.name + " >" }}</div>
<div class="ename">{{ box3TopTopData.eName }}</div>
</div>
</div>
......@@ -158,7 +159,7 @@
</template>
<script setup>
import { ref, onMounted } from "vue";
import { ref, onMounted, reactive } from "vue";
import { useRoute } from "vue-router";
import router from "@/router";
import WarnningPane from '@/components/base/WarningPane/index.vue'
......@@ -171,7 +172,8 @@ import {
getOverview,
} from "@/api/decree/introduction";
import { getDecreeRelatedEvent } from "@/api/decree/background";
import AiSummary from '@/components/base/Ai/AiSummary/index.vue'
import AiSummary from '@/components/base/Ai/AiSummary/index.vue';
import SimplePagination from "@/components/SimplePagination.vue";
import DefaultIcon1 from "@/assets/icons/default-icon1.png";
import DefaultIcon2 from "@/assets/icons/default-icon2.png";
......@@ -296,9 +298,21 @@ const onOverview = async () => {
// 相关事件
const relatedData = ref([]);
const handleGetRelateEvents = async () => {
const relateParams = reactive({
size: 5,
page: 1,
total: 0,
loading: false,
})
const onDecreeRelatedEvent = async (page) => {
if (page) keyDecreeInfo.page = page
relateParams.loading = true;
try {
const res = await getDecreeRelatedEvent({id: decreeId.value});
const res = await getDecreeRelatedEvent({
id: decreeId.value,
pageNum: relateParams.page -1,
pageSize: relateParams.size,
});
console.log("相关事件", res);
if (res.code === 200 && res.data) {
relatedData.value = res.data;
......@@ -307,8 +321,8 @@ const handleGetRelateEvents = async () => {
}
} catch (error) {
relatedData.value = [];
console.error("获取相关事件数据失败", error);
}
relateParams.loading = false;
};
// 发布机构
......@@ -382,7 +396,7 @@ onMounted(() => {
onOverview()
onKeyWordUp()
onRiskSignalData()
handleGetRelateEvents();
onDecreeRelatedEvent();
handleGetOrgnization();
});
</script>
......
......@@ -61,6 +61,13 @@
</div>
</div>
</div>
<div class="box-footer" style="padding: 10px 18px 16px;">
<div class="box-footer-left">{{ `共 ${box1Params.total} 项` }}</div>
<div class="box-footer-right">
<el-pagination :page-size="box1Params.size" @current-change="onMainContentData" :current-page="box1Params.page"
background layout="prev, pager, next" :total="box1Params.total" />
</div>
</div>
</div>
</div>
</AnalysisBox>
......@@ -159,6 +166,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 SimplePagination from "@/components/SimplePagination.vue";
import { onNumToChinese } from "@/views/marketAccessRestrictions/utils/index"
const route = useRoute();
......@@ -217,14 +225,24 @@ 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 box1Params = reactive({
loading: false,
size: 5,
page: 1,
total: 0,
})
const onMainContentData = async () => {
const onMainContentData = async (page=1) => {
box1Params.page = page
box1Params.loading = true;
try {
const keyword = commandWord.value;
const id = decreeId.value;
if (!id) return;
const res = await getDecreeMainContent({ id, keyword, domainId: areaType.value });
const res = await getDecreeMainContent({
id,
keyword: keyword || null,
domainId: areaType.value || null,
currentPage: box1Params.page,
pageSize: box1Params.size,
});
console.log("主要指令", res);
if (res && res.code === 200) {
contentList.value = res.data || [];
......@@ -936,4 +954,20 @@ onMounted(() => {
}
}
}
.box-footer {
display: flex;
justify-content: space-between;
align-items: center;
margin-top: 10px;
.box-footer-left {
height: 20px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 20px;
}
}
</style>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论