提交 26101b65 authored 作者: 张烨's avatar 张烨

feat:政令对接思维导图接口

上级 dec75869
...@@ -60,6 +60,17 @@ export function getDecreeMainContent(params) { ...@@ -60,6 +60,17 @@ export function getDecreeMainContent(params) {
}) })
} }
// 思维导图
/**
* @param { id }
*/
export function getDecreeMindMap(params) {
return request({
method: 'GET',
url: `/api/administrativeOrderInfo/mindMap/${params.id}`,
})
}
// 相关实体 // 相关实体
/** /**
* @param { id } * @param { id }
......
...@@ -27,15 +27,15 @@ ...@@ -27,15 +27,15 @@
<div class="date-text">近期美国各联邦政府机构发布涉华政令数量汇总</div> <div class="date-text">近期美国各联邦政府机构发布涉华政令数量汇总</div>
<TimeTabPane @time-click="handleDateChange" /> <TimeTabPane @time-click="handleDateChange" />
</div> </div>
<div class="organization-list" ref="refOrganization"> <div class="organization-list" ref="refOrganization" v-loading="organizationInfo.loading">
<div class="organization-item" v-for="(item, index) in organizationInfo.list" :key="index" @click="handleToInstitution(item)"> <div class="organization-item" v-for="(item, index) in organizationInfo.list" :key="index" @click="handleToInstitution(item)">
<div class="item-left"> <div class="item-left">
<img :src="item.orgImage || DefaultIcon2" alt="" /> <img :src="item.imgUrl || DefaultIcon2" alt="" />
</div> </div>
<div class="item-right one-line-ellipsis">{{ item.orgName }}</div> <div class="item-right one-line-ellipsis">{{ item.orgName }}</div>
<div class="item-total">{{ item.total }}项</div> <div class="item-total">{{ item.totalOrderNum }}项</div>
<el-icon color="var(--color-primary-100)"><ArrowRightBold /></el-icon> <el-icon color="var(--color-primary-100)"><ArrowRightBold /></el-icon>
<div class="item-dot" v-if="item.totalRecent">+{{item.totalRecent}}</div> <div class="item-dot" v-if="item.recentOrderNum">+{{item.recentOrderNum}}</div>
</div> </div>
</div> </div>
<div class="pagination-box"> <div class="pagination-box">
...@@ -62,6 +62,7 @@ import tipsTcon from "./assets/icons/tips-icon.png"; ...@@ -62,6 +62,7 @@ import tipsTcon from "./assets/icons/tips-icon.png";
import DefaultIcon2 from "@/assets/icons/default-icon2.png"; import DefaultIcon2 from "@/assets/icons/default-icon2.png";
const organizationInfo = reactive({ const organizationInfo = reactive({
loading: false,
pageNum: 1, pageNum: 1,
pageSize: 8, pageSize: 8,
total: 0, total: 0,
...@@ -73,18 +74,21 @@ const organizationInfo = reactive({ ...@@ -73,18 +74,21 @@ const organizationInfo = reactive({
const onAllOrganization = async (num) => { const onAllOrganization = async (num) => {
organizationInfo.pageNum = num || 1 organizationInfo.pageNum = num || 1
organizationInfo.loading = true
try { try {
let {keyWord, pageNum, pageSize, day} = organizationInfo let {keyWord, pageNum, pageSize, day} = organizationInfo
const res = await getAllOrganization({day, pageNum:pageNum-1, pageSize, keyWord: keyWord||undefined}); const res = await getAllOrganization({day, pageNum:pageNum-1, pageSize, keyWord: keyWord||undefined});
console.log("机构列表", res); console.log("机构列表", res);
if (res.code === 200) { if (res.code === 200) {
organizationInfo.list = res.data.orgList || [];
organizationInfo.total = res.data.total || 0;
} }
} catch (error) { } catch (error) {
console.error("获取机构列表数据失败", error); console.error("获取机构列表数据失败", error);
organizationInfo.list = []; organizationInfo.list = [];
organizationInfo.total = 0; organizationInfo.total = 0;
} }
organizationInfo.loading = false
} }
const handleDateChange = (event) => { const handleDateChange = (event) => {
...@@ -225,7 +229,8 @@ onMounted(() => { ...@@ -225,7 +229,8 @@ onMounted(() => {
.organization-list { .organization-list {
width: 100%; width: 100%;
height: 20px; height: 20px;
margin: 26px 0 16px; padding: 16px 0;
margin-top: 10px;
flex: auto; flex: auto;
display: grid; display: grid;
grid-template-columns: repeat(4, 1fr); grid-template-columns: repeat(4, 1fr);
......
...@@ -18,8 +18,8 @@ const onInitGraph = () => { ...@@ -18,8 +18,8 @@ const onInitGraph = () => {
graph = new G6.Graph({ graph = new G6.Graph({
container: container, container: container,
width, height, width, height,
fitView: true, // fitView: true,
fitViewPadding: 50, // fitViewPadding: 50,
defaultNode: { defaultNode: {
type: "rect", type: "rect",
size: [250, 45], size: [250, 45],
......
...@@ -2202,6 +2202,7 @@ onMounted(async () => { ...@@ -2202,6 +2202,7 @@ onMounted(async () => {
.box5-main { .box5-main {
flex: auto; flex: auto;
height: 20px; height: 20px;
padding-top: 16px;
.box5-chart { .box5-chart {
height: 100%; height: 100%;
} }
......
...@@ -170,7 +170,6 @@ const onWordWrap = (word, num) => { ...@@ -170,7 +170,6 @@ const onWordWrap = (word, num) => {
} }
const handleClickDecree = decree => { const handleClickDecree = decree => {
window.sessionStorage.setItem("curTabName", decree.name);
const route = router.resolve({ const route = router.resolve({
path: "/decreeLayout", path: "/decreeLayout",
query: { query: {
......
...@@ -75,7 +75,7 @@ ...@@ -75,7 +75,7 @@
</div> </div>
</template> </template>
<div class="box2-main"> <div class="box2-main">
<AiTips :tips="tips" /> <!-- <AiTips :tips="tips" /> -->
<div class="graph-box" v-if="contentType==1"> <div class="graph-box" v-if="contentType==1">
<ChartChain :listData="fishbone.list" :baseData="fishbone.base" /> <ChartChain :listData="fishbone.list" :baseData="fishbone.base" />
</div> </div>
......
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
<div class="custom-collapse-title"> <div class="custom-collapse-title">
<div class="custom-collapse-index">{{ index + 1 }}</div> <div class="custom-collapse-index">{{ index + 1 }}</div>
<div class="custom-collapse-name one-line-ellipsis"> <div class="custom-collapse-name one-line-ellipsis">
<span class="text-click-hover" @click.stop="handleClickDecree(item)">{{ item.title }}</span> <span class="text-click-hover" @click.stop="handleClickBull(item)">{{ item.title }}</span>
</div> </div>
</div> </div>
</template> </template>
...@@ -73,9 +73,9 @@ ...@@ -73,9 +73,9 @@
<div class="time-line-icon"> <div class="time-line-icon">
<img style="width: 100%; height: 100%;" :src="item.orgImage || DefaultIcon1" alt=""> <img style="width: 100%; height: 100%;" :src="item.orgImage || DefaultIcon1" alt="">
</div> </div>
<div class="time-line-name" @click="handleToInstitution(item)">{{ item.proposeOrgName }}</div> <div class="time-line-name text-click-hover" @click="handleToInstitution(item)">{{ item.proposeOrgName }}</div>
</div> </div>
<div class="timeline-content">{{ item.describe }}</div> <div class="timeline-content" @click="handleClickDecree(item)">{{ item.describe }}</div>
</div> </div>
</el-timeline-item> </el-timeline-item>
</el-timeline> </el-timeline>
...@@ -167,15 +167,24 @@ const handleGetPrev = async () => { ...@@ -167,15 +167,24 @@ const handleGetPrev = async () => {
}; };
// 跳转行政机构主页 // 跳转行政机构主页
const handleToInstitution = item => { const handleToInstitution = item => {
window.sessionStorage.setItem("curTabName", item.proposeOrgName);
const curRoute = router.resolve({ const curRoute = router.resolve({
path: "/institution", path: "/institution",
query: { query: {
id: item.id id: item.orgId
} }
}); });
window.open(curRoute.href, "_blank"); window.open(curRoute.href, "_blank");
}; };
// 跳转科技政令详情页
const handleClickDecree = item => {
const route = router.resolve({
path: "/decreeLayout",
query: {
id: item.id
}
});
window.open(route.href, "_blank");
};
// 法律依据 // 法律依据
const dependList = ref([]); const dependList = ref([]);
...@@ -196,7 +205,7 @@ const handleGetLaws = async () => { ...@@ -196,7 +205,7 @@ const handleGetLaws = async () => {
} }
}; };
// 跳转科技法案详情页 // 跳转科技法案详情页
const handleClickDecree = decree => { const handleClickBull = decree => {
window.sessionStorage.setItem("billId", decree.billId); window.sessionStorage.setItem("billId", decree.billId);
window.sessionStorage.setItem("curTabName", decree.title); window.sessionStorage.setItem("curTabName", decree.title);
const route = router.resolve({ const route = router.resolve({
...@@ -414,7 +423,6 @@ onMounted(() => { ...@@ -414,7 +423,6 @@ onMounted(() => {
.time-line-name { .time-line-name {
color: rgba(59, 65, 75, 1); color: rgba(59, 65, 75, 1);
font-size: 15px; font-size: 15px;
cursor: pointer;
} }
} }
...@@ -445,6 +453,7 @@ onMounted(() => { ...@@ -445,6 +453,7 @@ onMounted(() => {
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 400;
line-height: 26px; line-height: 26px;
cursor: pointer;
} }
} }
} }
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<div class="box1"> <div class="box1">
<AnalysisBox title="主要指令" :showAllBtn="false"> <AnalysisBox title="主要指令" :showAllBtn="false">
<template #header-btn> <template #header-btn>
<div class="mind-bnt" @click="headerTreeDialog()"> <div class="mind-bnt" @click="onDecreeMindMap()">
<div class="mind-icon"> <div class="mind-icon">
<img src="./assets/images/edit-line.png" alt=""> <img src="./assets/images/edit-line.png" alt="">
</div> </div>
...@@ -123,7 +123,7 @@ ...@@ -123,7 +123,7 @@
</div> </div>
</div> </div>
<el-dialog v-model="isTreeDialog" width="1400px" top="8vh" class="viewpoint-dialog" destroy-on-close> <el-dialog v-model="isTreeDialog" width="1540px" top="8vh" class="viewpoint-dialog" destroy-on-close>
<template #header> <template #header>
<div class="viewpoint-header"> <div class="viewpoint-header">
<div class="viewpoint-title">政令举措思维导图</div> <div class="viewpoint-title">政令举措思维导图</div>
...@@ -144,7 +144,7 @@ import router from "@/router"; ...@@ -144,7 +144,7 @@ import router from "@/router";
import { Search } from '@element-plus/icons-vue' import { Search } from '@element-plus/icons-vue'
import MindGraph from "@/views/decree/com/MindGraph.vue" import MindGraph from "@/views/decree/com/MindGraph.vue"
import { getDecreeOrganization } from "@/api/decree/introduction"; import { getDecreeOrganization } from "@/api/decree/introduction";
import { getDecreeRelatedEntity, getDecreeMainContent } from "@/api/decree/background"; import { getDecreeRelatedEntity, getDecreeMainContent, getDecreeMindMap } from "@/api/decree/background";
import { getDecreehylyList } from "@/api/decree/home"; import { getDecreehylyList } from "@/api/decree/home";
import ActionButton from '@/components/base/ActionButton/index.vue' import ActionButton from '@/components/base/ActionButton/index.vue'
import DefaultIcon1 from "@/assets/icons/default-icon1.png"; import DefaultIcon1 from "@/assets/icons/default-icon1.png";
...@@ -300,62 +300,7 @@ const simpleNumToChinese = (num) => { ...@@ -300,62 +300,7 @@ const simpleNumToChinese = (num) => {
// 思维导图 // 思维导图
const isTreeDialog = ref(false); const isTreeDialog = ref(false);
const refMindGraph = ref(null); const refMindGraph = ref(null);
let mindData = [ const onDecreeMindMap = async () => {
{
id: 1,
label: "在本命令发布之日起90天内,商务部长应与国务卿和白宫科学技术政策办公室(OSTP)主任协商,建立并实施“美国人工智能出口计划”(Program),以支持美国全栈人工智能出口包的开发和部署。执行期限:在本命令发布之日起90天内完成计划的建立与实施。",
children: [
{
id: 5,
label: "商务部",
},
{
id: 6,
label: "国务院",
},
]
},
{
id: 2,
label: "商务部长应向由产业界主导的联合体发布公开征集提案,以纳入该计划。提案必须包括全栈人工智能技术包、目标出口国家或区域集团、数据中心及基础设施的建设运营模式、所需联邦激励和支持机制,并遵守所有相关美国出口管制制度、对外投资法规和最终用户政策。执行期限:提案须在公开征集发布后90天内提交,商务部将滚动审议提案。",
children: [
{
id: 7,
label: "白宫科学和技术政策办公室",
},
{
id: 8,
label: "国防部",
},
]
},
{
id: 3,
label: "制定并执行统一的联邦政府战略,以促进美国人工智能技术和标准的出口;协调技术、金融和外交资源以加速优先人工智能出口项目包的部署;协调美国参与多边倡议和国别伙伴关系;支持伙伴国家营造有利于美国人工智能系统部署的监管、数据和基础设施环境;分析市场准入障碍;并与小企业管理局投资与创新办公室协调促进对美国小型企业的人工智能技术研发和基础设施制造的投资。执行期限:持续执行,无明确终止日期",
children: [
{
id: 9,
label: "能源部",
},
{
id: 10,
label: "美国贸易代表办公室",
},
]
},
{
id: 4,
label: "商务部长应与国务卿、国防部长、能源部长和OSTP主任协商,评估提交的提案。经选定的提案将被指定为优先人工智能出口包,并通过优先获得本命令第4节所述工具予以支持。执行期限:提案评估将在提案提交后持续进行,无明确截止日期。",
children: [
{
id: 11,
label: "小企业管理局",
},
]
},
]
const headerTreeDialog = () => {
isTreeDialog.value = true;
let labelCfg = { let labelCfg = {
position: 'left', position: 'left',
offset: -20, offset: -20,
...@@ -366,18 +311,34 @@ const headerTreeDialog = () => { ...@@ -366,18 +311,34 @@ const headerTreeDialog = () => {
autoWrap: true autoWrap: true
} }
} }
let nodes = [{id: "0", label: "人工智能领域举措"}] isTreeDialog.value = true;
let edges = [] try {
mindData.forEach(item => { let res = await getDecreeMindMap({id: route.query.id});
nodes.push({id:String(item.id), label:item.label, maxWidth:600, labelCfg}) console.log("思维导图", res);
item.children?.forEach(child => { if (res.code === 200) {
nodes.push({id:String(child.id), label:child.label}) let nodes = []
edges.push({id:`${child.id}-${item.id}`, source:String(child.id), target:String(item.id)}) let edges = []
edges.push({id:`0-${child.id}`, source:"0", target:String(child.id)}) Object.keys(res.data||{}).forEach((label, count) => {
}) nodes.push({ id:`node-${count}`, label })
}) })
console.log("思维导图数据", nodes, edges) Object.values(res.data||{}).forEach((list, count) => {
setTimeout(() => { refMindGraph.value.onMindGraphData(nodes, edges) }, 300) list.forEach((item, index) => {
if (item.execAgent?.length) {
nodes.push({ id:`node-${count}-${index}`, label:item.textZh, maxWidth:600, labelCfg })
item.execAgent.forEach((label, num) => {
nodes.push({ id:`node-${count}-${index}-${num}`, label })
edges.push({ id:`edge1-${count}-${index}-${num}`, source:`node-${count}-${index}-${num}`, target:`node-${count}-${index}` })
edges.push({ id:`edge2-${count}-${index}-${num}`, source:`node-${count}`, target:`node-${count}-${index}-${num}` })
})
}
})
})
setTimeout(() => { refMindGraph.value.onMindGraphData(nodes, edges) }, 100)
}
} catch (error) {
console.error("获取思维导图数据失败:", error);
}
} }
// 相关实体 // 相关实体
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论