提交 c5dda08b authored 作者: 李智林's avatar 李智林

合作限制

上级 2dda3480
...@@ -161,7 +161,9 @@ body { ...@@ -161,7 +161,9 @@ body {
color: rgba(10, 18, 30, 1); color: rgba(10, 18, 30, 1);
border-bottom: 1px solid #e5e7eb; border-bottom: 1px solid #e5e7eb;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
position: relative; position: sticky;
top: 0;
z-index: 2000;
box-sizing: border-box; box-sizing: border-box;
height: 72px; height: 72px;
} }
......
...@@ -48,7 +48,7 @@ export function getCoopRestrictionNews(params) { ...@@ -48,7 +48,7 @@ export function getCoopRestrictionNews(params) {
export function getCoopRestrictionSocial(params) { export function getCoopRestrictionSocial(params) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/api/commonFeature/social/${params.moduleId}` url: `/api/commonFeature/remarks/${params.moduleId}`
}) })
} }
...@@ -96,3 +96,57 @@ export function getCoopRestrictionList(params) { ...@@ -96,3 +96,57 @@ export function getCoopRestrictionList(params) {
params params
}) })
} }
// 合作限制-查询简介接口
/**
* @param {limitId} 合作限制ID
* @header token
*/
export function getCoopRestrictionIntroduction(params) {
return request({
method: 'GET',
url: `/api/cooperationlimitinfo/searchBlurb`,
params
})
}
// 合作限制-相关实体接口
/**
* @param {limitId} 合作限制ID
* @header token
*/
export function getCoopRestrictionRelated(params) {
return request({
method: 'GET',
url: `/api/cooperationlimitinfo/getLimitEntity`,
params
})
}
// 合作限制-背景分析接口
/**
* @param {limitId} 合作限制ID
* @header token
*/
export function getCoopRestrictionBackground(params) {
return request({
method: 'GET',
url: `/api/cooperationlimitinfo/getLimitBackGround`,
params
})
}
// 合作限制-限制条款接口
/**
* @param {limitId} 合作限制ID
* @header token
*/
export function getCoopRestrictionClause(params) {
return request({
method: 'GET',
url: `/api/cooperationlimitinfo/getLimitClause`,
params
})
}
...@@ -79,26 +79,19 @@ export function getIndustryCountByYear(sanTypeId) { ...@@ -79,26 +79,19 @@ export function getIndustryCountByYear(sanTypeId) {
/** /**
* 不同领域每年数量 * 不同领域每年数量
* @returns {Promise<{ * @param {Object} data - 请求参数
* data:{ * @param {boolean} data.isRule - 是否为规则
* year?: number * @param {string} [data.startYear="2020"] - 开始年份
* domainNum: { * @param {string} [data.endYear] - 结束年份
* [ key: string]: number; * @param {number} [data.sanTypeId=1] - 制裁类型ID
* } * @returns {Promise}
* }[]
* domains: string[]
* }>}
*/ */
export function getCountDomainByYear(isRule, startYear = "2020", endYear = String(new Date().getFullYear())) { export function getCountDomainByYear(data) {
return request200( return request200(
request({ request({
method: "POST", method: "POST",
url: "/api/entitiesDataCount/getAnnualSanDomain", url: "/api/entitiesDataCount/getAnnualSanDomain",
data: { data
isRule,
startYear,
endYear
}
}) })
); );
} }
...@@ -128,7 +121,7 @@ export function getSanctionsInfoCount() { ...@@ -128,7 +121,7 @@ export function getSanctionsInfoCount() {
* sanReason: string * sanReason: string
* }[]>} * }[]>}
*/ */
export function getSanctionProcess(typeName = "实体清单", pageNum = 1, pageSize = 10) { export function getSanctionProcess(typeName = "实体清单", pageNum = 1, pageSize = 10,isCn = false) {
return request200( return request200(
request({ request({
method: "POST", method: "POST",
...@@ -136,7 +129,8 @@ export function getSanctionProcess(typeName = "实体清单", pageNum = 1, pageS ...@@ -136,7 +129,8 @@ export function getSanctionProcess(typeName = "实体清单", pageNum = 1, pageS
data: { data: {
typeName, typeName,
pageNum, pageNum,
pageSize pageSize,
isCn
} }
}) })
); );
...@@ -498,14 +492,17 @@ export function getEntitiesUpdateCount(sanTypeId = 1) { ...@@ -498,14 +492,17 @@ export function getEntitiesUpdateCount(sanTypeId = 1) {
/** /**
* 制裁领域分析 * 制裁领域分析
* @param {string} rule - 规则
* @param {string} type - 类型
*/ */
export function getSanDomainCount(rule) { export function getSanDomainCount(rule, type) {
return request200( return request200(
request({ request({
method: "GET", method: "GET",
url: "/api/entitiesDataCount/getSanDomainCount", url: "/api/entitiesDataCount/getSanDomainCount",
params: { params: {
rule rule,
type
} }
}) })
); );
......
import request from "@/api/request.js"; import request from "@/api/request.js";
// 实体清单-制裁概况-获取实体清单基本信息 // 实体清单-制裁概况-获取实体清单基本信息
export function getEntityInfo() { export function getEntityInfo(sanType) {
return request({ return request({
method: 'GET', method: 'GET',
url: `/api/sanctionList/baseInfo/el` url: `/api/sanctionList/baseInfo/${sanType}`
}) })
} }
......
...@@ -438,6 +438,45 @@ onMounted(() => { ...@@ -438,6 +438,45 @@ onMounted(() => {
.btn { .btn {
margin-left: 8px; margin-left: 8px;
} }
:deep(.el-button) {
height: 28px;
padding: 2px 8px;
border-radius: 4px;
font-size: 16px;
font-weight: 400;
font-family: Microsoft YaHei;
line-height: 24px;
}
:deep(.el-button--primary.is-plain) {
background-color: #f0f7ff;
border-color: rgb(5, 95, 194);
color: rgb(5, 95, 194);
border-width: 1px;
&:hover,
&:focus {
background-color: #f0f7ff;
border-color: rgb(5, 95, 194);
color: rgb(5, 95, 194);
}
}
:deep(.el-button--info.is-plain) {
background-color: #fff;
border-color: rgb(230, 231, 232);
color: rgb(59, 65, 75);
&:hover,
&:focus {
background-color: #fff;
border-color: rgb(230, 231, 232);
color: rgb(59, 65, 75);
}
}
} }
.header-right { .header-right {
...@@ -468,8 +507,8 @@ onMounted(() => { ...@@ -468,8 +507,8 @@ onMounted(() => {
width: 1150px; width: 1150px;
height: 415px; height: 415px;
background: #fff; background: #fff;
border-radius: 4px; border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
.box1-main { .box1-main {
.box1-main-center { .box1-main-center {
margin: 0 22px; margin: 0 22px;
...@@ -555,8 +594,8 @@ onMounted(() => { ...@@ -555,8 +594,8 @@ onMounted(() => {
width: 1150px; width: 1150px;
height: 415px; height: 415px;
background: #fff; background: #fff;
border-radius: 4px; border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
.box2-main { .box2-main {
// margin-top: 9px; // margin-top: 9px;
width: 1110px; width: 1110px;
...@@ -661,8 +700,8 @@ onMounted(() => { ...@@ -661,8 +700,8 @@ onMounted(() => {
width: 576px; width: 576px;
height: 845px; height: 845px;
background: #fff; background: #fff;
border-radius: 4px; border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
.background-wrap-right-main { .background-wrap-right-main {
.right-box1 { .right-box1 {
height: 365px; height: 365px;
......
...@@ -270,7 +270,7 @@ ...@@ -270,7 +270,7 @@
<div class="box3-main"> <div class="box3-main">
<div <div
class="box3-item" class="box3-item"
v-for="(news, index) in newsList" v-for="(news, index) in newsList.slice(0, 5)"
:key="index" :key="index"
@click="handleClickToNewsDetail(news)" @click="handleClickToNewsDetail(news)"
> >
...@@ -679,6 +679,11 @@ ...@@ -679,6 +679,11 @@
style="width: 120px" style="width: 120px"
@change="handlePxChange" @change="handlePxChange"
> >
<template #prefix>
<div style="display: flex; align-items: center; height: 100%">
<img :src="desc" style="width: 14px; height: 14px" />
</div>
</template>
<el-option <el-option
v-for="item in releaseTimeList" v-for="item in releaseTimeList"
:key="item.value" :key="item.value"
...@@ -693,10 +698,9 @@ ...@@ -693,10 +698,9 @@
class="right-main-box" class="right-main-box"
v-for="(item, index) in bills" v-for="(item, index) in bills"
:key="index" :key="index"
@click="handleClickToDetailO(item)"
> >
<div class="header"> <div class="header">
<div class="title">{{ item.name }}</div> <div class="title" @click="handleClickToDetailO(item)">{{ item.name }}</div>
<div class="en-title">{{ item.eName }}</div> <div class="en-title">{{ item.eName }}</div>
</div> </div>
<div class="main"> <div class="main">
...@@ -716,7 +720,9 @@ ...@@ -716,7 +720,9 @@
</div> </div>
<div class="item"> <div class="item">
<div class="item-left">{{ "最新动议:" }}</div> <div class="item-left">{{ "最新动议:" }}</div>
<div class="item-right">{{ item.zxdy }}</div> <div class="item-right">
<CommonPrompt :content="item.zxdy" />
</div>
</div> </div>
<div class="item"> <div class="item">
<div class="item-left">{{ "法案进展:" }}</div> <div class="item-left">{{ "法案进展:" }}</div>
...@@ -791,20 +797,14 @@ import getDoublePieChart from "./utils/doublePieChart"; ...@@ -791,20 +797,14 @@ import getDoublePieChart from "./utils/doublePieChart";
import defaultNew from "../assets/images/default-icon-news.png"; import defaultNew from "../assets/images/default-icon-news.png";
import News1 from "./assets/images/news1.png"; import News1 from "./assets/images/news1.png";
import News2 from "./assets/images/news2.png"; import defaultIcon01 from "../../../assets/icons/default-icon1.png";
import News3 from "./assets/images/news3.png"; import desc from "./assets/icons/icon-desc.png";
import News4 from "./assets/images/news4.png";
import News5 from "./assets/images/news5.png";
import Message1 from "./assets/images/message-icon1.png"; import Message1 from "./assets/images/message-icon1.png";
import Message2 from "./assets/images/message-icon2.png"; import Message2 from "./assets/images/message-icon2.png";
import Message3 from "./assets/images/message-icon3.png"; import Message3 from "./assets/images/message-icon3.png";
import Box8Img1 from "./assets/images/box8-icon1.png";
import Box8Img2 from "./assets/images/box8-icon2.png";
import Box8Img3 from "./assets/images/box8-icon3.png";
import Box8Img4 from "./assets/images/box8-icon4.png";
import Box8Img5 from "./assets/images/box8-icon5.png";
import Cyy from "@/assets/icons/cyy.png"; import Cyy from "@/assets/icons/cyy.png";
import Zyy from "@/assets/icons/zyy.png"; import Zyy from "@/assets/icons/zyy.png";
...@@ -911,6 +911,7 @@ const currentPage = ref(1); ...@@ -911,6 +911,7 @@ const currentPage = ref(1);
const handleCurrentChange = page => { const handleCurrentChange = page => {
currentPage.value = page; currentPage.value = page;
handleGetBills(); handleGetBills();
handleToPosi("position4");
}; };
const containerRef = ref(null); const containerRef = ref(null);
...@@ -1455,6 +1456,7 @@ const box9YearList = ref([ ...@@ -1455,6 +1456,7 @@ const box9YearList = ref([
} }
]); ]);
const box9HasData = ref(true); const box9HasData = ref(true);
let box9ChartInstance = null;
const getBox9Data = async () => { const getBox9Data = async () => {
const params = { const params = {
year: box9selectetedTime.value year: box9selectetedTime.value
...@@ -1486,7 +1488,7 @@ const handleBox9Data = async () => { ...@@ -1486,7 +1488,7 @@ const handleBox9Data = async () => {
}; };
}) })
); );
setChart(box9Chart, "box9Chart"); box9ChartInstance = setChart(box9Chart, "box9Chart");
} }
}; };
...@@ -1698,7 +1700,12 @@ const handleSearch = () => { ...@@ -1698,7 +1700,12 @@ const handleSearch = () => {
window.open(curRoute.href, "_blank"); window.open(curRoute.href, "_blank");
}; };
const handleResize = () => {
box9ChartInstance && box9ChartInstance.resize();
};
onMounted(async () => { onMounted(async () => {
window.addEventListener("resize", handleResize);
handleGetHylyList(); handleGetHylyList();
// 获取风险信号 // 获取风险信号
handleGetBillRiskSignal(); handleGetBillRiskSignal();
...@@ -1728,7 +1735,9 @@ onMounted(async () => { ...@@ -1728,7 +1735,9 @@ onMounted(async () => {
handleBox9Data(); handleBox9Data();
}); });
onUnmounted(() => {}); onUnmounted(() => {
window.removeEventListener("resize", handleResize);
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
...@@ -2525,7 +2534,7 @@ onUnmounted(() => {}); ...@@ -2525,7 +2534,7 @@ onUnmounted(() => {});
} }
.box3-main { .box3-main {
height: 402px; height: 402px;
overflow-y: auto; overflow-y: hidden;
overflow-x: hidden; overflow-x: hidden;
padding-top: 6px; padding-top: 6px;
.box3-item { .box3-item {
...@@ -2649,6 +2658,7 @@ onUnmounted(() => {}); ...@@ -2649,6 +2658,7 @@ onUnmounted(() => {});
overflow-y: auto; overflow-y: auto;
box-sizing: border-box; box-sizing: border-box;
padding-top: 8px; padding-top: 8px;
padding-bottom: 20px;
.box4-main-item { .box4-main-item {
margin-top: 16px; margin-top: 16px;
display: flex; display: flex;
...@@ -2774,12 +2784,6 @@ onUnmounted(() => {}); ...@@ -2774,12 +2784,6 @@ onUnmounted(() => {});
.box5-main { .box5-main {
height: 397px; height: 397px;
} }
// .box5-select {
// position: absolute;
// top: 53px;
// left: 100px;
// z-index: 100;
// }
} }
.box6 { .box6 {
margin-left: 20px; margin-left: 20px;
...@@ -2982,26 +2986,19 @@ onUnmounted(() => {}); ...@@ -2982,26 +2986,19 @@ onUnmounted(() => {});
} }
} }
} }
// .box-center {
// height: 45px;
// padding-right: 20px;
// display: flex;
// align-items: center;
// justify-content: flex-end;
// }
.box8-main { .box8-main {
height: 380px; height: 380px;
overflow-y: auto; overflow: hidden;
overflow-x: hidden; padding: 20px;
.box8-main-item { .box8-main-item {
margin: 0 auto; // margin: 0 auto;
width: 478px; width: 478px;
height: 51px; height: 51px;
margin-bottom: 16px; margin-bottom: 20px;
display: flex; display: flex;
align-items: center; align-items: center;
position: relative; position: relative;
padding: 0 10px; // padding: 0 10px;
cursor: pointer; cursor: pointer;
&:hover { &:hover {
background: var(--color-bg-hover); background: var(--color-bg-hover);
...@@ -3151,6 +3148,7 @@ onUnmounted(() => {}); ...@@ -3151,6 +3148,7 @@ onUnmounted(() => {});
} }
.box9-main { .box9-main {
height: 380px; height: 380px;
padding: 10px 20px;
} }
} }
} }
...@@ -3305,8 +3303,8 @@ onUnmounted(() => {}); ...@@ -3305,8 +3303,8 @@ onUnmounted(() => {});
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
margin-bottom: 16px; margin-bottom: 16px;
overflow: hidden; overflow: hidden;
overflow-y: auto; // overflow-y: auto;
cursor: pointer; // cursor: pointer;
.header { .header {
height: 91px; height: 91px;
width: 1200px; width: 1200px;
...@@ -3314,8 +3312,7 @@ onUnmounted(() => {}); ...@@ -3314,8 +3312,7 @@ onUnmounted(() => {});
border-bottom: 1px solid rgba(234, 236, 238, 1); border-bottom: 1px solid rgba(234, 236, 238, 1);
padding-top: 19px; padding-top: 19px;
.title { .title {
// margin-top: 19px; cursor: pointer;
// padding-top: 19px;
height: 26px; height: 26px;
color: rgba(59, 65, 75, 1); color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
......
...@@ -39,7 +39,7 @@ const getPieChart = (data, colorList) => { ...@@ -39,7 +39,7 @@ const getPieChart = (data, colorList) => {
maxSurfaceAngle: 80 maxSurfaceAngle: 80
}, },
labelLayout: function (params) { labelLayout: function (params) {
const isLeft = params.labelRect.x < 556 / 2; const isLeft = params.labelRect.x < params.viewWidth / 2;
const points = params.labelLinePoints; const points = params.labelLinePoints;
// Update the end point. // Update the end point.
points[2][0] = isLeft points[2][0] = isLeft
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
<div class="layout-container"> <div class="layout-container">
<!-- 导航菜单 --> <!-- 导航菜单 -->
<div class="layout-main"> <div class="layout-main">
<div class="header-main">
<div class="layout-main-header"> <div class="layout-main-header">
<div class="layout-main-header-left-box"> <div class="layout-main-header-left-box">
<div class="left-box-top"> <div class="left-box-top">
...@@ -69,15 +70,17 @@ ...@@ -69,15 +70,17 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<div class="layout-main-center"> <div class="layout-main-center">
<router-view /> <router-view />
</div> </div>
</div> </div>
<div class="layout-report-box" v-if="activeName === '法案原文'"> <div class="layout-report-box" v-if="activeName === '法案原文'">
<div class="report-main">
<div class="report-close" @click="handleSwitchActiveName('分析报告')"> <div class="report-close" @click="handleSwitchActiveName('分析报告')">
<img src="./assets/images/report-close-icon.png" alt="" /> <img src="./assets/images/report-close-icon.png" alt="" />
</div> </div>
<div class="report-main">
<div class="report-header"> <div class="report-header">
<div class="report-header-left"> <div class="report-header-left">
<!-- <div class="text">法案版本:</div> <!-- <div class="text">法案版本:</div>
...@@ -210,18 +213,18 @@ const mainHeaderBtnList = ref([ ...@@ -210,18 +213,18 @@ const mainHeaderBtnList = ref([
name: "深度挖掘", name: "深度挖掘",
path: "/billLayout/deepDig" path: "/billLayout/deepDig"
}, },
{ // {
icon: icon3, // icon: icon3,
activeIcon: icon3Active, // activeIcon: icon3Active,
name: "影响分析", // name: "影响分析",
path: "/billLayout/influence" // path: "/billLayout/influence"
}, // },
{ // {
icon: icon4, // icon: icon4,
activeIcon: icon4Active, // activeIcon: icon4Active,
name: "相关情况", // name: "相关情况",
path: "/billLayout/relevantCircumstance" // path: "/billLayout/relevantCircumstance"
} // }
]); ]);
const activeTitle = ref("法案概况"); const activeTitle = ref("法案概况");
...@@ -247,164 +250,35 @@ onMounted(() => { ...@@ -247,164 +250,35 @@ onMounted(() => {
<style lang="scss" scoped> <style lang="scss" scoped>
.layout-container { .layout-container {
width: 1920px; width: 100%;
height: 1016px; // height: 1016px;
background: rgba(249, 250, 252, 1); background: rgba(249, 250, 252, 1);
position: relative; position: relative;
// margin: 0 auto; // margin: 0 auto;
.layout-header {
width: 1920px;
height: 64px;
// background: #0a121e;
background: #fff;
// border-bottom: 1px solid rgba(0, 0, 0, 0.1);
box-shadow: 0px 0px 8px 0px rgba(0, 0, 0, 0.1);
// margin-bottom: 13px;
display: flex;
position: relative;
z-index: 99;
.layout-header-left {
width: 480px;
display: flex;
.logo-box {
width: 36px;
height: 36px;
margin: 14px;
img {
width: 100%;
height: 100%;
border-radius: 6px;
}
}
.title-box {
height: 64px;
width: 350px;
margin: 0 5px;
color: #eee;
line-height: 64px;
font-size: 20px;
font-weight: bold;
color: rgba(10, 18, 30, 1);
font-family: Microsoft YaHei;
font-size: 22px;
font-weight: 700;
text-align: left;
}
}
.layout-header-center {
width: 700px;
display: flex;
justify-content: space-between;
margin-left: 200px;
.nav-item {
border-radius: 5px;
cursor: pointer;
display: flex;
&:hover {
background: rgba(255, 255, 255, 0.2);
}
.nav-icon-box {
width: 25px;
height: 25px;
margin: 22px 0 20px 5px;
.nav-icon {
width: 20px;
height: 20px;
img {
width: 100%;
height: 100%;
}
}
.nav-icon-active {
width: 20px;
height: 20px;
img {
width: 100%;
height: 100%;
}
}
}
.name-box {
margin: 18px 5px;
height: 30px;
text-align: center;
line-height: 30px;
color: rgba(59, 65, 75, 1);
letter-spacing: 2px;
font-size: 18px;
}
// .nameActive {
// color: #ea9518;
// font-weight: bold;
// }
}
.navItemActive {
// background: #295dab;
// border-bottom: 4px solid #ea9518;
// &:hover {
// background: #295dab;
// border-bottom: 4px solid #ea9518;
// }
}
}
.layout-header-right {
flex: 1;
display: flex;
justify-content: flex-end;
.nav-search {
width: 22px;
height: 22px;
margin: 21px 0;
}
.nav-message {
width: 22px;
height: 22px;
margin: 21px 30px;
}
.nav-usr {
width: 110px;
display: flex;
height: 40px;
margin: 12px 5px 12px 0;
.usr-img {
margin-top: 4px;
height: 32px;
width: 32px;
background: rgba(255, 255, 255, 0.5);
border-radius: 100%;
box-sizing: border-box;
padding: 4px;
// img {
// width: 100%;
// height: 100%;
// }
}
.usr-info {
height: 40px;
line-height: 40px;
text-align: center;
font-size: 14px;
margin-left: 10px;
}
}
}
}
.layout-main { .layout-main {
width: 100%; width: 100%;
height: calc(100% - 64px); height: calc(100% - 64px);
.header-main {
position: sticky;
top: 72px;
z-index: 1000;
width: 100%;
height: 136px;
background-color: #fff;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
}
.layout-main-header { .layout-main-header {
height: 137px; width: 1744px;
height: 136px;
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
margin: 0 auto;
padding-top: 14px;
.layout-main-header-left-box { .layout-main-header-left-box {
width: 900px; width: 900px;
margin-left: 160px; // margin-left: 160px;
margin-top: 13px; // margin-top: 13px;
.left-box-top { .left-box-top {
height: 64px; height: 64px;
display: flex; display: flex;
...@@ -489,8 +363,8 @@ onMounted(() => { ...@@ -489,8 +363,8 @@ onMounted(() => {
} }
.layout-main-header-right-box { .layout-main-header-right-box {
width: 600px; width: 600px;
margin-right: 150px; // margin-right: 150px;
margin-top: 19px; // margin-top: 19px;
.right-box-top { .right-box-top {
.time { .time {
height: 24px; height: 24px;
...@@ -651,7 +525,10 @@ onMounted(() => { ...@@ -651,7 +525,10 @@ onMounted(() => {
} }
} }
.layout-main-center { .layout-main-center {
height: calc(100% - 137px); // height: calc(100% - 137px);
width: 1744px;
margin: 0 auto;
padding-bottom: 100px;
} }
} }
.layout-report-box { .layout-report-box {
...@@ -662,10 +539,20 @@ onMounted(() => { ...@@ -662,10 +539,20 @@ onMounted(() => {
width: 100%; width: 100%;
height: 926px; height: 926px;
background: rgba(248, 249, 250, 1); background: rgba(248, 249, 250, 1);
.report-main {
position: relative;
width: 1744px;
height: 926px;
margin: 0 auto;
background: #fff;
box-sizing: border-box;
padding: 0 69px;
// border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
.report-close { .report-close {
position: absolute; position: absolute;
top: 24px; top: 24px;
right: 178px; right: 24px;
width: 32px; width: 32px;
height: 32px; height: 32px;
cursor: pointer; cursor: pointer;
...@@ -674,13 +561,6 @@ onMounted(() => { ...@@ -674,13 +561,6 @@ onMounted(() => {
height: 100%; height: 100%;
} }
} }
.report-main {
width: 1600px;
height: 926px;
margin: 0 auto;
background: #fff;
box-sizing: border-box;
padding: 0 69px;
.report-header { .report-header {
height: 77px; height: 77px;
border-bottom: 1px solid rgba(240, 242, 244, 1); border-bottom: 1px solid rgba(240, 242, 244, 1);
......
...@@ -65,9 +65,13 @@ const handleClickLeftSiderBtn = (item,index) => { ...@@ -65,9 +65,13 @@ const handleClickLeftSiderBtn = (item,index) => {
.wrap { .wrap {
display: flex; display: flex;
height: 879px; height: 879px;
position: relative;
// background: (243, 243, 244, 1); // background: (243, 243, 244, 1);
.sider { .sider {
width: 160px; width: 160px;
position: absolute;
top: 0;
left: -160px;
.sider-btn { .sider-btn {
margin-top: 20px; margin-top: 20px;
margin-left: 20px; margin-left: 20px;
......
...@@ -777,7 +777,7 @@ onMounted(async () => { ...@@ -777,7 +777,7 @@ onMounted(async () => {
height: 415px; height: 415px;
background: rgb(255, 255, 255); background: rgb(255, 255, 255);
border-radius: 10px; border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1); box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
.box1-main { .box1-main {
height: 359px; height: 359px;
.box1-main-center { .box1-main-center {
...@@ -897,7 +897,7 @@ onMounted(async () => { ...@@ -897,7 +897,7 @@ onMounted(async () => {
height: 415px; height: 415px;
background: rgb(255, 255, 255); background: rgb(255, 255, 255);
border-radius: 10px; border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1); box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
.box2-main { .box2-main {
height: 359px; height: 359px;
.box2-main-center { .box2-main-center {
...@@ -1051,77 +1051,6 @@ onMounted(async () => { ...@@ -1051,77 +1051,6 @@ onMounted(async () => {
} }
} }
} }
// .box2-main-center-content {
// height: 264px;
// display: flex;
// flex-wrap: wrap;
// justify-content: space-between;
// .box2-item {
// width: 402px;
// height: 58px;
// box-sizing: border-box;
// border: 1px solid rgba(243, 243, 244, 1);
// border-radius: 4px;
// margin-bottom: 8px;
// display: flex;
// .box2-item-left {
// width: 36px;
// height: 36px;
// margin-left: 16px;
// margin-top: 11px;
// img {
// width: 100%;
// height: 100%;
// }
// }
// .box2-item-center {
// margin-left: 14px;
// margin-top: 5px;
// width: 220px;
// .box2-item-center-top {
// height: 24px;
// color: rgba(59, 65, 75, 1);
// font-family: Microsoft YaHei;
// font-size: 14px;
// font-weight: 600;
// line-height: 24px;
// }
// .box2-item-center-bottom {
// height: 24px;
// color: rgba(132, 136, 142, 1);
// font-family: Microsoft YaHei;
// font-size: 14px;
// font-weight: 400;
// line-height: 24px;
// }
// }
// .box2-item-right {
// margin-left: 2px;
// .box2-item-right-top {
// height: 24px;
// color: rgba(206, 79, 81, 1);
// font-family: Microsoft YaHei;
// font-size: 14px;
// font-weight: 600;
// line-height: 24px;
// }
// .box2-item-right-bottom {
// height: 24px;
// color: rgba(132, 136, 142, 1);
// font-family: Microsoft YaHei;
// font-size: 14px;
// font-weight: 400;
// line-height: 24px;
// text-align: right;
// }
// }
// }
// }
// .box2-main-center-footer {
// height: 36px;
// display: flex;
// justify-self: center;
// }
} }
.box2-main-footer { .box2-main-footer {
width: 830px; width: 830px;
...@@ -1181,7 +1110,7 @@ onMounted(async () => { ...@@ -1181,7 +1110,7 @@ onMounted(async () => {
width: 100%; width: 100%;
height: 100%; height: 100%;
border-radius: 10px; border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1); box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
.box3-main { .box3-main {
height: 791px; height: 791px;
.box3-main-center { .box3-main-center {
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
</div> </div>
</div> </div>
<div class="main"> <div class="main">
<div class="left"> <div class="left" :style="{ width: (maxLineWidth + 250) + 'px' }">
<div class="top"> <div class="top">
<div class="top-line" :style="{ width: lineWidth }"> <div class="top-line" :style="{ width: lineWidth }">
<div class="top-line1"></div> <div class="top-line1"></div>
...@@ -29,11 +29,12 @@ ...@@ -29,11 +29,12 @@
<div class="item-box-dot"> <div class="item-box-dot">
<img src="./assets/images/top-line-dot.png" alt="" /> <img src="./assets/images/top-line-dot.png" alt="" />
</div> </div>
<div class="item-content">
<div class="item-header"> <div class="item-header">
<div class="item-title" :title="item.actionTitle"> <div class="item-title" :title="item.actionTitle">
{{ item.actionTitle }} <span v-if="item.versionId">({{ item.versionId }})</span> {{ item.actionTitle }} <span v-if="item.versionId">({{ item.versionId }})</span>
</div> </div>
<div class="item-header-icon" @click="handleClickDetail(true, item)"> <div class="item-header-icon" @click="handleClickDetail(true, item, $event)">
<img src="./assets/images/item-header-icon.png" alt="" /> <img src="./assets/images/item-header-icon.png" alt="" />
</div> </div>
</div> </div>
...@@ -43,7 +44,10 @@ ...@@ -43,7 +44,10 @@
<div class="item-main" v-if="item.fynrList && item.fynrList.length"> <div class="item-main" v-if="item.fynrList && item.fynrList.length">
<div class="item-main-item" v-for="(sub, subIndex) in item.fynrList" :key="subIndex"> <div class="item-main-item" v-for="(sub, subIndex) in item.fynrList" :key="subIndex">
<div class="icon"></div> <div class="icon"></div>
<CommonPrompt :content="sub">
<div class="text">{{ sub }}</div> <div class="text">{{ sub }}</div>
</CommonPrompt>
</div>
</div> </div>
</div> </div>
<div class="item-time"> <div class="item-time">
...@@ -72,11 +76,12 @@ ...@@ -72,11 +76,12 @@
<div class="item-box-dot"> <div class="item-box-dot">
<img src="./assets/images/bottom-line-dot.png" alt="" /> <img src="./assets/images/bottom-line-dot.png" alt="" />
</div> </div>
<div class="item-content">
<div class="item-header"> <div class="item-header">
<div class="item-title" :title="item.actionTitle"> <div class="item-title" :title="item.actionTitle">
{{ item.actionTitle }} <span v-if="item.versionId">({{ item.versionId }})</span> {{ item.actionTitle }} <span v-if="item.versionId">({{ item.versionId }})</span>
</div> </div>
<div class="item-header-icon" @click="handleClickDetail(true, item)"> <div class="item-header-icon" @click="handleClickDetail(true, item, $event)">
<img src="./assets/images/item-header-icon.png" alt="" /> <img src="./assets/images/item-header-icon.png" alt="" />
</div> </div>
</div> </div>
...@@ -86,7 +91,10 @@ ...@@ -86,7 +91,10 @@
<div class="item-main" v-if="item.fynrList && item.fynrList.length"> <div class="item-main" v-if="item.fynrList && item.fynrList.length">
<div class="item-main-item" v-for="(sub, subIndex) in item.fynrList" :key="subIndex"> <div class="item-main-item" v-for="(sub, subIndex) in item.fynrList" :key="subIndex">
<div class="icon"></div> <div class="icon"></div>
<CommonPrompt :content="sub">
<div class="text">{{ sub }}</div> <div class="text">{{ sub }}</div>
</CommonPrompt>
</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -111,7 +119,7 @@ ...@@ -111,7 +119,7 @@
<img src="./assets/icons/arrow-right.png" alt="" /> <img src="./assets/icons/arrow-right.png" alt="" />
</div> </div>
</div> --> </div> -->
<div class="dialog-wrapper" v-if="isShowDetailDialog" ref="dialogRef"> <div class="dialog-wrapper" v-if="isShowDetailDialog" ref="dialogRef" :style="dialogPos">
<div class="dialog-box1" @mousedown="handleMouseDown"> <div class="dialog-box1" @mousedown="handleMouseDown">
<div class="icon"> <div class="icon">
<img v-if="currentDetailItem.orgName === '参议院'" src="./assets/images/logo1.png" alt="" /> <img v-if="currentDetailItem.orgName === '参议院'" src="./assets/images/logo1.png" alt="" />
...@@ -446,6 +454,7 @@ ...@@ -446,6 +454,7 @@
<script setup> <script setup>
import { ref, onMounted, computed } from "vue"; import { ref, onMounted, computed } from "vue";
import { getBillDyqkSummary } from "@/api/bill"; import { getBillDyqkSummary } from "@/api/bill";
import CommonPrompt from "../../commonPrompt/index.vue";
// 获取法案流程 // 获取法案流程
...@@ -554,11 +563,34 @@ const curVersionList = ref([ ...@@ -554,11 +563,34 @@ const curVersionList = ref([
const isShowDetailDialog = ref(false); const isShowDetailDialog = ref(false);
const currentDetailItem = ref({}); const currentDetailItem = ref({});
const dialogPos = ref({ left: '0px', top: '0px' });
const handleClickDetail = (isShow, item = {}) => { const handleClickDetail = (isShow, item = {}, event = null) => {
isShowDetailDialog.value = isShow; isShowDetailDialog.value = isShow;
if (isShow) { if (isShow) {
currentDetailItem.value = item; currentDetailItem.value = item;
if (event) {
// 计算弹窗位置,出现在点击位置附近(偏移一些避免挡住鼠标)
const x = event.clientX;
const y = event.clientY;
// 获取包裹容器的偏移量,因为弹窗是 absolute 定位在 wrap 里的
const wrap = document.querySelector('.process-overview-wrap');
const rect = wrap.getBoundingClientRect();
let left = x - rect.left + 20;
let top = y - rect.top - 50;
// 边界处理:防止超出右边界
if (left + 480 > rect.width) {
left = x - rect.left - 500;
}
dialogPos.value = {
left: left + 'px',
top: top + 'px'
};
}
} }
}; };
...@@ -605,7 +637,8 @@ onMounted(() => { ...@@ -605,7 +637,8 @@ onMounted(() => {
.process-overview-wrap { .process-overview-wrap {
width: 1744px; width: 1744px;
height: 848px; height: 848px;
border-radius: 4px; border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
margin-top: 16px; margin-top: 16px;
position: relative; position: relative;
...@@ -650,15 +683,35 @@ onMounted(() => { ...@@ -650,15 +683,35 @@ onMounted(() => {
} }
.main { .main {
margin-left: 59px; margin-left: 59px;
height: 680px; height: 740px;
padding: 3px 10px; padding: 3px 10px 60px 10px;
overflow: hidden; overflow-x: auto;
overflow-y: hidden;
/* 自定义滚动条样式,模拟进度条 */
&::-webkit-scrollbar {
height: 8px;
}
&::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 4px;
}
&::-webkit-scrollbar-thumb {
background: rgba(20, 89, 187, 0.2);
border-radius: 4px;
&:hover {
background: rgba(20, 89, 187, 0.4);
}
}
.left { .left {
height: 680px; height: 680px;
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
/* 确保内容区域宽度足够展示所有节点和右侧汇合点 */
min-width: fit-content;
padding-right: 150px;
.top { .top {
height: 260px; height: 260px;
...@@ -751,11 +804,13 @@ onMounted(() => { ...@@ -751,11 +804,13 @@ onMounted(() => {
height: 100%; height: 100%;
} }
} }
.item-content {
border-left: 1px solid rgb(20, 89, 187);
}
.item-header { .item-header {
display: flex; display: flex;
align-items: center; align-items: center;
height: 30px; height: 30px;
border-left: 1px solid rgb(20, 89, 187);
padding: 0 10px; padding: 0 10px;
margin-bottom: 8px; margin-bottom: 8px;
.item-title { .item-title {
...@@ -788,7 +843,6 @@ onMounted(() => { ...@@ -788,7 +843,6 @@ onMounted(() => {
} }
} }
.item-info { .item-info {
border-left: 1px solid rgb(20, 89, 187);
padding: 0 10px; padding: 0 10px;
color: rgb(59, 65, 75); color: rgb(59, 65, 75);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
...@@ -798,7 +852,6 @@ onMounted(() => { ...@@ -798,7 +852,6 @@ onMounted(() => {
margin-bottom: 4px; margin-bottom: 4px;
} }
.item-main { .item-main {
border-left: 1px solid rgb(20, 89, 187);
padding: 5px 10px; padding: 5px 10px;
.item-main-item { .item-main-item {
display: flex; display: flex;
...@@ -819,6 +872,16 @@ onMounted(() => { ...@@ -819,6 +872,16 @@ onMounted(() => {
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 400;
line-height: 24px; line-height: 24px;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
height: 48px;
}
:deep(.text-ellipsis) {
white-space: normal !important;
} }
} }
} }
...@@ -962,11 +1025,13 @@ onMounted(() => { ...@@ -962,11 +1025,13 @@ onMounted(() => {
height: 100%; height: 100%;
} }
} }
.item-content {
border-left: 1px solid rgba(255, 172, 77, 1);
}
.item-header { .item-header {
display: flex; display: flex;
align-items: center; align-items: center;
height: 30px; height: 30px;
border-left: 1px solid rgba(255, 172, 77, 1);
padding: 5px 10px; padding: 5px 10px;
margin-top: 8px; margin-top: 8px;
.item-title { .item-title {
...@@ -999,7 +1064,6 @@ onMounted(() => { ...@@ -999,7 +1064,6 @@ onMounted(() => {
} }
} }
.item-info { .item-info {
border-left: 1px solid rgba(255, 172, 77, 1);
padding: 0 10px; padding: 0 10px;
color: rgb(59, 65, 75); color: rgb(59, 65, 75);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
...@@ -1009,7 +1073,6 @@ onMounted(() => { ...@@ -1009,7 +1073,6 @@ onMounted(() => {
margin-top: 8px; margin-top: 8px;
} }
.item-main { .item-main {
border-left: 1px solid rgba(255, 172, 77, 1);
padding: 5px 10px; padding: 5px 10px;
.item-main-item { .item-main-item {
display: flex; display: flex;
...@@ -1030,6 +1093,15 @@ onMounted(() => { ...@@ -1030,6 +1093,15 @@ onMounted(() => {
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 400;
line-height: 24px; line-height: 24px;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
height: 48px;
}
:deep(.text-ellipsis) {
white-space: normal !important;
} }
} }
} }
...@@ -1159,8 +1231,6 @@ onMounted(() => { ...@@ -1159,8 +1231,6 @@ onMounted(() => {
} }
.dialog-wrapper { .dialog-wrapper {
position: absolute; position: absolute;
top: 56px;
right: 17px;
width: 480px; width: 480px;
// height: 692px; // 去掉固定高度,由内容撑开 // height: 692px; // 去掉固定高度,由内容撑开
padding-bottom: 20px; padding-bottom: 20px;
......
<template> <template>
<div class="home-container"> <div class="home-container">
<!-- <div class="home-top">
<div class="home-top-left-box">
<div class="left-box-top">
<div class="icon">
<img src="./assets/images/USA-logo.png" alt="" />
</div>
<div class="info">
<div class="info-box1">{{ "H.R.1(119th)-大而美法案" }}</div>
<div class="info-box2">
{{ "第119届美国国会众议院第1号法案 One Big Beautiful Bill Act" }}
</div>
</div>
</div>
<div class="left-box-bottom">
<div
class="left-box-bottom-item"
style="border-bottom: 2px solid rgba(22, 119, 255, 1)"
>
<div class="icon">
<img src="./assets/icons/icon1.png" alt="" />
</div>
<div class="name" style="color: rgba(22, 119, 255, 1)">
法案概况
</div>
</div>
<div class="left-box-bottom-item">
<div class="icon">
<img src="./assets/icons/icon2.png" alt="" />
</div>
<div class="name">深度挖掘</div>
</div>
<div class="left-box-bottom-item">
<div class="icon">
<img src="./assets/icons/icon3.png" alt="" />
</div>
<div class="name">影响分析</div>
</div>
<div class="left-box-bottom-item">
<div class="icon">
<img src="./assets/icons/icon4.png" alt="" />
</div>
<div class="name">相关情况</div>
</div>
</div>
</div>
<div class="home-top-right-box">
<div class="right-box-top">
<div class="time">{{ "2025年7月" }}</div>
<div class="name">{{ "乔迪·阿灵顿(Jodey Arrington)​​ " }}</div>
</div>
<div class="right-box-bottom">
<el-button type="plain" size="large" icon="Search"
>法案原文</el-button
>
<el-button type="primary" size="large" icon="EditPen"
>分析报告</el-button
>
</div>
</div>
</div> -->
<div class="home-center"> <div class="home-center">
<div class="home-sider"> <div class="home-sider">
<div <div
...@@ -226,8 +166,12 @@ onMounted(() => {}); ...@@ -226,8 +166,12 @@ onMounted(() => {});
.home-center { .home-center {
display: flex; display: flex;
height: 879px; height: 879px;
position: relative;
.home-sider { .home-sider {
width: 160px; width: 160px;
position: absolute;
top: 0;
left: -160px;
.sider-btn { .sider-btn {
margin-top: 20px; margin-top: 20px;
margin-left: 20px; margin-left: 20px;
......
...@@ -58,9 +58,13 @@ const handleClickLeftSiderBtn = (item,index) => { ...@@ -58,9 +58,13 @@ const handleClickLeftSiderBtn = (item,index) => {
.influence-wrap { .influence-wrap {
display: flex; display: flex;
height: 879px; height: 879px;
position: relative;
// background: (243, 243, 244, 1); // background: (243, 243, 244, 1);
.sider { .sider {
width: 160px; width: 160px;
position: absolute;
top: 0;
left: -160px;
.sider-btn { .sider-btn {
margin-top: 20px; margin-top: 20px;
margin-left: 10px; margin-left: 10px;
......
...@@ -811,7 +811,8 @@ onMounted(async () => { ...@@ -811,7 +811,8 @@ onMounted(async () => {
width: 480px; width: 480px;
height: 848px; height: 848px;
background: rgba(255, 255, 255); background: rgba(255, 255, 255);
border-radius: 4px; border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
.left-top { .left-top {
margin: 0 auto; margin: 0 auto;
width: 446px; width: 446px;
...@@ -949,7 +950,8 @@ onMounted(async () => { ...@@ -949,7 +950,8 @@ onMounted(async () => {
width: 1247px; width: 1247px;
height: 847px; height: 847px;
background: rgba(255, 255, 255); background: rgba(255, 255, 255);
border-radius: 4px; border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
position: relative; position: relative;
.graph-dialog { .graph-dialog {
width: 740px; width: 740px;
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
</div> </div>
<div class="box1-main"> <div class="box1-main">
<div class="box1-left"> <div class="box1-left">
<img src="./assets/images/image1.png" alt="" /> <img :src=" basicInfo.imageUrl || defaultBill" alt="" />
</div> </div>
<div class="box1-right"> <div class="box1-right">
<div class="box1-right-item"> <div class="box1-right-item">
...@@ -31,9 +31,6 @@ ...@@ -31,9 +31,6 @@
<div class="box1-right-item"> <div class="box1-right-item">
<div class="item-left">相关领域:</div> <div class="item-left">相关领域:</div>
<div class="item-right1"> <div class="item-right1">
<!-- <div class="right1-item">跨境电商</div>
<div class="right1-item">新能源产业</div>
<div class="right1-item">半导体产业</div> -->
<div class="right1-item" v-for="item in basicInfo.hylyList" :key="item">{{ item }}</div> <div class="right1-item" v-for="item in basicInfo.hylyList" :key="item">{{ item }}</div>
</div> </div>
</div> </div>
...@@ -355,6 +352,7 @@ import STimeline from "./STimeline.vue"; ...@@ -355,6 +352,7 @@ import STimeline from "./STimeline.vue";
import { getBillInfo, getBillPerson, getBillEvent, getBillDyqk } from "@/api/bill"; import { getBillInfo, getBillPerson, getBillEvent, getBillDyqk } from "@/api/bill";
import defaultAvatar from "../assets/images/default-icon1.png"; import defaultAvatar from "../assets/images/default-icon1.png";
import defaultNew from "../assets/images/default-icon-news.png"; import defaultNew from "../assets/images/default-icon-news.png";
import defaultBill from "./assets/images/image1.png"
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
...@@ -376,13 +374,6 @@ const handleClcikDialogBoxBtn = index => { ...@@ -376,13 +374,6 @@ const handleClcikDialogBoxBtn = index => {
dialogBoxBtnActive.value = index; dialogBoxBtnActive.value = index;
}; };
const handleChangeFaId = val => {
console.log("val", val);
handleGetBillPerson(val);
};
const timelineData = ref([]); const timelineData = ref([]);
const isShowDialog = ref(false); const isShowDialog = ref(false);
...@@ -520,7 +511,7 @@ onMounted(() => { ...@@ -520,7 +511,7 @@ onMounted(() => {
height: 415px; height: 415px;
background: #fff; background: #fff;
border-radius: 10px; border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1); box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
.box1-main { .box1-main {
display: flex; display: flex;
height: 394px; height: 394px;
...@@ -528,6 +519,10 @@ onMounted(() => { ...@@ -528,6 +519,10 @@ onMounted(() => {
margin-left: 23px; margin-left: 23px;
width: 247px; width: 247px;
height: 350px; height: 350px;
img {
width: 100%;
height: 100%;
}
} }
.box1-right { .box1-right {
margin-left: 31px; margin-left: 31px;
...@@ -541,49 +536,38 @@ onMounted(() => { ...@@ -541,49 +536,38 @@ onMounted(() => {
width: 100px; width: 100px;
height: 14px; height: 14px;
color: rgba(59, 65, 75, 1); color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei; font-family: "Microsoft YaHei";
font-size: 14px; font-size: 16px;
font-weight: 600; font-weight: 700;
line-height: 14px; line-height: 14px;
text-align: left; text-align: left;
} }
.item-right { .item-right {
height: 14px; height: 14px;
color: var(--color-main-active); color: var(--color-main-active);
font-family: Microsoft YaHei; font-family: "Microsoft YaHei";
font-size: 14px; font-size: 16px;
font-weight: 600; font-weight: 700;
line-height: 14px; line-height: 14px;
letter-spacing: 0px; letter-spacing: 0px;
text-align: left; text-align: left;
} }
.item-right1 { .item-right1 {
display: flex; display: flex;
flex-wrap: wrap;
align-items: center; align-items: center;
width: 700px; width: 700px;
height: 40px; min-height: 40px;
overflow-x: auto;
overflow-y: hidden;
&::-webkit-scrollbar {
height: 4px;
}
&::-webkit-scrollbar-thumb {
border-radius: 4px;
background: #e1e1e1;
}
&::-webkit-scrollbar-track {
background: transparent;
}
.right1-item { .right1-item {
flex-shrink: 0;
margin-right: 10px; margin-right: 10px;
margin-bottom: 8px;
padding: 1px 8px; padding: 1px 8px;
box-sizing: border-box; box-sizing: border-box;
border: 1px solid rgba(186, 224, 255, 1); border: 1px solid rgba(186, 224, 255, 1);
border-radius: 4px; border-radius: 4px;
background: rgba(230, 244, 255, 1); background: rgba(230, 244, 255, 1);
color: rgba(22, 119, 255, 1); color: rgba(22, 119, 255, 1);
font-family: Microsoft YaHei; font-family: "Microsoft YaHei";
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;
line-height: 20px; line-height: 20px;
...@@ -593,8 +577,8 @@ onMounted(() => { ...@@ -593,8 +577,8 @@ onMounted(() => {
.right2-item { .right2-item {
height: 14px; height: 14px;
color: rgba(95, 101, 108, 1); color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei; font-family: "Microsoft YaHei";
font-size: 14px; font-size: 16px;
font-weight: 400; font-weight: 400;
line-height: 14px; line-height: 14px;
text-align: left; text-align: left;
...@@ -604,8 +588,8 @@ onMounted(() => { ...@@ -604,8 +588,8 @@ onMounted(() => {
.item-right3 { .item-right3 {
height: 14px; height: 14px;
color: rgba(95, 101, 108, 1); color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei; font-family: "Microsoft YaHei";
font-size: 14px; font-size: 16px;
font-weight: 400; font-weight: 400;
line-height: 14px; line-height: 14px;
text-align: left; text-align: left;
...@@ -618,7 +602,7 @@ onMounted(() => { ...@@ -618,7 +602,7 @@ onMounted(() => {
.step { .step {
height: 28px; height: 28px;
line-height: 26px; line-height: 26px;
font-size: 14px; font-size: 16px;
text-align: center; text-align: center;
position: relative; position: relative;
background: transparent; background: transparent;
...@@ -702,7 +686,7 @@ onMounted(() => { ...@@ -702,7 +686,7 @@ onMounted(() => {
height: 415px; height: 415px;
background: #fff; background: #fff;
border-radius: 10px; border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1); box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
position: relative; position: relative;
.box2-main { .box2-main {
margin-top: 10px; margin-top: 10px;
...@@ -841,7 +825,7 @@ onMounted(() => { ...@@ -841,7 +825,7 @@ onMounted(() => {
height: 845px; height: 845px;
background: #fff; background: #fff;
border-radius: 10px; border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1); box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
.introduction-wrap-right-main { .introduction-wrap-right-main {
.right-main-box1 { .right-main-box1 {
// height: 218px; 将选择框去掉后高度变化 // height: 218px; 将选择框去掉后高度变化
......
...@@ -596,7 +596,7 @@ onMounted(() => { ...@@ -596,7 +596,7 @@ onMounted(() => {
width: 100%; width: 100%;
height: 100%; height: 100%;
display: flex; display: flex;
padding: 16px 160px; padding: 16px 0px;
justify-content: space-between; justify-content: space-between;
.box-header { .box-header {
height: 45px; height: 45px;
...@@ -680,10 +680,10 @@ onMounted(() => { ...@@ -680,10 +680,10 @@ onMounted(() => {
} }
} }
.left { .left {
width: 1068px; width: 1212px;
height: 847px; height: 847px;
border-radius: 4px; border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2); box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
.box1 { .box1 {
position: relative; position: relative;
...@@ -721,7 +721,7 @@ onMounted(() => { ...@@ -721,7 +721,7 @@ onMounted(() => {
} }
} }
.box1-main { .box1-main {
width: 1068px; width: 1212px;
height: 730px; height: 730px;
// background: orange; // background: orange;
} }
...@@ -773,8 +773,8 @@ onMounted(() => { ...@@ -773,8 +773,8 @@ onMounted(() => {
.right { .right {
width: 520px; width: 520px;
height: 848px; height: 848px;
border-radius: 4px; border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2); box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
.box2 { .box2 {
.box2-main { .box2-main {
......
...@@ -103,7 +103,7 @@ ...@@ -103,7 +103,7 @@
<div class="right-box1"> <div class="right-box1">
<div class="box-header"> <div class="box-header">
<div class="box-header-left"></div> <div class="box-header-left"></div>
<div class="box-header-title">限制方式</div> <div class="box-header-title">限制手段</div>
<div class="header-right"> <div class="header-right">
<div class="icon"> <div class="icon">
<img src="@/assets/icons/box-header-icon1.png" alt="" /> <img src="@/assets/icons/box-header-icon1.png" alt="" />
...@@ -130,7 +130,7 @@ ...@@ -130,7 +130,7 @@
<div class="right-box2"> <div class="right-box2">
<div class="box-header"> <div class="box-header">
<div class="box-header-left"></div> <div class="box-header-left"></div>
<div class="box-header-title">涉及行业</div> <div class="box-header-title">涉及领域</div>
<div class="header-right"> <div class="header-right">
<div class="icon"> <div class="icon">
<img src="@/assets/icons/box-header-icon1.png" alt="" /> <img src="@/assets/icons/box-header-icon1.png" alt="" />
...@@ -430,7 +430,8 @@ onMounted(async () => { ...@@ -430,7 +430,8 @@ onMounted(async () => {
margin-top: 16px; margin-top: 16px;
width: 1150px; width: 1150px;
height: 845px; height: 845px;
border-radius: 4px; border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
.left-top { .left-top {
height: 45px; height: 45px;
...@@ -599,7 +600,8 @@ onMounted(async () => { ...@@ -599,7 +600,8 @@ onMounted(async () => {
.right-box1 { .right-box1 {
width: 576px; width: 576px;
height: 415px; height: 415px;
border-radius: 4px; border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
.right-box1-main { .right-box1-main {
width: 576px; width: 576px;
...@@ -655,7 +657,8 @@ onMounted(async () => { ...@@ -655,7 +657,8 @@ onMounted(async () => {
margin-top: 15px; margin-top: 15px;
width: 576px; width: 576px;
height: 415px; height: 415px;
border-radius: 4px; border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1); background: rgba(255, 255, 255, 1);
.right-box2-main { .right-box2-main {
width: 576px; width: 576px;
......
<template>
<el-tooltip
effect="dark"
:content="content"
popper-class="common-prompt-popper"
placement="top"
:show-after="500"
>
<div class="text-ellipsis">
<slot>{{ content }}</slot>
</div>
</el-tooltip>
</template>
<script setup>
defineProps({
content: {
type: String,
default: ""
}
});
</script>
<style scoped>
.text-ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
cursor: pointer;
}
</style>
<style>
.common-prompt-popper.el-popper {
padding: 8px 16px !important;
border-radius: 10px !important;
background-color: rgb(59, 65, 75) !important;
font-size: 16px !important;
font-weight: 400 !important;
font-family: "Microsoft YaHei" !important;
line-height: 30px !important;
color: #fff !important;
border: none !important;
}
.common-prompt-popper.el-popper .el-popper__arrow::before {
background-color: rgb(59, 65, 75) !important;
border-color: rgb(59, 65, 75) !important;
}
</style>
...@@ -7,12 +7,20 @@ ...@@ -7,12 +7,20 @@
<div class="more" @click="handleToMoreNews">更多 +</div> <div class="more" @click="handleToMoreNews">更多 +</div>
</div> </div>
<div class="left-main"> <div class="left-main">
<div v-for="item in leftList" :key="item.id" class="main-item"> <div v-for="item in leftList.slice(0, 5)" :key="item.id" class="main-item" @click="handleToNewsDetail(item)">
<img :src="item.image" alt=""> <img :src="item.image || defaultNews" alt="" @error="e => e.target.src = defaultNews">
<div class="item-content"> <div class="item-content">
<div class="title">{{item.title}}</div> <div class="title">
<div class="content">{{item.content}}</div> <CommonPrompt :content="item.title">
<div class="time">{{item.time}}</div> {{ item.title }}
</CommonPrompt>
</div>
<div class="content">
<CommonPrompt :content="item.content">
{{ item.content }}
</CommonPrompt>
</div>
<div class="time">{{ item.time }}</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -23,28 +31,12 @@ ...@@ -23,28 +31,12 @@
<div class="tit">社交媒体</div> <div class="tit">社交媒体</div>
</div> </div>
<div class="right-main"> <div class="right-main">
<div class="trump"> <div v-for="(item, index) in rightList.slice(0, 3)" :key="item.id" class="social-item" @click="handleToSocialDetail(item)">
<img src="./assets/title01.png" alt=""> <img :src="item.image || defaultAvatar" alt="" @error="e => e.target.src = defaultAvatar">
<div class="trump-main"> <div class="social-item-main" :style="{ backgroundImage: `url(${socialConfig[index].bg})` }">
<div class="cl1">{{ rightList[0].name }}</div> <div class="cl1">{{ item.name }}</div>
<div class="cl2">{{ rightList[0].content }}</div> <div class="cl2">{{ item.content }}</div>
<div class="cl3">{{ rightList[0].time }}</div> <div class="cl3">{{ item.time }}</div>
</div>
</div>
<div class="mask">
<img src="./assets/title02.png" alt="">
<div class="mask-main">
<div class="cl1">{{ rightList[1].name }}</div>
<div class="cl2">{{ rightList[1].content }}</div>
<div class="cl3">{{ rightList[1].time }}</div>
</div>
</div>
<div class="malaby">
<img src="./assets/title03.png" alt="">
<div class="malaby-main">
<div class="cl1">{{ rightList[2].name }}</div>
<div class="cl2">{{ rightList[2].content }}</div>
<div class="cl3">{{ rightList[2].time }}</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -53,86 +45,108 @@ ...@@ -53,86 +45,108 @@
</template> </template>
<script setup> <script setup>
import { ref } from "vue"; import { ref, onMounted } from "vue";
import router from '@/router' import router from '@/router'
import image01 from './assets/image01.png' import { getCoopRestrictionNews, getCoopRestrictionSocial } from '@/api/coopRestriction/coopRestriction'
import image02 from './assets/image02.png' import CommonPrompt from "../../commonPrompt/index.vue";
import image03 from './assets/image03.png'
import image04 from './assets/image04.png'
import image05 from './assets/image05.png'
import defaultNews from "../../assets/images/default-icon-news.png"
import defaultAvatar from "../../assets/images/default-icon1.png"
import title01 from './assets/title01.png' import title01 from './assets/title01.png'
import title02 from './assets/title02.png' import title02 from './assets/title02.png'
import title03 from './assets/title03.png' import title03 from './assets/title03.png'
import title01bg from './assets/title01bg.png'
import title02bg from './assets/title02bg.png'
import title03bg from './assets/title03bg.png'
// 合作限制-查询社交媒体接口
const getCoopRestrictionSocialData = async () => {
try {
const res = await getCoopRestrictionSocial({ moduleId: "0106" });
if (res && res.code === 200) {
rightList.value = (res.data || []).map(item => {
const date = new Date(item.time);
const y = date.getFullYear();
const m = (date.getMonth() + 1).toString().padStart(2, '0');
const d = date.getDate().toString().padStart(2, '0');
const hh = date.getHours().toString().padStart(2, '0');
const mm = date.getMinutes().toString().padStart(2, '0');
const formattedTime = `${y}-${m}-${d} ${hh}:${mm} · 发布于${item.orgName}`;
return {
id: item.personId,
name: item.personName,
content: item.remarks,
time: formattedTime,
image: item.personImage
}
});
}
} catch (error) {
console.error("获取合作限制社交媒体数据失败:", error);
}
};
// 合作限制-查询新闻资讯接口
const getCoopRestrictionNewsData = async () => {
try {
const res = await getCoopRestrictionNews({ moduleId: "0106" });
if (res && res.code === 200) {
leftList.value = (res.data || []).map(item => ({
id: item.newsId,
title: item.newsTitle,
content: item.newsContent,
time: `${item.newsDate}${item.newsOrg ? ' · ' + item.newsOrg : ''}`,
image: item.newsImage
}));
}
} catch (error) {
console.error("获取合作限制新闻资讯数据失败:", error);
}
};
const leftList = ref([])
const leftList = ref([ const rightList = ref([])
{
id:1,
title:'美国智库激辩人工智能监管路径',
content:'各方就AI监管模式展开讨论。有观点认为碎片化州级监管比全面联邦法规更灵活,也有分析...',
time:'11-4 · 华盛顿邮报',
image:image01
},
{
id:2,
title:'布鲁金斯学会称美国低估中国在“印太”战略',
content:'分析认为,当美国注意力被其他地区分散时,中国通过外交、发展和防务多管齐下,系统性...',
time:'11-4 · 纽约时报',
image:image02
},
{
id:3,
title:'五角大楼指令引发智库与国防部“脱钩”震荡',
content:'美国国防部长下令全面暂停部内人员参与所有智库活动,标志着传统的“旋转门”关系发生...',
time:'11-3 · 洛杉矶时报',
image:image03
},
{
id:4,
title:'卡内基基金会警告冲突中AI宣传战的风险',
content:'分析指出,在伊朗与以色列的冲突中,人工智能生成的虚假信息泛滥,深度破坏了信息生态...',
time:'11-3 · 今日美国',
image:image04
},
{
id:5,
title:'CSIS建议美国建立跨机构AI基准测试体系',
content:'指出美国《人工智能行动计划》忽视了基准测试这一关键环节,建议由国家标准与技术研究...',
time:'11-2 · ​福克斯新闻网',
image:image05
}
])
const rightList = ref([ const socialConfig = [
{ { icon: title01, bg: title01bg },
id:1, { icon: title02, bg: title02bg },
name:'唐纳德·特朗普', { icon: title03, bg: title03bg }
content:'埃隆·马斯克在强力支持我竞选总统之前,早就知道我强烈反对‘电动汽车强制令’。这太荒谬了,这一直是我竞选活动的主要部分。电动汽车没问题,但不应该强迫每个人都拥有一辆。埃隆获得的补贴可能远远超过历史上任何一个人。如果没有补贴,埃隆可能不得不关门大吉,回到南非老家。', ]
time:'15:23 · 发布于真实社交',
title:title01
},
{
id:2,
name:'埃隆·马斯克',
content:'如果这个疯狂的支出法案获得通过,‘美国党’将在第二天成立。',
time:'14:49 · 发布于X',
title:title02
},
{
id:3,
name:'塞巴斯蒂安·马拉比',
content:'提出特朗普政府的AI政策强调技术开放与快速应用,但可能以牺牲安全防范为代价,开启了“潘多拉魔盒”。',
time:'11:05 · 发布于X',
title:title03
}
])
// 查看更多新闻资讯 // 查看更多新闻资讯
const handleToMoreNews = () => { const handleToMoreNews = () => {
const route = router.resolve("/newsBrief"); const route = router.resolve("/newsBrief");
window.open(route.href, "_blank"); window.open(route.href, "_blank");
}; };
// 查看新闻资讯详情
const handleToNewsDetail = (item) => {
const route = router.resolve({
path: "/newsAnalysis",
query: {
newsId: item.id
}
});
window.open(route.href, "_blank");
}
// 查看社交媒体详情
const handleToSocialDetail = (item) => {
const route = router.resolve({
path: "/characterPage",
query: {
personId: item.id
}
});
window.open(route.href, "_blank");
}
onMounted(() => {
// 合作限制-查询新闻资讯数据
getCoopRestrictionNewsData()
// 合作限制-查询社交媒体数据
getCoopRestrictionSocialData()
})
</script> </script>
...@@ -201,6 +215,9 @@ const handleToMoreNews = () => { ...@@ -201,6 +215,9 @@ const handleToMoreNews = () => {
display: flex; display: flex;
border-bottom: 1px solid rgba(240, 242, 244, 1); border-bottom: 1px solid rgba(240, 242, 244, 1);
margin-bottom: 14px; margin-bottom: 14px;
&:hover {
background-color: #f9f9f9;
}
img { img {
width: 72px; width: 72px;
height: 48px; height: 48px;
...@@ -212,20 +229,28 @@ const handleToMoreNews = () => { ...@@ -212,20 +229,28 @@ const handleToMoreNews = () => {
height: 50px; height: 50px;
position: relative; position: relative;
.title { .title {
width: 480px;
font-size: 16px; font-size: 16px;
font-weight: 700; font-weight: 700;
font-family: 'Microsoft YaHei'; font-family: 'Microsoft YaHei';
line-height: 24px; line-height: 24px;
color: rgb(59, 65, 75); color: rgb(59, 65, 75);
cursor: pointer; cursor: pointer;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
} }
.content { .content {
width: 100%;
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 400;
font-family: 'Microsoft YaHei'; font-family: 'Microsoft YaHei';
line-height: 24px; line-height: 24px;
color: rgb(59, 65, 75); color: rgb(59, 65, 75);
cursor: pointer; cursor: pointer;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
} }
.time { .time {
position: absolute; position: absolute;
...@@ -290,110 +315,23 @@ const handleToMoreNews = () => { ...@@ -290,110 +315,23 @@ const handleToMoreNews = () => {
width: 792px; width: 792px;
height: 402px; height: 402px;
padding: 23px 30px 25px 21px; padding: 23px 30px 25px 21px;
.trump { overflow: auto;
width: 740px; .social-item {
height: 148px;
margin-bottom: 16px;
display: flex;
img {
width: 36px;
height: 36px;
margin-right: 8.5px;
}
.trump-main {
width: 695.6px;
height: 148px;
background-image: url('./assets/title01bg.png');
padding: 11px 14px 12px 22.5px;
background-size: cover;
position: relative;
.cl1 {
font-size: 16px;
font-weight: 700;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(59, 65, 75);
margin-bottom: 5px;
}
.cl2 {
font-size: 16px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(59, 65, 75);
}
.cl3 {
position: absolute;
top: 11px;
right: 14px;
font-size: 16px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 30px;
color: rgb(95, 101, 108);
}
}
}
.mask {
width: 740px;
height: 76px;
margin-bottom: 16px;
display: flex;
img {
width: 36px;
height: 36px;
margin-right: 8.5px;
}
.mask-main {
width: 695.6px;
height: 76px;
background-image: url('./assets/title02bg.png');
padding: 11px 14px 12px 22.5px;
background-size: cover;
position: relative;
.cl1 {
font-size: 16px;
font-weight: 700;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(59, 65, 75);
margin-bottom: 5px;
}
.cl2 {
font-size: 16px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 24px;
color: rgb(59, 65, 75);
}
.cl3 {
position: absolute;
top: 11px;
right: 14px;
font-size: 16px;
font-weight: 400;
font-family: 'Microsoft YaHei';
line-height: 30px;
color: rgb(95, 101, 108);
}
}
}
.malaby {
width: 740px; width: 740px;
height: 98px;
margin-bottom: 16px; margin-bottom: 16px;
display: flex; display: flex;
cursor: pointer;
img { img {
width: 36px; width: 36px;
height: 36px; height: 36px;
margin-right: 8.5px; margin-right: 8.5px;
border-radius: 50%;
} }
.malaby-main { .social-item-main {
width: 695.6px; width: 695.6px;
height: 98px;
background-image: url('./assets/title03bg.png');
padding: 11px 14px 12px 22.5px; padding: 11px 14px 12px 22.5px;
background-size: cover; background-size: 100% 100%;
background-repeat: no-repeat;
position: relative; position: relative;
.cl1 { .cl1 {
font-size: 16px; font-size: 16px;
......
...@@ -99,14 +99,23 @@ ...@@ -99,14 +99,23 @@
</div> </div>
</div> </div>
<div style="margin: 6px 34px 0 23px"> <div style="margin: 6px 34px 0 23px">
<div v-for="item in riskSignals" :key="item.id" class="right-main" @click="handleToRiskDetail"> <div v-for="item in riskSignals" :key="item.id" class="right-main" @click="handleToRiskDetail(item)">
<div class="main-left" :class="{ cl4: item.title === '特别重大', cl5: item.title === '重大风险' }"> <div
class="main-left"
:class="{ cl4: item.title === '特别重大', cl5: item.title === '重大风险', cl6: item.title === '一般风险' }"
>
{{ item.title }} {{ item.title }}
</div> </div>
<div class="main-center">{{ item.content }}</div> <div class="item-right">
<div class="main-center">
<CommonPrompt :content="item.content">
{{ item.content }}
</CommonPrompt>
</div>
<div class="main-right">{{ item.time }}</div> <div class="main-right">{{ item.time }}</div>
</div> </div>
</div> </div>
</div>
<div class="right-mainbtn" @click="handleToMoreRiskSignal"> <div class="right-mainbtn" @click="handleToMoreRiskSignal">
<img src="./assets/btn.png" alt="" /> <img src="./assets/btn.png" alt="" />
查看更多 查看更多
...@@ -118,8 +127,27 @@ ...@@ -118,8 +127,27 @@
<script setup> <script setup>
import { ref, onMounted, computed } from "vue"; import { ref, onMounted, computed } from "vue";
import router from "@/router"; import router from "@/router";
import { getCoopRestrictionTrends } from "@/api/coopRestriction/coopRestriction.js"; import { getCoopRestrictionTrends, getCoopRestrictionSignals } from "@/api/coopRestriction/coopRestriction.js";
import defaultImg from "./assets/usImg.png"; import defaultImg from "./assets/usImg.png";
import CommonPrompt from "../../commonPrompt/index.vue";
// 合作限制-查询风险信号数据
const getCoopRestrictionSignalsData = async () => {
try {
const res = await getCoopRestrictionSignals({ moduleId: "0106" });
if (res && res.code === 200) {
riskSignals.value = (res.data || []).map(item => ({
id: item.signalId,
title: item.signalLevel,
content: item.signalTitle,
time: item.signalTime
}));
}
} catch (error) {
console.error("获取合作限制风险信号数据失败:", error);
}
};
const coopRestrictionTrends = ref([]); const coopRestrictionTrends = ref([]);
const carouselRef = ref(null); const carouselRef = ref(null);
...@@ -161,32 +189,7 @@ const mainTrend = computed(() => { ...@@ -161,32 +189,7 @@ const mainTrend = computed(() => {
}); });
// 右侧风险信号列表 // 右侧风险信号列表
const riskSignals = ref([ const riskSignals = ref([]);
{
id: 1,
title: "特别重大",
content: "保护美国资金与专业知识免受敌对研究利用法案",
time: "一天前"
},
{
id: 2,
title: "特别重大",
content: "美国国土安全部终止哈佛大学SEVP认证",
time: "一天前"
},
{
id: 3,
title: "重大风险",
content: "众议院“美中战略竞争特别委员会”向国会提...",
time: "一天前"
},
{
id: 4,
title: "重大风险",
content: '2026财年拨款法案要求重启"中国行动计划"',
time: "一天前"
}
]);
// 点击查看详情 // 点击查看详情
const handleClickToDetail = (item) => { const handleClickToDetail = (item) => {
...@@ -201,8 +204,11 @@ const handleClickToDetail = (item) => { ...@@ -201,8 +204,11 @@ const handleClickToDetail = (item) => {
}; };
// 点击风险信号详情 // 点击风险信号详情
const handleToRiskDetail = () => { const handleToRiskDetail = (item) => {
const curRoute = router.resolve("/cooperationRestrictions/detail"); const curRoute = router.resolve({
path: "/cooperationRestrictions/detail",
query: { id: item.id },
});
window.open(curRoute.href, "_blank"); window.open(curRoute.href, "_blank");
}; };
...@@ -215,6 +221,8 @@ const handleToMoreRiskSignal = () => { ...@@ -215,6 +221,8 @@ const handleToMoreRiskSignal = () => {
onMounted(() => { onMounted(() => {
// 合作限制-最新动态数据-获取数据 // 合作限制-最新动态数据-获取数据
getCoopRestrictionTrendsData(); getCoopRestrictionTrendsData();
// 合作限制-风险信号数据-获取数据
getCoopRestrictionSignalsData();
}); });
</script> </script>
...@@ -522,18 +530,31 @@ onMounted(() => { ...@@ -522,18 +530,31 @@ onMounted(() => {
background-color: rgba(255, 247, 230, 1); background-color: rgba(255, 247, 230, 1);
color: rgba(250, 140, 22, 1); color: rgba(250, 140, 22, 1);
} }
.cl6 {
background-color: rgba(246, 255, 237, 1);
color: rgba(82, 196, 26, 1);
}
.item-right {
flex: 1;
display: flex;
justify-content: space-between;
align-items: center;
overflow: hidden;
.main-center { .main-center {
width: 347px; flex: 1;
height: 30px; height: 30px;
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 400;
font-family: "Microsoft YaHei"; font-family: "Microsoft YaHei";
line-height: 30px; line-height: 30px;
color: rgb(59, 65, 75); color: rgb(59, 65, 75);
margin-right: 2px; margin-right: 10px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
} }
.main-right { .main-right {
width: 60px; width: 100px;
height: 24px; height: 24px;
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 400;
...@@ -541,6 +562,8 @@ onMounted(() => { ...@@ -541,6 +562,8 @@ onMounted(() => {
line-height: 24px; line-height: 24px;
color: rgb(132, 136, 142); color: rgb(132, 136, 142);
text-align: right; text-align: right;
flex-shrink: 0;
}
} }
} }
.right-mainbtn { .right-mainbtn {
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
</template> </template>
<script setup> <script setup>
import { ref, onMounted, onBeforeUnmount } from "vue"; import { ref, onMounted, onBeforeUnmount, watch } from "vue";
import * as echarts from "echarts"; import * as echarts from "echarts";
import { getCoopRestrictionCompare, getCoopRestrictionDomain } from "@/api/coopRestriction/coopRestriction"; import { getCoopRestrictionCompare, getCoopRestrictionDomain } from "@/api/coopRestriction/coopRestriction";
...@@ -63,6 +63,14 @@ const getCoopRestrictionCompareData = async () => { ...@@ -63,6 +63,14 @@ const getCoopRestrictionCompareData = async () => {
} }
}; };
watch(() => coopRestrictionCompare.value, () => {
initLeftChart();
}, { deep: true });
watch(() => coopRestrictionDomain.value, () => {
initRightChart();
}, { deep: true });
const value = ref(10); const value = ref(10);
const value1 = ref("2026"); const value1 = ref("2026");
const options = [ const options = [
...@@ -155,24 +163,111 @@ const initLeftChart = () => { ...@@ -155,24 +163,111 @@ const initLeftChart = () => {
if (!leftChartRef.value) return; if (!leftChartRef.value) return;
if (leftChart) leftChart.dispose(); if (leftChart) leftChart.dispose();
leftChart = echarts.init(leftChartRef.value); leftChart = echarts.init(leftChartRef.value);
const years = ["2014","2015","2016","2017","2018","2019","2020","2021","2022","2023","2024","2025"];
const academic = [150,65,85,95,70,95,125,150,140,170,190,175]; // 处理动态数据
const research = [70,90,123,115,130,145,165,160,162,168,180,182]; const rawData = coopRestrictionCompare.value;
const talent = [90,70,60,75,65,72,80,120,118,145,130,100]; const yearsSet = new Set();
const dataShare = [0,0,0,0,0,0,0,0,0,0,15,22]; const typesSet = new Set();
rawData.forEach(item => {
yearsSet.add(item.LIMITDATE);
typesSet.add(item.TYPENAME);
});
const years = Array.from(yearsSet).sort();
const types = Array.from(typesSet);
// 如果没有数据,给一些默认年份展示
const finalYears = years.length > 0 ? years : ["2020", "2021", "2022", "2023", "2024", "2025"];
// 定义颜色配置,确保线条色与阴影色对应
const colorMap = [
{ line: "#2f7ae5", start: "rgba(47, 122, 229, 0.3)", end: "rgba(47, 122, 229, 0.05)" },
{ line: "#29c0b1", start: "rgba(41, 192, 177, 0.3)", end: "rgba(41, 192, 177, 0.05)" },
{ line: "#e45f5f", start: "rgba(228, 95, 95, 0.3)", end: "rgba(228, 95, 95, 0.05)" },
{ line: "#7b5de6", start: "rgba(123, 93, 230, 0.3)", end: "rgba(123, 93, 230, 0.05)" }
];
const series = types.map((type, index) => {
const data = finalYears.map(year => {
const found = rawData.find(item => item.TYPENAME === type && item.LIMITDATE === year);
return found ? found.TYPECOUNT : 0;
});
// 根据索引获取颜色配置,超出范围则循环使用
const colorConfig = colorMap[index % colorMap.length];
return {
name: type,
type: "line",
smooth: false,
data: data,
symbol: "circle",
symbolSize: 6,
lineStyle: {
color: colorConfig.line,
width: 2
},
itemStyle: {
color: colorConfig.line
},
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: colorConfig.start },
{ offset: 1, color: colorConfig.end }
])
}
};
});
const option = { const option = {
color: ["#2f7ae5","#29c0b1","#e45f5f","#7b5de6"], color: colorMap.map(c => c.line),
grid: { left: 40, right: 24, top: 46, bottom: 36 }, grid: { left: 40, right: 24, top: 46, bottom: 36 },
tooltip: { trigger: "axis", axisPointer: { type: "line" } }, tooltip: { trigger: "axis", axisPointer: { type: "line" } },
legend: { top: 8, icon: "circle", itemWidth: 12, itemHeight: 12, itemGap: 24, textStyle: { color: "rgb(95, 101, 108)", fontSize: 16, fontFamily: "Microsoft YaHei", fontWeight: 400, lineHeight: 24 }, data: ["学术交流","科研合作","人才流动","数据共享"] }, legend: {
xAxis: { type: "category", boundaryGap: false, data: years, axisLine: { show: false }, axisTick: { show: false }, axisLabel: { color: "rgba(132, 136, 142, 1)", fontSize: 14, lineHeight: 22, fontFamily: "Microsoft YaHei", fontWeight: 400 } }, top: 8,
yAxis: { type: "value", min: 0, max: 200, interval: 40, splitLine: { show: true, lineStyle: { color: "#e6e6e6", type: "dashed" } }, axisLine: { show: false }, axisTick: { show: false }, axisLabel: { color: "rgba(132, 136, 142, 1)", fontSize: 14, fontFamily: "Microsoft YaHei", fontWeight: 400, lineHeight: 22 } }, icon: "circle",
series: [ itemWidth: 12,
{ name: "学术交流", type: "line", smooth: false, data: academic, symbol: "circle", symbolSize: 6, areaStyle: { color: new echarts.graphic.LinearGradient(0,0,0,1,[{offset:0,color:"rgba(47,122,229,0.25)"},{offset:1,color:"rgba(47,122,229,0.05)"}]) } }, itemHeight: 12,
{ name: "科研合作", type: "line", smooth: false, data: research, symbol: "circle", symbolSize: 6, areaStyle: { color: new echarts.graphic.LinearGradient(0,0,0,1,[{offset:0,color:"rgba(41,192,177,0.25)"},{offset:1,color:"rgba(41,192,177,0.05)"}]) } }, itemGap: 24,
{ name: "人才流动", type: "line", smooth: false, data: talent, symbol: "circle", symbolSize: 6, areaStyle: { color: new echarts.graphic.LinearGradient(0,0,0,1,[{offset:0,color:"rgba(228,95,95,0.25)"},{offset:1,color:"rgba(228,95,95,0.05)"}]) } }, textStyle: {
{ name: "数据共享", type: "line", smooth: false, data: dataShare, symbol: "circle", symbolSize: 6, areaStyle: { color: new echarts.graphic.LinearGradient(0,0,0,1,[{offset:0,color:"rgba(123,93,230,0.25)"},{offset:1,color:"rgba(123,93,230,0.05)"}]) } } color: "rgb(95, 101, 108)",
] fontSize: 16,
fontFamily: "Microsoft YaHei",
fontWeight: 400,
lineHeight: 24
},
data: types
},
xAxis: {
type: "category",
boundaryGap: false,
data: finalYears,
axisLine: { show: false },
axisTick: { show: false },
axisLabel: {
color: "rgba(132, 136, 142, 1)",
fontSize: 14,
lineHeight: 22,
fontFamily: "Microsoft YaHei",
fontWeight: 400
}
},
yAxis: {
type: "value",
min: 0,
splitLine: { show: true, lineStyle: { color: "#e6e6e6", type: "dashed" } },
axisLine: { show: false },
axisTick: { show: false },
axisLabel: {
color: "rgba(132, 136, 142, 1)",
fontSize: 14,
fontFamily: "Microsoft YaHei",
fontWeight: 400,
lineHeight: 22
}
},
series: series
}; };
leftChart.setOption(option); leftChart.setOption(option);
window.addEventListener("resize", handleResize); window.addEventListener("resize", handleResize);
...@@ -184,20 +279,62 @@ const initRightChart = () => { ...@@ -184,20 +279,62 @@ const initRightChart = () => {
if (!rightChartRef.value) return; if (!rightChartRef.value) return;
if (rightChart) rightChart.dispose(); if (rightChart) rightChart.dispose();
rightChart = echarts.init(rightChartRef.value); rightChart = echarts.init(rightChartRef.value);
const indicators = [
{ name: "集成电路", max: 10 }, const rawData = coopRestrictionDomain.value;
{ name: "能源领域", max: 10 },
{ name: "量子科技", max: 10 }, // 数据为空处理
{ name: "通信网络", max: 10 }, if (!rawData || rawData.length === 0) {
{ name: "人工智能", max: 10 }, rightChart.setOption({
{ name: "生物科技", max: 10 } graphic: {
]; type: 'text',
const academicR = [9,6,6,6,9,7]; left: 'center',
const researchR = [3,4,1.5,2,1.5,4]; top: 'middle',
const talentR = [4,10,3,4,2,5]; style: {
const dataShareR = [7,8,4,5,7,8]; text: '暂无数据',
fill: '#999',
fontSize: 16
}
}
});
return;
}
// 1. 动态提取所有领域(雷达图的维度)
const domainsSet = new Set();
const typesSet = new Set();
rawData.forEach(item => {
domainsSet.add(item.AREA);
typesSet.add(item.COOPERTYPE);
});
const domains = Array.from(domainsSet);
const types = Array.from(typesSet);
// 2. 构造指示器(Indicator),自动计算 Max 值
const indicators = domains.map(domain => {
const domainData = rawData.filter(item => item.AREA === domain);
const maxVal = Math.max(...domainData.map(d => d.COOPERTYPECOUNT), 5); // 最小给个5
return { name: domain, max: Math.ceil(maxVal * 1.2) }; // 留 20% 的余量
});
// 3. 构造 Series 数据
const colorMap = ["#2f7ae5", "#29c0b1", "#e45f5f", "#7b5de6"];
const seriesData = types.map((type, index) => {
const dataValues = domains.map(domain => {
const found = rawData.find(item => item.COOPERTYPE === type && item.AREA === domain);
return found ? found.COOPERTYPECOUNT : 0;
});
return {
name: type,
value: dataValues,
itemStyle: { color: colorMap[index % colorMap.length] },
areaStyle: { color: colorMap[index % colorMap.length], opacity: 0.1 }
};
});
const option = { const option = {
color: ["#2f7ae5","#29c0b1","#e45f5f","#7b5de6"], color: colorMap,
legend: { legend: {
top: 8, top: 8,
icon: "circle", icon: "circle",
...@@ -211,99 +348,31 @@ const initRightChart = () => { ...@@ -211,99 +348,31 @@ const initRightChart = () => {
fontWeight: 400, fontWeight: 400,
lineHeight: 24 lineHeight: 24
}, },
data: ["学术交流","科研合作","人才流动","数据共享"] data: types
}, },
radar: { radar: {
shape: "polygon", center: ["50%", "55%"],
splitNumber: 5, radius: "65%",
indicator: indicators, indicator: indicators.length > 0 ? indicators : [
center: ["50%","56%"], { name: "暂无数据", max: 100 },
radius: "58%", { name: "暂无数据", max: 100 },
startAngle: 90, { name: "暂无数据", max: 100 }
clockwise: false, ],
axisName: { axisName: {
color: "rgb(59, 65, 75)", color: "rgba(132, 136, 142, 1)",
fontSize: 16, fontSize: 14,
fontFamily: "Microsoft YaHei", fontWeight: 400
fontWeight: 700,
lineHeight: 24,
padding: [0, 5]
},
splitLine: {
lineStyle: {
color: "#d0d0d0",
width: 1
}
},
axisLine: {
lineStyle: {
color: "#d0d0d0",
width: 1
}
},
splitArea: {
show: true,
areaStyle: {
color: ["#fff","rgb(247, 248, 249)","#fff","rgb(247, 248, 249)","#fff"]
}
}
},
series: [
{
name: "学术交流",
type: "radar",
data: [{ value: academicR }],
lineStyle: {
width: 2,
color: "#2f7ae5"
}, },
symbol: "none", splitLine: { lineStyle: { color: ["#e6e6e6"] } },
areaStyle: { splitArea: { show: false }
color: "rgba(47,122,229,0.15)"
}
}, },
{ series: [{
name: "科研合作",
type: "radar", type: "radar",
data: [{ value: researchR }], data: seriesData
lineStyle: { }]
width: 2,
color: "#29c0b1"
},
symbol: "none",
areaStyle: {
color: "rgba(41,192,177,0.15)"
}
},
{
name: "人才流动",
type: "radar",
data: [{ value: talentR }],
lineStyle: {
width: 2,
color: "#e45f5f"
},
symbol: "none",
areaStyle: {
color: "rgba(228,95,95,0.15)"
}
},
{
name: "数据共享",
type: "radar",
data: [{ value: dataShareR }],
lineStyle: {
width: 2,
color: "#7b5de6"
},
symbol: "none",
areaStyle: {
color: "rgba(123,93,230,0.15)"
}
}
]
}; };
rightChart.setOption(option); rightChart.setOption(option);
window.addEventListener("resize", handleResize);
}; };
onMounted(() => { onMounted(() => {
......
...@@ -2,11 +2,11 @@ ...@@ -2,11 +2,11 @@
<div class="cooperation-restrictions-detail"> <div class="cooperation-restrictions-detail">
<div class="nav"> <div class="nav">
<div class="nav-main"> <div class="nav-main">
<img src="./assets/image01.png" alt="" /> <img :src="coopData?.IMAGEURL || defaultImg" alt="" />
<div class="content"> <div class="content">
<div class="cl1">通过应对哈佛大学的风险来增强国家安全</div> <div class="cl1">{{coopData?.LIMITNAMEZH}}</div>
<div class="cl2">Enhancing National Security by Addressing Risks at Harvard University</div> <div class="cl2">{{coopData?.LIMITNAME}}</div>
<div class="cl3">2025年6月4日 10:33 · 美国白宫</div> <div class="cl3">{{coopData?.LIMITDATE}} · {{ coopData?.LIMITORGNAME }}</div>
</div> </div>
<div class="btn"> <div class="btn">
<button class="btn1"><img src="./assets/icon01.png" alt="" />查看原文</button> <button class="btn1"><img src="./assets/icon01.png" alt="" />查看原文</button>
...@@ -15,9 +15,9 @@ ...@@ -15,9 +15,9 @@
</div> </div>
</div> </div>
</div> </div>
<div class="title"> <div class="title" v-if="coopData?.Relation?.[0]" @click="handleClick">
<span class="title-one">当前合作限制数据已关联至总统政令</span> <span class="title-one">当前合作限制数据已关联至{{coopData.Relation[0]?.TYPE}}</span>
<span class="title-two">通过应对哈佛大学的风险来增强国家安全》2025年6月4日</span> <span class="title-two">{{coopData.Relation[0]?.RELATIONNAME}}{{coopData.Relation[0]?.RELATIONDATE}}</span>
<img src="./assets/right.png" alt="" /> <img src="./assets/right.png" alt="" />
</div> </div>
<div class="main"> <div class="main">
...@@ -30,15 +30,15 @@ ...@@ -30,15 +30,15 @@
<img class="img3" src="./assets/收藏按钮.png" alt="" /> <img class="img3" src="./assets/收藏按钮.png" alt="" />
<div class="left-top-content"> <div class="left-top-content">
<span <span
>2025年6月4日,特朗普签署总统公告,全面暂停持F/M/J签证者入境哈佛学习,并授权撤销部分在校国际生的签证。</span >{{ coopData?.INTRODUCTION }}</span
> >
</div> </div>
<div class="left-top-bottom"> <div class="left-top-bottom">
<div><span class="tit">限制时间:</span><span class="tit1">2025年6月4日</span></div> <div><span class="tit">限制时间:</span><span class="tit1">{{ coopData?.LIMITDATE }}</span></div>
<div><span class="tit">限制机构:</span><span class="tit1 tit2">美国白宫 ></span></div> <div @click="handleClickOnLimitOrg" style="cursor: pointer;"><span class="tit">限制机构:</span><span class="tit1 tit2">{{ coopData?.LIMITORGNAME }} ></span></div>
<div><span class="tit">限制手段:</span><span class="tit1">总统行政令</span></div> <div><span class="tit">限制手段:</span><span class="tit1">{{ coopData?.LIMITMEANS }}</span></div>
<div><span class="tit">限制类型:</span><span class="tit1 tit3">人才交流限制</span></div> <div><span class="tit">限制类型:</span><span class="tit1 tit3">{{ coopData?.LIMITTYPE }}</span></div>
<div><span class="tit">限制领域:</span><span class="tit1">无特定领域</span></div> <div><span class="tit">限制领域:</span><span class="tit1">{{ coopData?.area }}</span></div>
</div> </div>
</div> </div>
<!-- 相关实体 --> <!-- 相关实体 -->
...@@ -48,9 +48,9 @@ ...@@ -48,9 +48,9 @@
<img class="img2" src="./assets/下载按钮.png" alt="" /> <img class="img2" src="./assets/下载按钮.png" alt="" />
<img class="img3" src="./assets/收藏按钮.png" alt="" /> <img class="img3" src="./assets/收藏按钮.png" alt="" />
<div class="left-bottom-main"> <div class="left-bottom-main">
<div v-for="item in dataList" :key="item.id" class="main-box"> <div v-for="item in coopRelatedData" :key="item.id" class="main-box" @click="handleClickOnEntity(item)">
<img :src="item.img" alt="" /> <img :src="item.img || defaultCom" alt="" />
<div class="name">{{ item.name }}</div> <div class="name">{{ item.ENTITYNAME }}</div>
<div class="type">{{ item.type }}</div> <div class="type">{{ item.type }}</div>
</div> </div>
</div> </div>
...@@ -64,9 +64,9 @@ ...@@ -64,9 +64,9 @@
<div class="btn cl1" :class="{'active': active === '涉华背景'}" @click="active = '涉华背景'">涉华背景</div> <div class="btn cl1" :class="{'active': active === '涉华背景'}" @click="active = '涉华背景'">涉华背景</div>
<div class="btn cl2" :class="{'active': active === '全部背景'}" @click="active = '全部背景'">全部背景</div> <div class="btn cl2" :class="{'active': active === '全部背景'}" @click="active = '全部背景'">全部背景</div>
<div class="right-top-content"> <div class="right-top-content">
<div v-for="item in dataList2" :key="item.id" class="right-top-item"> <div v-for="(item, index) in filteredBackgroundList" :key="index" class="right-top-item">
<span class="id">{{ item.id }}</span> <span class="id">{{ index + 1 }}</span>
<span class="name">{{ item.name }}</span> <span class="name">{{ item.CONTENT }}</span>
<img src="./assets/打开按钮.png" alt="" /> <img src="./assets/打开按钮.png" alt="" />
</div> </div>
</div> </div>
...@@ -77,35 +77,16 @@ ...@@ -77,35 +77,16 @@
<div class="right-bottom-title">限制条款</div> <div class="right-bottom-title">限制条款</div>
<div class="btn cl1" :class="{'active': active2 === '涉华背景'}" @click="active2 = '涉华背景'">涉华背景</div> <div class="btn cl1" :class="{'active': active2 === '涉华背景'}" @click="active2 = '涉华背景'">涉华背景</div>
<div class="btn cl2" :class="{'active': active2 === '全部背景'}" @click="active2 = '全部背景'">全部背景</div> <div class="btn cl2" :class="{'active': active2 === '全部背景'}" @click="active2 = '全部背景'">全部背景</div>
<div class="right-bottom-content1"> <div class="right-bottom-content">
<div class="right-bottom-content1-title"> <div v-for="(item, index) in filteredClauseList" :key="index" class="clause-item">
<span>(一)暂停入境 </span> <div class="clause-item-title">
<span>{{ chineseNumbers[index] }}{{ item.TITLE }} </span>
<img src="./assets/打开按钮.png" alt=""> <img src="./assets/打开按钮.png" alt="">
</div> </div>
<div class="right-bottom-content1-content"> <div class="clause-item-content">
任何外籍人士作为非移民进入美国,根据 INA 第 101(a)(15)(F)或第 101(a)(15)(M)条,即 8 U.S.C. 1101(a)(15)(F)或 1101(a)(15)(M)条款,进入哈佛大学参加交流访客项目,或根据 INA 第 101(a)(15)(J)条,在哈佛大学主办的交流访客项目, 8 U.S.C. 1101(a)(15)(J)被暂停并限制,受本公告第 2 条约束。 该暂停和限制将在本公告发布后 6 个月内失效,除非延长。 {{ item.CONTENT }}
</div> </div>
</div> </div>
<div class="right-bottom-content2">
<div class="right-bottom-content2-title">
<span>(二)暂停和限制入境的范围及实施 </span>
<img src="./assets/打开按钮.png" alt="">
</div>
<div class="right-bottom-content2-content">
<div v-for="item in dataList3" :key="item.id" class="forcontent">
<span>{{ item.id }}.</span>
<span>{{ item.name }}</span>
</div>
</div>
</div>
<div class="right-bottom-content3">
<div class="right-bottom-content3-title">
<span>(三)执行本命令的作性行动 </span>
<img src="./assets/打开按钮.png" alt="">
</div>
<div class="right-bottom-content3-content">
国务卿、司法部长和国土安全部长应协调采取一切必要和适当的行动以落实本公告。 国务卿、司法部长和国土安全部长还应考虑利用各自在 INA 下的权限,对哈佛大学参与 SEVP 的能力施加限制,以及学生及交流访客信息系统。 任何此类行动应包括对任何符合国家利益的外国人的例外,这些入境由国务卿、国土安全部长或其各自指定的人决定。
</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -114,7 +95,14 @@ ...@@ -114,7 +95,14 @@
</template> </template>
<script setup> <script setup>
import { ref, onMounted } from "vue"; import { ref, watch, computed } from "vue";
import { useRoute, useRouter } from "vue-router";
import { getCoopRestrictionIntroduction, getCoopRestrictionRelated, getCoopRestrictionBackground, getCoopRestrictionClause } from "@/api/coopRestriction/coopRestriction";
const route = useRoute();
const router = useRouter();
import defaultImg from "./assets/image01.png"
import defaultCom from "../assets/images/default-icon2.png"
import Harvard from "./assets/哈佛.png"; import Harvard from "./assets/哈佛.png";
import Senate from "./assets/参议院.png"; import Senate from "./assets/参议院.png";
import Justice from "./assets/司法部.png"; import Justice from "./assets/司法部.png";
...@@ -125,8 +113,159 @@ import Rubio from "./assets/卢比奥.png"; ...@@ -125,8 +113,159 @@ import Rubio from "./assets/卢比奥.png";
import Bondi from "./assets/邦迪.png"; import Bondi from "./assets/邦迪.png";
import Nome from "./assets/诺姆.png"; import Nome from "./assets/诺姆.png";
// 合作限制-查询限制条款
const limitClauseData = ref([]);
const getlimitClauseData = async () => {
if (!route.query.id) return;
try {
const res = await getCoopRestrictionClause({
limitId: route.query.id
});
if (res && res.code === 200) {
limitClauseData.value = res.data || [];
} else {
limitClauseData.value = [];
}
} catch (error) {
console.error("获取合作限制限制条款数据失败:", error);
limitClauseData.value = [];
}
};
// 合作限制-查询背景分析
const backgroundList = ref([]);
const getbackgroundData = async () => {
if (!route.query.id) return;
try {
const res = await getCoopRestrictionBackground({
limitId: route.query.id
});
if (res && res.code === 200) {
backgroundList.value = res.data || [];
} else {
backgroundList.value = [];
}
} catch (error) {
console.error("获取合作限制背景分析数据失败:", error);
backgroundList.value = [];
}
};
// 合作限制-查询相关实体
const coopRelatedData = ref([]);
const getcoopRelatedData = async () => {
if (!route.query.id) return;
try {
const res = await getCoopRestrictionRelated({
limitId: route.query.id
});
if (res && res.code === 200) {
coopRelatedData.value = res.data || {};
} else {
coopRelatedData.value = {};
}
} catch (error) {
console.error("获取合作限制相关实体数据失败:", error);
coopRelatedData.value = {};
}
};
// 点击跳转关联实体详情
const handleClickOnEntity = (item) => {
if (!item.ENTITYID) return;
const path = `/companyPages/${item.ENTITYID}`;
const { href } = router.resolve({ path });
window.open(href, "_blank");
};
// 合作限制-查询简介接口
const coopData = ref({});
const getCoopRestrictionIntroductionData = async () => {
if (!route.query.id) return;
try {
const res = await getCoopRestrictionIntroduction({
limitId: route.query.id
});
if (res && res.code === 200) {
coopData.value = res.data || {};
} else {
coopData.value = {};
}
} catch (error) {
console.error("获取合作限制简介数据失败:", error);
coopData.value = {};
}
};
// 点击跳转关联文件详情
const handleClick = () => {
const relation = coopData.value?.Relation?.[0];
if (!relation?.RELATIONID) return;
let path = "";
let query = {};
if (relation.TYPE === "行政令") {
path = "/decreeLayout/overview/introduction";
query = { id: relation.RELATIONID };
} else if (relation.TYPE === "法案") {
path = "/billLayout/bill/introduction";
query = { billId: relation.RELATIONID };
}
if (path) {
const { href } = router.resolve({ path, query });
window.open(href, "_blank");
}
};
// 点击跳转限制机构详情
const handleClickOnLimitOrg = () => {
if (!coopData.value?.LIMITORGID) return;
const path = "/institution";
const query = { id: coopData.value?.LIMITORGID };
const { href } = router.resolve({ path, query });
window.open(href, "_blank");
};
// 监听路由 id 变化,自动刷新数据
watch(
() => route.query.id,
(newId) => {
if (newId) {
getCoopRestrictionIntroductionData();
getcoopRelatedData();
getbackgroundData();
getlimitClauseData();
}
},
{ immediate: true }
);
const active = ref("涉华背景"); const active = ref("涉华背景");
// 根据按钮切换过滤背景数据
const filteredBackgroundList = computed(() => {
if (active.value === "全部背景") {
return backgroundList.value;
} else {
return backgroundList.value.filter(item => item.ISCN === "Y");
}
});
const active2 = ref("涉华背景"); const active2 = ref("涉华背景");
const chineseNumbers = ["一", "二", "三", "四", "五", "六", "七", "八", "九", "十"];
const filteredClauseList = computed(() => {
if (active2.value === "全部背景") {
return limitClauseData.value;
} else {
return limitClauseData.value.filter(item => item.ISCN === "Y");
}
});
const dataList = ref([ const dataList = ref([
{ {
...@@ -273,6 +412,7 @@ const dataList3 = ref([ ...@@ -273,6 +412,7 @@ const dataList3 = ref([
margin-bottom: 1px; margin-bottom: 1px;
} }
.cl2 { .cl2 {
height: 24px;
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 400;
line-height: 24px; line-height: 24px;
...@@ -292,6 +432,7 @@ const dataList3 = ref([ ...@@ -292,6 +432,7 @@ const dataList3 = ref([
width: 376px; width: 376px;
height: 36px; height: 36px;
display: flex; display: flex;
justify-content: right;
.btn1 { .btn1 {
border-radius: 6px; border-radius: 6px;
border: 1px solid rgb(230, 231, 232); border: 1px solid rgb(230, 231, 232);
...@@ -332,6 +473,7 @@ const dataList3 = ref([ ...@@ -332,6 +473,7 @@ const dataList3 = ref([
display: flex; display: flex;
align-items: center; align-items: center;
position: relative; position: relative;
cursor: pointer;
.title-one { .title-one {
margin-left: 23px; margin-left: 23px;
font-size: 16px; font-size: 16px;
...@@ -369,11 +511,14 @@ const dataList3 = ref([ ...@@ -369,11 +511,14 @@ const dataList3 = ref([
.left-top { .left-top {
margin-bottom: 16px; margin-bottom: 16px;
width: 520px; width: 520px;
height: 386px; // height: 386px;
background-color: #fff; background-color: #fff;
border-radius: 10px; border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1); box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
position: relative; position: relative;
box-sizing: border-box;
overflow: hidden;
padding-bottom: 33px;
.left-top-title { .left-top-title {
font-size: 20px; font-size: 20px;
font-weight: 700; font-weight: 700;
...@@ -409,13 +554,11 @@ const dataList3 = ref([ ...@@ -409,13 +554,11 @@ const dataList3 = ref([
} }
.left-top-content { .left-top-content {
width: 470px; width: 470px;
height: 92px; margin-top: 58px;
margin-left: 26px;
border-radius: 4px; border-radius: 4px;
border: 1px solid rgba(231, 243, 255, 1); border: 1px solid rgba(231, 243, 255, 1);
background-color: rgba(246, 250, 255, 1); background-color: rgba(246, 250, 255, 1);
position: absolute;
top: 58px;
left: 26px;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
...@@ -431,9 +574,8 @@ const dataList3 = ref([ ...@@ -431,9 +574,8 @@ const dataList3 = ref([
.left-top-bottom { .left-top-bottom {
width: 460px; width: 460px;
height: 184px; height: 184px;
position: absolute; margin-top: 19px;
top: 169px; margin-left: 26px;
left: 26px;
div { div {
height: 24px; height: 24px;
margin-bottom: 16px; margin-bottom: 16px;
...@@ -590,6 +732,7 @@ const dataList3 = ref([ ...@@ -590,6 +732,7 @@ const dataList3 = ref([
position: relative; position: relative;
display: flex; display: flex;
align-items: center; align-items: center;
overflow: auto;
} }
.right-top-item:nth-child(odd) { .right-top-item:nth-child(odd) {
background-color: rgb(247, 248, 249); background-color: rgb(247, 248, 249);
...@@ -710,109 +853,16 @@ const dataList3 = ref([ ...@@ -710,109 +853,16 @@ const dataList3 = ref([
background-color: rgba(246, 250, 255, 1); background-color: rgba(246, 250, 255, 1);
border-color: rgb(5, 95, 194); border-color: rgb(5, 95, 194);
} }
.right-bottom-content1 { .right-bottom-content {
width: 1022px; width: 1022px;
height: 199px;
position: absolute; position: absolute;
top: 60px; top: 60px;
left: 22px; left: 22px;
margin-bottom: 24px; margin-bottom: 24px;
.right-bottom-content1-title { overflow: auto;
width: 1022px; .clause-item {
height: 55px;
padding: 14px 56px 17px 24px;
display: flex;
align-items: center;
position: relative;
background-color: rgb(247, 248, 249);
border-top: 1px solid rgb(234, 236, 238);
border-bottom: 1px solid rgb(234, 236, 238);
span {
font-size: 18px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
}
img {
width: 16px;
height: 31px;
position: absolute;
right: 24px;
top: 14px;
cursor: pointer;
}
}
.right-bottom-content1-content {
width: 1022px;
height: 144px;
padding: 12px 24px 12px 78px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 30px;
color: rgb(59, 65, 75);
border-bottom: 1px solid rgb(234, 236, 238);
}
}
.right-bottom-content2 {
width: 1022px;
height: 385px;
position: absolute;
top: 283px;
left: 22px;
margin-bottom: 24px;
.right-bottom-content2-title {
width: 1022px;
height: 55px;
padding: 14px 56px 17px 24px;
display: flex;
align-items: center;
position: relative;
background-color: rgb(247, 248, 249);
border-top: 1px solid rgb(234, 236, 238);
border-bottom: 1px solid rgb(234, 236, 238);
span {
font-size: 18px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(59, 65, 75);
}
img {
width: 16px;
height: 31px;
position: absolute;
right: 24px;
top: 14px;
cursor: pointer;
}
}
.right-bottom-content2-content {
width: 1022px;
height: 330px;
.forcontent {
padding: 12px 24px 12px 54px;
border-bottom: 1px solid rgb(234, 236, 238);
span {
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 30px;
color: rgb(59, 65, 75);
}
}
}
}
.right-bottom-content3 {
width: 1022px;
height: 169px;
position: absolute;
top: 692px;
left: 22px;
margin-bottom: 24px; margin-bottom: 24px;
.right-bottom-content3-title { .clause-item-title {
width: 1022px; width: 1022px;
height: 55px; height: 55px;
padding: 14px 56px 17px 24px; padding: 14px 56px 17px 24px;
...@@ -838,9 +888,8 @@ const dataList3 = ref([ ...@@ -838,9 +888,8 @@ const dataList3 = ref([
cursor: pointer; cursor: pointer;
} }
} }
.right-bottom-content3-content { .clause-item-content {
width: 1022px; width: 1022px;
height: 114px;
padding: 12px 24px 12px 78px; padding: 12px 24px 12px 78px;
font-size: 16px; font-size: 16px;
font-weight: 400; font-weight: 400;
...@@ -848,6 +897,8 @@ const dataList3 = ref([ ...@@ -848,6 +897,8 @@ const dataList3 = ref([
line-height: 30px; line-height: 30px;
color: rgb(59, 65, 75); color: rgb(59, 65, 75);
border-bottom: 1px solid rgb(234, 236, 238); border-bottom: 1px solid rgb(234, 236, 238);
white-space: pre-line;
}
} }
} }
} }
......
...@@ -21,7 +21,7 @@ defineProps({ ...@@ -21,7 +21,7 @@ defineProps({
display: flex; display: flex;
align-items: center; align-items: center;
width: 100%; width: 100%;
margin-bottom: 20px; margin-bottom: 36px;
padding: 10px 15px; padding: 10px 15px;
} }
......
...@@ -98,7 +98,7 @@ ...@@ -98,7 +98,7 @@
</div> </div>
<el-row :gutter="20" style="width: 1600px; margin: 0 auto"> <el-row :gutter="20" style="width: 1600px; margin: 0 auto">
<CustomTitle id="position1" title="最新动态" style="margin-top: 24px" /> <CustomTitle id="position1" title="最新动态" style="margin-top: 10px" />
<el-col :span="16"> <el-col :span="16">
<custom-container titleType="primary" title="最新出口管制政策" :titleIcon="houseIcon" height="450px"> <custom-container titleType="primary" title="最新出口管制政策" :titleIcon="houseIcon" height="450px">
<template #header-right> <template #header-right>
...@@ -246,7 +246,7 @@ ...@@ -246,7 +246,7 @@
</el-row> </el-row>
<el-row :gutter="20" style="width: 1600px; margin: 0 auto"> <el-row :gutter="20" style="width: 1600px; margin: 0 auto">
<CustomTitle id="position2" title="资讯要闻" style="margin-top: 64px" /> <CustomTitle id="position2" title="资讯要闻" style="margin-top: 10px" />
<el-col :span="12"> <el-col :span="12">
<custom-container title="新闻资讯" :titleIcon="newsIcon" height="450px"> <custom-container title="新闻资讯" :titleIcon="newsIcon" height="450px">
<template #header-right> <template #header-right>
...@@ -277,37 +277,6 @@ ...@@ -277,37 +277,6 @@
:source="item.source" :source="item.source"
:content="item.content" :content="item.content"
/> />
<!-- <MessageBubble
:avatar="customMessage.avatar"
:name="customMessage.name"
:time="customMessage.time"
:source="customMessage.source"
:content="customMessage.content"
/> -->
<!-- <MessageBubble
@click="handlePerClick(item)"
:avatar="trumpAvatar"
name="唐纳德·特朗普"
time="16:02"
source="发布于真实社交"
content="埃隆·马斯克在强力支持我竞选总统之前,早就知道我强烈反对‘电动汽车强制令’。这太荒谬了,这一直是我竞选活动的主要部分。电动汽车没问题,但不应该强迫每个人都拥有一辆。埃隆获得的补贴可能远远超过历史上任何一个人。如果没有补贴,埃隆可能不得不关门大吉,回到南非老家。"
/>
<MessageBubble
:avatar="elongAvatar"
name="埃隆·马斯克"
time="16:02"
source="发布于真实社交"
content="如果这个疯狂的支出法案获得通过,‘美国党’将在第二天成立。"
/>
<MessageBubble
:avatar="elongAvatar"
name="埃隆·马斯克"
time="16:02"
source="发布于真实社交"
content="提出特朗普政府的AI政策强调技术开放与快速应用,但可能以牺牲安全防范为代价,开启了“潘多拉魔盒”。"
/> -->
</div> </div>
</template> </template>
</custom-container> </custom-container>
...@@ -315,7 +284,7 @@ ...@@ -315,7 +284,7 @@
</el-row> </el-row>
<el-row :gutter="20" style="width: 1600px; margin: 0 auto"> <el-row :gutter="20" style="width: 1600px; margin: 0 auto">
<CustomTitle id="position3" title="数据总览" style="margin-top: 64px" /> <CustomTitle id="position3" title="数据总览" style="margin-top: 10px" />
<el-col :span="24"> <el-col :span="24">
<custom-container title="发布频度" :titleIcon="box3Icon" height="450px"> <custom-container title="发布频度" :titleIcon="box3Icon" height="450px">
<template #default> <template #default>
...@@ -425,7 +394,17 @@ ...@@ -425,7 +394,17 @@
<el-col :span="16"> <el-col :span="16">
<custom-container title="制裁清单数量增长趋势" :titleIcon="qushiIcon" height="480px"> <custom-container title="制裁清单数量增长趋势" :titleIcon="qushiIcon" height="480px">
<template #header-right> <template #header-right>
<div style="display: flex; align-items: center; gap: 16px">
<el-checkbox v-model="trendChecked" label="50%规则" size="large" /> <el-checkbox v-model="trendChecked" label="50%规则" size="large" />
<el-select v-model="selectedEntityId" placeholder="请选择清单类型" style="width: 160px">
<el-option
v-for="item in infoList"
:key="item.id"
:label="item.nameZh"
:value="item.id"
/>
</el-select>
</div>
</template> </template>
<template #default> <template #default>
<EChart :option="trendOption" autoresize :style="{ height: '400px' }" /> <EChart :option="trendOption" autoresize :style="{ height: '400px' }" />
...@@ -435,7 +414,7 @@ ...@@ -435,7 +414,7 @@
</el-row> </el-row>
<el-row :gutter="20" style="width: 1600px; margin: 0 auto"> <el-row :gutter="20" style="width: 1600px; margin: 0 auto">
<CustomTitle id="position4" title="资源库" style="margin-top: 54px" /> <CustomTitle id="position4" title="资源库" style="margin-top: 0px" />
<div class="resource-tabs"> <div class="resource-tabs">
<div <div
v-for="tab in resourceTabs" v-for="tab in resourceTabs"
...@@ -662,7 +641,7 @@ ...@@ -662,7 +641,7 @@
<div class="year">{{ item.year }}</div> <div class="year">{{ item.year }}</div>
<div class="date">{{ item.dateStr }}</div> <div class="date">{{ item.dateStr }}</div>
</div> </div>
<img :src="item.icon || comTitle" alt="" /> <img :src="item.orgLogoUrl || comTitle" alt="" />
<div class="main"> <div class="main">
<div class="main-title" @click="handleTitleClick(item)">{{ item.title }}</div> <div class="main-title" @click="handleTitleClick(item)">{{ item.title }}</div>
<div class="main-desc">{{ item.desc }}</div> <div class="main-desc">{{ item.desc }}</div>
...@@ -936,6 +915,7 @@ const entitiesDataInfoList = shallowRef([]); ...@@ -936,6 +915,7 @@ const entitiesDataInfoList = shallowRef([]);
// 趋势图 // 趋势图
const trendOption = ref({}); const trendOption = ref({});
const trendChecked = ref(false); const trendChecked = ref(false);
const selectedEntityId = ref(1);
// 发布频度 // 发布频度
const tableData1 = ref([]); const tableData1 = ref([]);
// CCL发布频度 // CCL发布频度
...@@ -955,12 +935,11 @@ const newsList = ref([]); ...@@ -955,12 +935,11 @@ const newsList = ref([]);
onMounted(async () => { onMounted(async () => {
try { try {
const [dataCount, entitiesDataInfo, industryCountByYear, cclList, countDomainByYear] = await Promise.all([ const [dataCount, entitiesDataInfo, industryCountByYear, cclList] = await Promise.all([
getEntitiesDataCount(), getEntitiesDataCount(),
getEntitiesDataInfo(), getEntitiesDataInfo(),
getIndustryCountByYear(1), getIndustryCountByYear(1),
getIndustryCountByYear(13), getIndustryCountByYear(13)
getCountDomainByYear(trendChecked.value)
]); ]);
// 交换第二个和第三个元素 // 交换第二个和第三个元素
[dataCount[1], dataCount[2]] = [dataCount[2], dataCount[1]]; [dataCount[1], dataCount[2]] = [dataCount[2], dataCount[1]];
...@@ -990,10 +969,8 @@ onMounted(async () => { ...@@ -990,10 +969,8 @@ onMounted(async () => {
}; };
}).slice(0, 5); }).slice(0, 5);
// 整理柱状图数据并应用到趋势图 // 获取趋势图数据
if (countDomainByYear && countDomainByYear[0].yearDomainCount) { await fetchTrendData();
trendOption.value = processYearDomainCountData(countDomainByYear[0].yearDomainCount);
}
await fetchRiskSignals("0103"); await fetchRiskSignals("0103");
// 获取社交媒体信息 // 获取社交媒体信息
...@@ -1011,6 +988,30 @@ onMounted(async () => { ...@@ -1011,6 +988,30 @@ onMounted(async () => {
} }
}); });
// 获取趋势图数据
const fetchTrendData = async () => {
try {
const res = await getCountDomainByYear({
isRule: trendChecked.value,
startYear: "2020",
endYear: String(new Date().getFullYear()),
sanTypeId: selectedEntityId.value
});
if (res && res[0] && res[0].yearDomainCount) {
trendOption.value = processYearDomainCountData(res[0].yearDomainCount);
}
} catch (error) {
console.error("获取趋势图数据失败:", error);
}
};
watch(
() => [trendChecked.value, selectedEntityId.value],
() => {
fetchTrendData();
}
);
// 新增函数:处理 yearDomainCount 数据并使用 getMultipleBarChart_m 方法生成图表配置 // 新增函数:处理 yearDomainCount 数据并使用 getMultipleBarChart_m 方法生成图表配置
const processYearDomainCountData = yearDomainCountData => { const processYearDomainCountData = yearDomainCountData => {
// 提取所有年份并排序 // 提取所有年份并排序
...@@ -1049,20 +1050,6 @@ const processYearDomainCountData = yearDomainCountData => { ...@@ -1049,20 +1050,6 @@ const processYearDomainCountData = yearDomainCountData => {
return getMultipleBarChart_m(chartData); return getMultipleBarChart_m(chartData);
}; };
watch(
() => trendChecked.value,
async checked => {
const res = await getCountDomainByYear(checked);
// if (res && Array.isArray(res) && res.length > 0) {
// trendOption.value = getMultipleBarChart_m(res);
// }
// 整理数据并更新趋势图
if (res && res[0].yearDomainCount) {
trendOption.value = processYearDomainCountData(res[0].yearDomainCount);
}
}
);
const handleEntityClick = item => { const handleEntityClick = item => {
console.log("item", item); console.log("item", item);
const route = router.resolve({ const route = router.resolve({
...@@ -1144,43 +1131,6 @@ const searchExportControlText = ref(""); ...@@ -1144,43 +1131,6 @@ const searchExportControlText = ref("");
const infoListColor = ref(["rgba(206, 79, 81, 1)", "rgba(132, 136, 142, 1)", "rgba(132, 136, 142, 1)", "rgba(132, 136, 142, 1)"]); const infoListColor = ref(["rgba(206, 79, 81, 1)", "rgba(132, 136, 142, 1)", "rgba(132, 136, 142, 1)", "rgba(132, 136, 142, 1)"]);
const infoList = ref([]); const infoList = ref([]);
// const customNewsData = ref([
// {
// image: newsImg,
// title: "美国智库激辩人工智能监管路径",
// time: "11-4",
// source: "华盛顿邮报",
// description: "各方就AI监管模式展开讨论。有观点认为碎片化州级监管比全面联邦法规更灵活,也有分析..."
// },
// {
// image: newsImg,
// title: "布鲁金斯学会称美国低估中国在“印太”战略",
// time: "11-3",
// source: "纽约时报",
// description: "分析认为,当美国注意力被其他地区分散时,中国通过外交、发展和防务多管齐下,系统性......"
// },
// {
// image: newsImg1,
// title: "五角大楼指令引发智库与国防部“脱钩”震荡",
// time: "11-3",
// source: "洛杉矶时报",
// description: "美国国防部长下令全面暂停部内人员参与所有智库活动,标志着传统的“旋转门”关系发生......"
// },
// {
// image: newsImg,
// title: "CSIS建议美国建立跨机构AI基准测试体系",
// time: "11-3",
// source: "福克斯新闻网",
// description: "指出美国《人工智能行动计划》忽视了基准测试这一关键环节,建议由国家标准与技术研究........."
// },
// {
// image: newsImg1,
// title: "美国智库激辩人工智能监管路径",
// time: "11-4",
// source: "华盛顿邮报",
// description: "各方就AI监管模式展开讨论。有观点认为碎片化州级监管比全面联邦法规更灵活,也有分析..."
// }
// ]);
// 雷达图 // 雷达图
const domainChecked = ref(false); const domainChecked = ref(false);
...@@ -1188,9 +1138,24 @@ const radarOption = ref({ ...@@ -1188,9 +1138,24 @@ const radarOption = ref({
title: { title: {
text: "" text: ""
}, },
tooltip: {
trigger: "item",
confine: true
},
legend: { legend: {
top: "0%", top: "0%",
icon: "circle", icon: "circle",
itemWidth: 12,
itemHeight: 12,
textStyle: {
fontSize: 16,
fontWeight: 400,
fontFamily: "Microsoft YaHei",
color: "rgb(95, 101, 108)",
lineHeight: 24,
verticalAlign: "middle",
padding: [2, 0, 0, 0]
},
data: [] data: []
}, },
radar: { radar: {
...@@ -1209,6 +1174,7 @@ const radarOption = ref({ ...@@ -1209,6 +1174,7 @@ const radarOption = ref({
{ {
name: "", name: "",
type: "radar", type: "radar",
symbol: "none", // 隐藏节点圆圈
data: [] data: []
} }
] ]
...@@ -1217,7 +1183,7 @@ const radarOption = ref({ ...@@ -1217,7 +1183,7 @@ const radarOption = ref({
// 获取雷达图数据 // 获取雷达图数据
const fetchRadarData = async checked => { const fetchRadarData = async checked => {
try { try {
const data = await getSanDomainCount(checked); const data = await getSanDomainCount(checked, "export");
if (data && Array.isArray(data) && data.length > 0) { if (data && Array.isArray(data) && data.length > 0) {
// 收集所有可能的领域名称 // 收集所有可能的领域名称
const allDomains = new Set(); const allDomains = new Set();
...@@ -1232,7 +1198,16 @@ const fetchRadarData = async checked => { ...@@ -1232,7 +1198,16 @@ const fetchRadarData = async checked => {
const domainNames = Array.from(allDomains); const domainNames = Array.from(allDomains);
// 为每个制裁类型准备数据 // 为每个制裁类型准备数据
const seriesData = data.map(sanItem => { const radarColors = [
"rgba(45, 123, 248, 1)",
"rgba(206, 79, 81, 1)",
"rgba(255, 197, 61, 1)",
"rgba(255, 182, 193, 1)",
"rgba(159, 122, 234, 1)",
"rgba(90, 200, 220, 1)"
];
const seriesData = data.map((sanItem, index) => {
// 创建一个映射,将领域名称映射到数量 // 创建一个映射,将领域名称映射到数量
const domainMap = {}; const domainMap = {};
if (sanItem.domainCountInfo) { if (sanItem.domainCountInfo) {
...@@ -1245,17 +1220,14 @@ const fetchRadarData = async checked => { ...@@ -1245,17 +1220,14 @@ const fetchRadarData = async checked => {
const values = domainNames.map(name => domainMap[name] || 0); const values = domainNames.map(name => domainMap[name] || 0);
// 确定颜色 // 确定颜色
let color = "rgba(10, 87, 166, 0.2)"; // 默认实体清单颜色 const solidColor = radarColors[index % radarColors.length];
if (sanItem.sanTypeName === "商业管制清单") { const areaColor = solidColor.replace("1)", "0.2)");
color = "rgba(206, 79, 81, 0.2)";
} else if (sanItem.sanTypeName === "关键和新型技术清单") {
color = "rgba(250, 140, 22, 0.2)";
}
return { return {
value: values, value: values,
name: sanItem.sanTypeName, name: sanItem.sanTypeName,
areaStyle: { color } itemStyle: { color: solidColor },
areaStyle: { color: areaColor }
}; };
}); });
...@@ -1272,7 +1244,14 @@ const fetchRadarData = async checked => { ...@@ -1272,7 +1244,14 @@ const fetchRadarData = async checked => {
// 更新雷达图配置 // 更新雷达图配置
radarOption.value.radar.indicator = indicators; radarOption.value.radar.indicator = indicators;
radarOption.value.series[0].data = seriesData; radarOption.value.series[0].data = seriesData;
radarOption.value.legend.data = data.map(item => item.sanTypeName); radarOption.value.legend.data = seriesData.map(item => {
return {
name: item.name,
itemStyle: {
color: item.itemStyle.color
}
};
});
} }
} catch (error) { } catch (error) {
console.error("获取雷达图数据失败:", error); console.error("获取雷达图数据失败:", error);
...@@ -1684,35 +1663,6 @@ const handleSanc = item => { ...@@ -1684,35 +1663,6 @@ const handleSanc = item => {
window.open(route.href, "_blank"); window.open(route.href, "_blank");
}; };
// // 获取热门法案
// const handleGetHotBills = async () => {
// try {
// const res = await getHotBills();
// console.log("热门法案", res);
// billList.value = res.data;
// } catch (error) {
// console.error(error);
// }
// };
// // 根据法案类型获取法案列表
// const handleGetBillsByType = async () => {
// const params = {
// type: activeHylyId.value
// };
// try {
// const res = await getBillsByType(params);
// console.log("根据法案类型获取法案列表", res);
// curBillList.value = res.data.map(item => {
// return {
// billId: item.billId,
// billName: item.billName,
// introductionDate: item.introductionDate,
// img: bill1
// };
// });
// } catch (error) {}
// };
// 查看更多风险信号 // 查看更多风险信号
const handleToMoreRiskSignal = () => { const handleToMoreRiskSignal = () => {
...@@ -3295,6 +3245,18 @@ const handleMediaClick = item => { ...@@ -3295,6 +3245,18 @@ const handleMediaClick = item => {
width: 1169px; width: 1169px;
padding: 0px 0 12px 0; padding: 0px 0 12px 0;
display: flex; display: flex;
position: relative;
&:not(:last-child)::after {
content: "";
position: absolute;
left: 111px; // 80px(time width) + 16px(margin) + 15px(30px img half)
top: 44px; // 14px(img margin-top) + 30px(img height)
bottom: -14px; // 延伸到下一个图标的顶部
width: 2px;
background-color: rgb(234, 236, 238);
z-index: 1;
}
// justify-content: flex-start; // justify-content: flex-start;
.time { .time {
......
...@@ -928,47 +928,47 @@ export const getMultipleLineChart = obj => { ...@@ -928,47 +928,47 @@ export const getMultipleLineChart = obj => {
export const getMultipleBarChart_m = object => { export const getMultipleBarChart_m = object => {
const list = _.chain(object.data).filter("year").orderBy("year", "asc").value(); const list = _.chain(object.data).filter("year").orderBy("year", "asc").value();
const colors = [ const colors = [
["rgba(45, 123, 248, 1)", "rgba(45, 123, 248, 0)"], ["rgba(45, 123, 248, 1)", "rgba(45, 123, 248, 0.1)"],
["rgba(206, 79, 81, 1)", "rgba(206, 79, 81, 0)"], ["rgba(206, 79, 81, 1)", "rgba(206, 79, 81, 0.1)"],
["rgba(255, 197, 61, 1)", "rgba(255, 197, 61, 0)"], ["rgba(255, 197, 61, 1)", "rgba(255, 197, 61, 0.1)"],
["rgba(255, 182, 193, 1)", "rgba(255, 182, 193, 0)"], ["rgba(255, 182, 193, 1)", "rgba(255, 182, 193, 0.1)"],
["rgba(159, 122, 234, 1)", "rgba(159, 122, 234, 0)"], ["rgba(159, 122, 234, 1)", "rgba(159, 122, 234, 0.1)"],
["rgba(90, 200, 220, 1)", "rgba(90, 200, 220, 0)"] ["rgba(90, 200, 220, 1)", "rgba(90, 200, 220, 0.1)"]
]; ];
const names = _.map(list, "year"); const names = _.map(list, "year");
const legendData = _.chain(object.domains)
.slice(0, 6)
.map((name, index) => {
return {
name: name,
itemStyle: {
color: colors[index % colors.length][0] // 强制图例使用实色
}
};
})
.value();
const datas = _.chain(object.domains) const datas = _.chain(object.domains)
.splice(0, 6) .slice(0, 6)
.map((name, index) => { .map((name, index) => {
// console.log(_.map(list, name)); const colorPair = colors[index % colors.length];
return { return {
name, name,
data: _.map(list, `domainNum.${name}`), data: _.map(list, `domainNum.${name}`),
type: "bar", type: "bar",
color: colors[index % colors.length][0], color: colorPair[0], // 图例使用实色
barWidth: 12, barWidth: 12,
itemStyle: { itemStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: colors[index % colors.length][0] }, { offset: 0, color: colorPair[0] }, // 顶部颜色
// { offset: 0.5, color: '#188df0' }, { offset: 1, color: colorPair[1] } // 底部颜色
{ offset: 1, color: colors[index % colors.length][1] }
]), ]),
borderRadius: [6, 6, 0, 0] borderRadius: [6, 6, 0, 0]
} }
}; };
}) })
.value(); .value();
// console.log("names", names);
let allValues = [];
datas.forEach(series => {
if (series.data) allValues.push(...series.data);
});
let maxVal = Math.max(...(allValues.length > 0 ? allValues : [0]));
// if (maxVal === 0) maxVal = 100;
// else maxVal = maxVal * 1.2;
// let interval = Math.ceil(maxVal / 5);
// if (interval > 5) interval = Math.ceil(interval / 10) * 10;
// maxVal = interval * 5;
const option = { const option = {
tooltip: { tooltip: {
...@@ -985,10 +985,19 @@ export const getMultipleBarChart_m = object => { ...@@ -985,10 +985,19 @@ export const getMultipleBarChart_m = object => {
containLabel: true containLabel: true
}, },
legend: { legend: {
// type: "scroll", icon: "circle",
// show: true, itemWidth: 12,
// orient: "horizontal", itemHeight: 12,
icon: "circle" data: legendData,
textStyle: {
fontSize: 16,
fontWeight: 400,
fontFamily: "Microsoft YaHei",
color: "rgb(95, 101, 108)",
lineHeight: 24,
verticalAlign: "middle",
padding: [2, 0, 0, 0] // 微调文字位置,使中线对齐
}
}, },
xAxis: { xAxis: {
type: "category", type: "category",
......
...@@ -126,7 +126,9 @@ ...@@ -126,7 +126,9 @@
> >
<img :src="item.imageUrl" alt="" /> <img :src="item.imageUrl" alt="" />
<div class="person-info"> <div class="person-info">
<div class="name">{{ item.name }}</div> <CommonPrompt :content="item.name">
<span class="name">{{ item.name }}</span>
</CommonPrompt>
<div class="title1">{{ item.position }}</div> <div class="title1">{{ item.position }}</div>
</div> </div>
</div> </div>
...@@ -168,6 +170,7 @@ import defaultIcon from "../../../../../assets/icons/default-avatar.png"; ...@@ -168,6 +170,7 @@ import defaultIcon from "../../../../../assets/icons/default-avatar.png";
import icon01 from "../../assets/icon01.png"; import icon01 from "../../assets/icon01.png";
import icon02 from "../../assets/icon02.png"; import icon02 from "../../assets/icon02.png";
import { ArrowDown } from "@element-plus/icons-vue"; import { ArrowDown } from "@element-plus/icons-vue";
import CommonPrompt from "../../../../../commonPrompt/index.vue";
import { getEntityInfo, getPublishInfo, getPublishOrgInfo, getEntityUpdateInfo } from "@/api/exportControlV2.0.js"; import { getEntityInfo, getPublishInfo, getPublishOrgInfo, getEntityUpdateInfo } from "@/api/exportControlV2.0.js";
// 处理点击发布机构的方法 // 处理点击发布机构的方法
...@@ -364,11 +367,13 @@ const handleLoadMoreDynamic = () => { ...@@ -364,11 +367,13 @@ const handleLoadMoreDynamic = () => {
// 获取实体清单基本信息 // 获取实体清单基本信息
const entityInfo = ref({}); const entityInfo = ref({});
const emit = defineEmits(['update-entity-info']);
const getEntityInfoFn = async () => { const getEntityInfoFn = async () => {
try { try {
const res = await getEntityInfo(); const res = await getEntityInfo("el");
if (res && res.code === 200) { if (res && res.code === 200) {
entityInfo.value = res.data; entityInfo.value = res.data;
emit('update-entity-info', res.data);
} }
} catch (error) { } catch (error) {
console.error("获取实体清单基本信息失败:", error); console.error("获取实体清单基本信息失败:", error);
...@@ -637,19 +642,19 @@ onMounted(() => { ...@@ -637,19 +642,19 @@ onMounted(() => {
} }
} }
.key-person-list { .key-person-list {
display: flex; display: grid;
flex-wrap: wrap; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
column-gap: 40px;
padding-left: 28px;
.person-item { .person-item {
width: 185px; width: 100%;
cursor: pointer; cursor: pointer;
display: flex; display: flex;
align-items: center; align-items: flex-start;
margin-bottom: 16px; margin-bottom: 16px;
&:nth-child(2n-1) { min-width: 0;
margin-left: 28px;
margin-right: 39px;
}
img { img {
width: 48px; width: 48px;
height: 48px; height: 48px;
...@@ -659,13 +664,20 @@ onMounted(() => { ...@@ -659,13 +664,20 @@ onMounted(() => {
flex-shrink: 0; flex-shrink: 0;
} }
.person-info { .person-info {
flex: 1;
min-width: 0;
overflow: hidden;
.name { .name {
display: block;
font-size: 16px; font-size: 16px;
font-weight: 700; font-weight: 700;
font-family: "Microsoft YaHei"; font-family: "Microsoft YaHei";
color: rgb(59, 65, 75); color: rgb(59, 65, 75);
margin-bottom: 1px; margin-bottom: 1px;
white-space: nowrap; white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
} }
.title1 { .title1 {
font-size: 16px; font-size: 16px;
...@@ -673,7 +685,7 @@ onMounted(() => { ...@@ -673,7 +685,7 @@ onMounted(() => {
font-family: "Microsoft YaHei"; font-family: "Microsoft YaHei";
color: rgb(95, 101, 108); color: rgb(95, 101, 108);
line-height: 1.2; line-height: 1.2;
// white-space: nowrap; word-break: break-all;
} }
} }
} }
......
...@@ -7,17 +7,19 @@ ...@@ -7,17 +7,19 @@
</div> </div>
</div> </div>
<div class="content-box"> <div class="content-box">
<introductionPage v-if="activeIndex === 0"></introductionPage> <introductionPage v-if="activeIndex === 0" @update-entity-info="(data) => $emit('update-entity-info', data)"></introductionPage>
<listPage v-if="activeIndex === 1"></listPage> <listPage v-if="activeIndex === 1"></listPage>
</div> </div>
</div> </div>
</template> </template>
<script setup> <script setup>
import { ref } from 'vue' import { ref, defineEmits } from 'vue'
import introductionPage from "./components/introductionPage/index.vue" import introductionPage from "./components/introductionPage/index.vue"
import listPage from "./components/listPage/index.vue" import listPage from "./components/listPage/index.vue"
const emit = defineEmits(['update-entity-info'])
const activeTab = ref(["实体清单简介", "实体清单列表"]) const activeTab = ref(["实体清单简介", "实体清单列表"])
const activeIndex = ref(0) const activeIndex = ref(0)
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
</div> </div>
</div> </div>
<div class="main"> <div class="main">
<sanctions-overview v-if="activeIndex === 0"></sanctions-overview> <sanctions-overview v-if="activeIndex === 0" @update-entity-info="handleUpdateEntityInfo"></sanctions-overview>
<data-statistics v-if="activeIndex === 1"></data-statistics> <data-statistics v-if="activeIndex === 1"></data-statistics>
<deep-mining v-if="activeIndex === 2"></deep-mining> <deep-mining v-if="activeIndex === 2"></deep-mining>
<impact-analysis v-if="activeIndex === 3"></impact-analysis> <impact-analysis v-if="activeIndex === 3"></impact-analysis>
...@@ -60,12 +60,25 @@ import icon3Active from "../assets/icons/icon3_active.png"; ...@@ -60,12 +60,25 @@ import icon3Active from "../assets/icons/icon3_active.png";
const headerTitle = ref({ const headerTitle = ref({
img: title, // img: title,
title: "实体清单", // title: "实体清单",
titleEn: "Entity List", // titleEn: "Entity List",
department: "美国商务部工业与安全局" // department: "美国商务部工业与安全局"
}) })
const handleUpdateEntityInfo = (data) => {
if (data) {
headerTitle.value = {
...headerTitle.value,
title: data.name,
titleEn: data.originalName,
department: data.orgName,
departId: data.orgId,
img: data.orgLogoUrl || title
}
}
}
const activeIndex = ref(0) const activeIndex = ref(0)
const headerNavList = ref([ const headerNavList = ref([
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论