提交 52826e66 authored 作者: yanpeng's avatar yanpeng

Merge branch 'master' into yp-dev

......@@ -35,3 +35,15 @@ export function getDecreeOrganization(params) {
params
})
}
// 获取全局信息
/**
* @param {id}
*/
export function getDecreeSummary(params) {
return request({
method: 'GET',
url: `/api/administrativeOrderInfo/summary/${params.id}`,
params
})
}
\ No newline at end of file
......@@ -95,3 +95,38 @@ export function getProcessSummary(params) {
params,
})
}
// 获取党派政治献金
/**
* @param {id, personCongress}
*/
export function getBillPoliContribution(params) {
return request({
method: 'GET',
url: `/api/billDeepDive/processAnalyze/totalxj/${params.id}`,
params
})
}
// 获取主要议员政治献金
/**
* @param {id, personCongress}
*/
export function getBillMainPoliContribution(params) {
return request({
method: 'GET',
url: `/api/billDeepDive/processAnalyze/xj/${params.id}`,
params
})
}
// 根据法案ID获取人员政治献金来源及行业领域分布
/**
* @param {id, personId}
*/
export function getBillPersonPoliContribution(params) {
return request({
method: 'GET',
url: `/api/billDeepDive/processAnalyze/xj/${params.id}/${params.personId}`
})
}
......@@ -31,3 +31,16 @@ export function getHylyList() {
url: `/api/billImpactAnalysis/industry/hylyList`,
})
}
// 获取公司详情
/**
* @param {billId,companyId,id}
*/
export function getCompanyDetail(params) {
return request({
method: 'GET',
url: `/api/billImpactAnalysis/industry/companyDetail/${params.billId}/${params.id}/${params.companyId}`,
params,
})
}
\ No newline at end of file
......@@ -10,6 +10,15 @@ export function getThinkTankList() {
})
}
//智库概览:获取智库发布
export function getNewReport() {
return request({
method: 'GET',
url: `/api/thinkTankOverview/newReport`,
})
}
// 风险信号
export function getThinkTankRiskSignal() {
return request({
......@@ -20,10 +29,10 @@ export function getThinkTankRiskSignal() {
}
// 政策建议趋势分布
export function getThinkTankPolicyIndustryChange() {
export function getThinkTankPolicyIndustryChange(params) {
return request({
method: 'GET',
url: `/api/thinkTankOverview/policyIndustryChange`,
url: `/api/thinkTankOverview/policyIndustryChange/${params}`,
})
}
......@@ -45,3 +54,188 @@ export function getThinkTankDonation() {
})
}
//智库概览:获取智库研究热点
export function getThinkTankHot(params) {
return request({
method: 'GET',
url: `/api/thinkTankOverview/research/hot/${params}`,
})
}
// 行业领域字典列表
export function getHylyList() {
return request({
method: 'GET',
url: `/api/billImpactAnalysis/industry/hylyList`,
})
}
//获取智库报告
export function getThinkTankReport(params) {
return request({
method: 'GET',
url: `/api/thinkTankOverview/report`,
params: params
})
}
/********* 智库信息 */
//智库百科:获取全局信息
export function getThinkTankSummary(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/summary/${params.id}`,
})
}
//智库报告:获取智库报告类型
export function getThinkDynamicsReportType() {
return request({
method: 'GET',
url: `/api/thinkTankInfo/reportType`,
})
}
//智库动态:获取智库报告
export function getThinkDynamicsReport(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/report/${params.id}/${params.startDate}`,
params: params.parmas
})
}
//提出建议领域分布
export function getThinkPolicyIndustry(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/policyIndustry/${params.id}/${params.year}`,
})
}
//获取相关政策领域分布
export function getThinkPolicyIndustryTotal(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/policyIndustryTotal/${params.id}/${params.year}`,
})
}
//获取热门研究方向变化趋势
export function getThinkPolicyIndustryChange(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/policyIndustryChange/${params.id}/${params.year}`,
})
}
//获取智库政策
export function getThinkPolicy(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/policy/${params.id}/${params.startDate}`,
params
})
}
//智库百科基本信息
export function getThinkTankInfoBasic(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/basic/${params}`,
})
}
//获取全球分支机构
export function getThinkTankInfoBranch(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/branch/${params}`,
})
}
//获取经费来源统计
export function getThinkTankFundsTotal(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/fundsTotal/${params}`,
})
}
//获取经费来源
export function getThinkTankFundsSource(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/fundsSource/${params}`,
})
}
//获取研究领域演变
export function getThinkTankResearchAreae(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/researchArea/${params}`,
})
}
//获取核心研究人员
export function getThinkTankPerson(params) {
return request({
method: 'GET',
url: `/api/thinkTankInfo/person/${params}`,
})
}
//获取报告内容摘要
export function getThinkTankReportAbstract(params) {
return request({
method: 'GET',
url: `/api/thinkTankReport/abstract/${params}`,
})
}
//获取报告主要观点
export function getThinkTankReportContent(params) {
return request({
method: 'GET',
url: `/api/thinkTankReport/content/${params}`,
})
}
//获取涉及科技领域
export function getThinkTankReportIndustry(params) {
return request({
method: 'GET',
url: `/api/thinkTankReport/industry/${'Rand_RRA3572-1'}`,
})
}
//获取科技领域词云
export function getThinkTankReportIndustryCloud(params) {
return request({
method: 'GET',
url: `/api/thinkTankReport/industry/${params.id}/${params.industryId}`,
})
}
//获取政策建议落实情况
export function getThinkTankReportPolicy(params) {
return request({
method: 'GET',
url: `/api/thinkTankReport/policy/${params}`,
})
}
//获取相关政策动态
export function getThinkTankReportPolicyAction(params) {
return request({
method: 'GET',
url: `/api/thinkTankReport/policyAction/${params}`,
})
}
......@@ -2523,6 +2523,7 @@ onUnmounted(() => {});
font-size: 14px;
font-weight: 400;
line-height: 22px;
overflow: hidden;
}
}
.right-footer {
......@@ -2606,6 +2607,7 @@ onUnmounted(() => {});
img {
width: 100%;
height: 100%;
border-radius: 50%;
}
}
.right {
......
......@@ -212,7 +212,7 @@ onMounted(() => {
height: 1016px;
background: rgba(249, 250, 252, 1);
position: relative;
margin: 0 auto;
// margin: 0 auto;
.layout-header {
width: 1920px;
height: 64px;
......
......@@ -6,8 +6,12 @@
<div class="icon"></div>
<div class="title">{{ "主要议员" }}</div>
<div class="btn-box">
<div class="btn" :class="{ btnActive: activeBtnIndex === 0 }">{{ "参议院" }}</div>
<div class="btn" :class="{ btnActive: activeBtnIndex === 1 }">{{ "众议院" }}</div>
<div class="btn" :class="{ btnActive: activeBtnIndex === 0 }" @click="activeBtnIndex = 0">
{{ "参议院" }}
</div>
<div class="btn" :class="{ btnActive: activeBtnIndex === 1 }" @click="activeBtnIndex = 1">
{{ "众议院" }}
</div>
</div>
<div class="header-right">
<div class="right-icon">
......@@ -20,7 +24,7 @@
</div>
<div class="box1-main">
<div class="box1-main-top">
<div class="top-item" v-for="(item, index) in majorList[activeBtnIndex].data1" :key="index">
<div class="top-item" v-for="(item, index) in partyContributionList" :key="index">
<div class="icon">
<img :src="item.img" alt="" />
</div>
......@@ -33,28 +37,29 @@
<div
class="item"
:class="{ itemActive: itemActiveIndex === index }"
v-for="(item, index) in majorList[activeBtnIndex].data2"
v-for="(item, index) in mainPoliContribution"
:key="index"
@click="handlePersonClick(item, index)"
>
<div class="item-left">
<img :src="item.img" alt="" />
<img :src="item.image || Img1" alt="" />
</div>
<div class="item-center">
<div class="center-top">
<div class="name">{{ item.name }}</div>
<div class="icon1">
<img :src="item.dangpai" alt="" />
<img :src="item.dp === 'Republican' ? Ghd : Mzd" alt="" />
</div>
<div class="icon2">
<img :src="item.yuanbie" alt="" />
<img :src="activeBtnIndex === 0 ? Cyy : Zyy" alt="" />
</div>
</div>
<div class="center-footer">
{{ item.zhiwei }}
{{ item.zw }}
</div>
</div>
<div class="item-right">
{{ item.num }}
{{ item.formattedTotalJe }}
</div>
</div>
</div>
......@@ -67,6 +72,9 @@
<div class="icon"></div>
<div class="title">{{ "政治献金流向" }}</div>
<div class="header-right">
<div class="more-btn" v-if="fullSourceList.length > 5" @click="toggleSankeyData">
{{ showAllSankeyData ? '收起' : '更多+' }}
</div>
<div class="right-icon">
<img src="@/assets/icons/box-header-icon1.png" alt="" />
</div>
......@@ -84,9 +92,7 @@
<img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div>
<div class="box-footer-center">
{{
"马尔科·卢比奥的政治资金主要依赖于一个由亿万富翁、特定行业利益集团及通过​“超级政治行动委员会”​​ 运作的大额捐款网络。"
}}
{{ currentPersonName }}的政治资金主要依赖于一个由亿万富翁、特定行业利益集团及通过​“超级政治行动委员会”​​ 运作的大额捐款网络。
</div>
<div class="box-footer-right">
<img src="@/assets/icons/box-footer-right-icon.png" alt="" />
......@@ -116,7 +122,7 @@
<div class="id">{{ index + 1 }}</div>
<div class="name">{{ item.name }}</div>
<div class="line">
<div class="inner-line" :style="{width: (item.num / areaList[0].num)* 100 + '%' }"></div>
<div class="inner-line" :style="{ width: (item.num / areaList[0].num) * 100 + '%' }"></div>
</div>
<div class="num">{{ item.numtext }}</div>
<div class="more">{{ `${item.insNum}家机构 >` }}</div>
......@@ -128,9 +134,7 @@
<img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div>
<div class="box-footer-center">
{{
"马尔科·卢比奥的政治资金主要依赖于一个由亿万富翁、特定行业利益集团及通过​“超级政治行动委员会”​​ 运作的大额捐款网络。"
}}
{{ currentPersonName }}的政治资金主要依赖于一个由亿万富翁、特定行业利益集团及通过​“超级政治行动委员会”​​ 运作的大额捐款网络。
</div>
<div class="box-footer-right">
<img src="@/assets/icons/box-footer-right-icon.png" alt="" />
......@@ -142,12 +146,13 @@
</template>
<script setup>
import { ref, onMounted } from "vue";
import { ref, onMounted, watch, computed } from "vue";
import { getBillPoliContribution, getBillMainPoliContribution, getBillPersonPoliContribution } from "@/api/deepdig";
import setChart from "@/utils/setChart";
import getPieChart from "./utils/piechart";
import getSankeyChart from "./utils/sankey"
import getSankeyChart from "./utils/sankey";
import Img1 from "./assets/images/1.png";
import Img2 from "./assets/images/2.png";
......@@ -168,196 +173,474 @@ import Mzd from "@/assets/icons/mzd.png";
const activeBtnIndex = ref(0);
const itemActiveIndex = ref(0);
const majorList = ref([
{
name: "参议院",
data1: [
const currentPersonName = computed(() => {
if (mainPoliContribution.value && mainPoliContribution.value[itemActiveIndex.value]) {
return mainPoliContribution.value[itemActiveIndex.value].name;
}
return "";
});
// const majorList = ref([
// {
// name: "参议院",
// data1: [
// {
// name: "共和党",
// img: Ghd,
// num: "$1,550,000"
// },
// {
// name: "民主党",
// img: Mzd,
// num: "$298,000"
// }
// ],
// data2: [
// {
// img: Img1,
// name: "马尔科·卢比奥",
// dangpai: Ghd,
// yuanbie: Cyy,
// zhiwei: "众议院预算委员会主席",
// num: "$1,550,000"
// },
// {
// img: Img2,
// name: "史蒂夫·戴恩斯",
// dangpai: Ghd,
// yuanbie: Cyy,
// zhiwei: "众议院预算委员会主席",
// num: "$820,000"
// },
// {
// img: Img3,
// name: "伯尼·莫雷诺",
// dangpai: Ghd,
// yuanbie: Cyy,
// zhiwei: "众议院预算委员会主席",
// num: "$50,000"
// },
// {
// img: Img4,
// name: "戴夫·麦考密克",
// dangpai: Ghd,
// yuanbie: Cyy,
// zhiwei: "众议院预算委员会主席",
// num: "$50,000"
// },
// {
// img: Img5,
// name: "蒂姆·希伊",
// dangpai: Ghd,
// yuanbie: Cyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// },
// {
// img: Img6,
// name: "史蒂夫·戴恩斯",
// dangpai: Ghd,
// yuanbie: Cyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// },
// {
// img: Img7,
// name: "皮特·赫格塞思",
// dangpai: Ghd,
// yuanbie: Cyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// },
// {
// img: Img8,
// name: "安妮·海瑟薇",
// dangpai: Ghd,
// yuanbie: Cyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// },
// {
// img: Img9,
// name: "贾米森·格里尔",
// dangpai: Ghd,
// yuanbie: Cyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// },
// {
// img: Img10,
// name: "迈克·华尔兹",
// dangpai: Ghd,
// yuanbie: Cyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// }
// ]
// },
// {
// name: "众议院",
// data1: [
// {
// name: "共和党",
// img: Ghd,
// num: "$1,550,000"
// },
// {
// name: "民主党",
// img: Mzd,
// num: "$298,000"
// }
// ],
// data2: [
// {
// img: Img1,
// name: "马尔科·卢比奥",
// dangpai: Ghd,
// yuanbie: Zyy,
// zhiwei: "众议院预算委员会主席",
// num: "$1,550,000"
// },
// {
// img: Img2,
// name: "史蒂夫·戴恩斯",
// dangpai: Ghd,
// yuanbie: Zyy,
// zhiwei: "众议院预算委员会主席",
// num: "$820,000"
// },
// {
// img: Img3,
// name: "伯尼·莫雷诺",
// dangpai: Ghd,
// yuanbie: Zyy,
// zhiwei: "众议院预算委员会主席",
// num: "$50,000"
// },
// {
// img: Img4,
// name: "戴夫·麦考密克",
// dangpai: Ghd,
// yuanbie: Zyy,
// zhiwei: "众议院预算委员会主席",
// num: "$50,000"
// },
// {
// img: Img5,
// name: "蒂姆·希伊",
// dangpai: Ghd,
// yuanbie: Zyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// },
// {
// img: Img6,
// name: "史蒂夫·戴恩斯",
// dangpai: Ghd,
// yuanbie: Zyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// },
// {
// img: Img7,
// name: "皮特·赫格塞思",
// dangpai: Ghd,
// yuanbie: Zyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// },
// {
// img: Img8,
// name: "安妮·海瑟薇",
// dangpai: Ghd,
// yuanbie: Zyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// },
// {
// img: Img9,
// name: "贾米森·格里尔",
// dangpai: Ghd,
// yuanbie: Zyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// },
// {
// img: Img10,
// name: "迈克·华尔兹",
// dangpai: Ghd,
// yuanbie: Zyy,
// zhiwei: "众议院预算委员会主席",
// num: "$35,000"
// }
// ]
// }
// ]);
const chart1Data = ref();
const areaList = ref([]);
const chart2Data = ref([]);
const chart2ColorList = ref(["#4096FF", "#FFA39E", "#ADC6FF", "#FFC069", "#B5F5EC", "#B37FEB", "#D6E4FF"]);
const sankeyColors = [
"#5470c6",
"#91cc75",
"#fac858",
"#ee6666",
"#73c0de",
"#3ba272",
"#fc8452",
"#9a60b4",
"#ea7ccc",
"#a2c0f1",
"#f596aa",
"#e6b422",
"#4b2c20"
];
const partyContributionList = ref([
{
name: "共和党",
img: Ghd,
num: "$1,550,000"
num: "$0"
},
{
name: "民主党",
img: Mzd,
num: "$298,000"
num: "$0"
}
],
data2: [
{
img: Img1,
name: "马尔科·卢比奥",
dangpai: Ghd,
yuanbie: Cyy,
zhiwei: "众议院预算委员会主席",
num: "$1,550,000"
},
{
img: Img2,
name: "史蒂夫·戴恩斯",
dangpai: Ghd,
yuanbie: Cyy,
zhiwei: "众议院预算委员会主席",
num: "$820,000"
},
{
img: Img3,
name: "伯尼·莫雷诺",
dangpai: Ghd,
yuanbie: Cyy,
zhiwei: "众议院预算委员会主席",
num: "$50,000"
},
{
img: Img4,
name: "戴夫·麦考密克",
dangpai: Ghd,
yuanbie: Cyy,
zhiwei: "众议院预算委员会主席",
num: "$50,000"
},
{
img: Img5,
name: "蒂姆·希伊",
dangpai: Ghd,
yuanbie: Cyy,
zhiwei: "众议院预算委员会主席",
num: "$35,000"
},
{
img: Img6,
name: "史蒂夫·戴恩斯",
dangpai: Ghd,
yuanbie: Cyy,
zhiwei: "众议院预算委员会主席",
num: "$35,000"
},
{
img: Img7,
name: "皮特·赫格塞思",
dangpai: Ghd,
yuanbie: Cyy,
zhiwei: "众议院预算委员会主席",
num: "$35,000"
},
{
img: Img8,
name: "安妮·海瑟薇",
dangpai: Ghd,
yuanbie: Cyy,
zhiwei: "众议院预算委员会主席",
num: "$35,000"
},
{
img: Img9,
name: "贾米森·格里尔",
dangpai: Ghd,
yuanbie: Cyy,
zhiwei: "众议院预算委员会主席",
num: "$35,000"
},
{
img: Img10,
name: "迈克·华尔兹",
dangpai: Ghd,
yuanbie: Cyy,
zhiwei: "众议院预算委员会主席",
num: "$35,000"
]);
// 获取党派政治献金
const poliContribution = ref();
const getPoliContribution = async () => {
const currentType = activeBtnIndex.value === 0 ? "参议院" : "众议院";
const params = {
id: window.sessionStorage.getItem("billId"),
personCongress: currentType
};
try {
const res = await getBillPoliContribution(params);
if (res.code === 200) {
poliContribution.value = res.data;
// 重置为默认值
partyContributionList.value = [
{ name: "共和党", img: Ghd, num: "$0" },
{ name: "民主党", img: Mzd, num: "$0" }
];
if (res.data && res.data.length > 0) {
res.data.forEach(item => {
const totalAmount = item.totalJe || 0;
if (item.dp === "Republican") {
partyContributionList.value[0].num = `$${totalAmount.toLocaleString()}`;
} else {
partyContributionList.value[1].num = `$${totalAmount.toLocaleString()}`;
}
]
});
} else {
partyContributionList.value[0].num = "$0";
partyContributionList.value[1].num = "$0";
}
]);
} else {
partyContributionList.value = [
{ name: "共和党", img: Ghd, num: "$0" },
{ name: "民主党", img: Mzd, num: "$0" }
];
}
} catch (error) {
partyContributionList.value = [
{ name: "共和党", img: Ghd, num: "$0" },
{ name: "民主党", img: Mzd, num: "$0" }
];
}
};
const chart1Data = ref(
watch(activeBtnIndex, () => {
itemActiveIndex.value = 0;
getPoliContribution();
getMainPoliContribution();
});
)
// 获取主要议员政治献金
const mainPoliContribution = ref();
const clearPersonDetails = () => {
personPoliContribution.value = null;
fullSourceList.value = [];
renderSankeyChart();
const areaList = ref([
{
name: "半导体",
num: 186000,
numtext: "$186,000",
insNum: 8
},
{
name: "电子设备",
num: 180000,
numtext: "$180,000",
insNum: 5
},
{
name: "显示技术",
num: 171000,
numtext: "$171,000",
insNum: 2
},
{
name: "新能源",
num: 75000,
numtext: "$75,000",
insNum: 3
},
{
name: "通信设备",
num: 70000,
numtext: "$70,000",
insNum: 2
},
{
name: "汽车",
num: 52000,
numtext: "$52,000",
insNum: 2
},
{
name: "其他",
num: 36000,
numtext: "$36,000",
insNum: 1
chart2Data.value = [];
areaList.value = [];
let chart2 = getPieChart([], chart2ColorList.value);
setChart(chart2, "chart2");
};
const getMainPoliContribution = async () => {
const currentType = activeBtnIndex.value === 0 ? "参议院" : "众议院";
const params = {
id: window.sessionStorage.getItem("billId"),
personCongress: currentType
};
try {
const res = await getBillMainPoliContribution(params);
// 打印主要议员政治献金
console.log("主要议员政治献金:", res);
if (res.code === 200) {
mainPoliContribution.value = res.data.map(item => ({
...item,
formattedTotalJe: `$${(item.totalJe || 0).toLocaleString()}`
}));
// 默认选中第一个人
if (mainPoliContribution.value.length > 0) {
handlePersonClick(mainPoliContribution.value[0], 0);
} else {
clearPersonDetails();
}
]);
} else {
mainPoliContribution.value = [];
clearPersonDetails();
}
} catch (error) {
mainPoliContribution.value = [];
clearPersonDetails();
}
};
const chart2Data = ref([
{
name: "半导体",
value: 50
},
{
name: "电子设备",
value: 46
},
{
name: "显示技术",
value: 40
},
{
name: "新能源",
value: 32
},
{
name: "通信设备",
value: 31
},
// Sankey data state
const fullSourceList = ref([]);
const showAllSankeyData = ref(false);
const renderSankeyChart = () => {
const sourceList = showAllSankeyData.value ? fullSourceList.value : fullSourceList.value.slice(0, 5);
if (sourceList.length > 0) {
const currentPerson = mainPoliContribution.value[itemActiveIndex.value];
const personName = currentPerson ? currentPerson.name : "Person";
const totalAmount = sourceList.reduce((sum, item) => sum + (item.amount || 0), 0);
const nodes = [
{
name: "汽车",
value: 30
name: personName,
value: totalAmount,
label: { position: 'left' },
itemStyle: {
color: '#FF1493'
}
},
{
name: "其他",
value: 24
...sourceList.map((item, index) => ({
name: item.orgName,
value: item.amount,
itemStyle: {
color: sankeyColors[index % sankeyColors.length]
}
]);
}))
];
const chart2ColorList = ref(["#4096FF", "#FFA39E", "#ADC6FF", "#FFC069", "#B5F5EC", "#B37FEB", "#D6E4FF"]);
const links = sourceList.map(item => ({
source: item.orgName,
target: personName,
value: item.amount
}));
onMounted(() => {
let chart1 = getSankeyChart()
setChart(chart1, 'chart1')
let chart1 = getSankeyChart(nodes, links);
setChart(chart1, "chart1");
} else {
let chart1 = getSankeyChart([], []);
setChart(chart1, "chart1");
}
};
const toggleSankeyData = () => {
showAllSankeyData.value = !showAllSankeyData.value;
renderSankeyChart();
};
// 获取人员政治献金来源及行业领域分布
const personPoliContribution = ref();
const getPersonPoliContribution = async (personId) => {
if (!personId) return;
const params = {
id: window.sessionStorage.getItem("billId"),
personId: personId
};
try {
const res = await getBillPersonPoliContribution(params);
// 打印人员政治献金
console.log("人员政治献金:", res);
if (res.code === 200 && res.data) {
personPoliContribution.value = res.data;
fullSourceList.value = res.data.sourceList || [];
showAllSankeyData.value = false; // Reset to default (top 5)
renderSankeyChart();
// Update Industry List (Chart 2 and List)
const industries = res.data.industryList || [];
// Update Chart 2 Data
chart2Data.value = industries.map(item => ({
name: item.industryName,
value: item.amount
}));
// Re-render Chart 2
let chart2 = getPieChart(chart2Data.value, chart2ColorList.value);
setChart(chart2, "chart2");
// Update List Data
// Sort by amount desc to ensure first item is max for progress bar
const sortedIndustries = [...industries].sort((a, b) => (b.amount || 0) - (a.amount || 0));
areaList.value = sortedIndustries.map(item => ({
name: item.industryName,
num: item.amount,
numtext: `$${(item.amount || 0).toLocaleString()}`,
insNum: item.orgNum
}));
} else {
personPoliContribution.value = [];
fullSourceList.value = [];
renderSankeyChart();
chart2Data.value = [];
areaList.value = [];
let chart2 = getPieChart([], chart2ColorList.value);
setChart(chart2, "chart2");
}
} catch (error) {
console.error(error);
personPoliContribution.value = [];
fullSourceList.value = [];
renderSankeyChart();
chart2Data.value = [];
areaList.value = [];
let chart2 = getPieChart([], chart2ColorList.value);
setChart(chart2, "chart2");
}
};
const handlePersonClick = (item, index) => {
itemActiveIndex.value = index;
if (item && item.personid) {
getPersonPoliContribution(item.personid);
}
};
onMounted(() => {
getPoliContribution();
getMainPoliContribution();
let chart1 = getSankeyChart();
setChart(chart1, "chart1");
let chart2 = getPieChart(chart2Data.value, chart2ColorList.value);
setChart(chart2, "chart2");
});
</script>
......@@ -405,6 +688,7 @@ onMounted(() => {
border-radius: 4px;
background: var(--btn-plain-bg-color);
border: 1px solid var(--btn-plain-border-color);
cursor: pointer;
}
.btnActive {
color: var(--btn-active-text-color);
......@@ -417,10 +701,19 @@ onMounted(() => {
right: 12px;
top: 14px;
display: flex;
gap: 4px;
gap: 16px;
.more-btn {
color: rgba(5, 95, 194, 1);
font-size: 14px;
cursor: pointer;
margin-top: 2px;
&:hover {
opacity: 0.8;
}
}
.right-icon {
width: 28px;
height: 28px;
width: 24px;
height: 24px;
img {
width: 100%;
height: 100%;
......@@ -551,6 +844,7 @@ onMounted(() => {
margin-top: 6px;
width: 498px;
height: 640px;
overflow: auto;
.item {
display: flex;
position: relative;
......@@ -672,7 +966,7 @@ onMounted(() => {
.box3-main-right {
width: 518px;
margin-left: 10px;
overflow: hidden;
overflow: auto;
.box3-main-right-item {
height: 60px;
width: 518px;
......
......@@ -14,14 +14,19 @@ const getPieChart = (data,colorList) => {
},
label: {
alignTo: 'edge',
formatter: '{name|{b}}\n{time|{c} 条 {d}%}',
formatter: '{name|{b}}\n{time|{d}%}',
minMargin: 5,
edgeDistance: 10,
lineHeight: 15,
rich: {
time: {
fontSize: 10,
color: '#999'
fontSize: 12,
color: '#666'
},
name: {
fontSize: 14,
color: '#333',
fontWeight: 'bold'
}
}
},
......
const getSankeyChart = () => {
const getSankeyChart = (data = [], links = []) => {
const option = {
tooltip: {
trigger: 'item',
triggerOn: 'mousemove'
},
series: {
type: 'sankey',
layout: 'none',
left: '5%',
right: '5%',
left: '1%',
right: '1%',
top: '5%',
bottom: '5%',
emphasis: {
focus: 'adjacency'
},
nodeWidth: 50,
nodeGap: 2,
layoutIterations: 32,
lineStyle: {
color: 'source',
curveness: 0.5
},
label: {
show: true,
formatter: function (params) {
return `${params.name} $${params.value}`;
return `${params.name} $${params.value.toLocaleString()}`;
},
position: 'right',
textStyle: {
fontSize: '16px',
fontSize: 16,
color: '#555'
}
},
data: [
{
name: '马尔科·卢比奥',
label: {
position: 'left'
}
},
{
name: '成长俱乐部'
},
{
name: '埃利奥特管理公司'
},
{
name: '高盛集团'
},
{
name: '黑石集团'
},
{
name: '佛罗里达水晶'
},
{
name: '美国银行'
}
],
links: [
{
source: '成长俱乐部',
target: '马尔科·卢比奥',
value: 680751
},
{
source: '埃利奥特管理公司',
target: '马尔科·卢比奥',
value: 440120
},
{
source: '高盛集团',
target: '马尔科·卢比奥',
value: 371517
},
{
source: '黑石集团',
target: '马尔科·卢比奥',
value: 259321
},
{
source: '佛罗里达水晶',
target: '马尔科·卢比奥',
value: 203775
},
{
source: '美国银行',
target: '马尔科·卢比奥',
value: 150892
}
]
data: data,
links: links
}
};
......
......@@ -95,58 +95,117 @@
<div class="box3-main-center-header-box6">关键议员</div>
</div>
<div class="box3-main-center-content">
<div class="box3-main-center-content-box">
<div class="item" v-for="(item, index) in voteAnalysisList1" :key="index">
<div class="box3-main-center-content-box" v-for="item in voteAnalysisList" :key="item.actionId">
<div class="item">
<div class="item-box1">
<div class="box1-left">
<div class="icon" v-if="item.nameIcon">
<img :src="item.nameIcon" alt="" />
</div>
<div style="height: 80px;">
<div class="name" :class="{ nameBlod: item.nameBold }">
{{ item.name }}
<div style="width: 100%; display: flex; flex-direction: column; align-items: flex-end;">
<div class="name nameBlod" :title="item.actionTitle" style="white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%;">
{{ item.actionTitle }}
</div>
<div class="time">
{{ item.time }}
{{ formatDate(item.actionDate) }}
</div>
</div>
</div>
<div class="box1-right">
<div class="box1-right-top">
<el-progress :percentage="item.supportRate" :show-text="false"> </el-progress>
<el-progress :percentage="Number(item.agreePercent)" :show-text="false" color="#1677FF"> </el-progress>
</div>
<div class="box1-right-bottom">
<el-progress :percentage="item.againistRate" :show-text="false"> </el-progress>
<el-progress :percentage="Number(item.againstPercent)" :show-text="false" color="#FF9054"> </el-progress>
</div>
</div>
</div>
<div class="item-box2">
<div class="box2-1">{{ item.support + "票" }}</div>
<div class="box2-2">{{ item.againist + "票" }}</div>
<div class="box2-1" style="color: #1677FF">{{ item.agreeCount + "票" }}</div>
<div class="box2-2" style="color: #FF9054">{{ item.againstCount + "票" }}</div>
</div>
<div class="item-box3">
<div class="box3-1">{{ item.supportRank }}</div>
<div class="box3-2">{{ item.againistRank }}</div>
<div class="box3-1"></div>
<div class="box3-2"></div>
</div>
<div class="item-box4">
<div class="box4-1">{{ item.supportRate + "%" }}</div>
<div class="box4-2">{{ item.againistRate + "%" }}</div>
<div class="box4-1" style="color: #1677FF">{{ item.agreePercent + "%" }}</div>
<div class="box4-2" style="color: #FF9054">{{ item.againstPercent + "%" }}</div>
</div>
<div class="item-box5"></div>
<div class="item-box6">
<el-icon size="20" color="#555"><ArrowDownBold /></el-icon>
</div>
</div>
<div class="item">
<div class="item-box1">
<div class="box1-left">
<div class="icon">
<img :src="MZD" alt="" />
</div>
<div class="name">民主党</div>
</div>
<div class="box1-right">
<div class="box1-right-top">
<el-progress :percentage="Number(item.dagreePercent)" :show-text="false" color="#85b4ff"> </el-progress>
</div>
<div class="box1-right-bottom">
<el-progress :percentage="Number(item.dagainstPercent)" :show-text="false" color="#FF9054"> </el-progress>
</div>
</div>
</div>
<div class="item-box2">
<div class="box2-1" style="color: #1677FF">{{ item.dagreeCount + "票" }}</div>
<div class="box2-2" style="color: #FF9054">{{ item.dagainstCount + "票" }}</div>
</div>
<div class="item-box3"></div>
<div class="item-box4">
<div class="box4-1" style="color: #1677FF">{{ item.dagreePercent + "%" }}</div>
<div class="box4-2" style="color: #FF9054">{{ item.dagainstPercent + "%" }}</div>
</div>
<div class="item-box5">
<div class="box5-1" v-if="item.people">{{ item.people+' 人' }}</div>
<div class="box5-2" v-if="item.peopleRank">{{ `( ${item.peopleRank} )` }}</div>
<div class="box5-1" style="color: #CE4F51">{{ item.dreverseCount + "人" }}</div>
</div>
<div class="item-box6">
<div class="img-box" v-if="item.keyUser">
<img :src="item.keyUser" alt="" />
<div class="img-box" v-if="item.dpersonImageUrl">
<img :src="item.dpersonImageUrl" alt="" />
</div>
<div v-else>
<el-icon size="20" color="#555"><ArrowDownBold /></el-icon>
</div>
</div>
<div class="item">
<div class="item-box1">
<div class="box1-left">
<div class="icon">
<img :src="GHD" alt="" />
</div>
<div class="name">共和党</div>
</div>
<div class="box3-main-center-content-box">
<div class="box1-right">
<div class="box1-right-top">
<el-progress :percentage="Number(item.ragreePercent)" :show-text="false" color="#1677FF"> </el-progress>
</div>
<div class="box1-right-bottom">
<el-progress :percentage="Number(item.ragainstPercent)" :show-text="false" color="#ffdcc8"> </el-progress>
</div>
</div>
</div>
<div class="item-box2">
<div class="box2-1" style="color: #1677FF">{{ item.ragreeCount + "票" }}</div>
<div class="box2-2" style="color: #FF9054">{{ item.ragainstCount + "票" }}</div>
</div>
<div class="item-box3"></div>
<div class="item-box4">
<div class="box4-1" style="color: #1677FF">{{ item.ragreePercent + "%" }}</div>
<div class="box4-2" style="color: #FF9054">{{ item.ragainstPercent + "%" }}</div>
</div>
<div class="item-box5">
<div class="box5-1" style="color: #CE4F51">{{ item.rreverseCount + "人" }}</div>
</div>
<div class="item-box6">
<div class="img-box" v-if="item.rpersonImageUrl">
<img :src="item.rpersonImageUrl" alt="" />
</div>
</div>
</div>
</div>
<!-- <div class="box3-main-center-content-box">
<div class="item" v-for="(item, index) in voteAnalysisList2" :key="index">
<div class="item-box1">
<div class="box1-left">
......@@ -196,8 +255,8 @@
</div>
</div>
</div>
</div>
<div class="box3-main-center-content-box">
</div> -->
<!-- <div class="box3-main-center-content-box">
<div class="item" v-for="(item, index) in voteAnalysisList3" :key="index">
<div class="item-box1">
<div class="box1-left">
......@@ -298,7 +357,7 @@
</div>
</div>
</div>
</div>
</div> -->
</div>
</div>
<div class="box3-main-footer">
......@@ -597,6 +656,15 @@ const handleGetBillAmeAnalyzeCount = async () => {
};
// 获取投票分析
const voteAnalysisList = ref([]);
const formatDate = (dateStr) => {
if (!dateStr) return "";
const date = new Date(dateStr);
const y = date.getFullYear();
const m = date.getMonth() + 1;
const d = date.getDate();
return `${y}年${m}月${d}日`;
};
const handleGetBillVoteAnalyze = async () => {
const params = {
id: window.sessionStorage.getItem("billId")
......@@ -604,6 +672,7 @@ const handleGetBillVoteAnalyze = async () => {
try {
const res = await getBillTp(params);
console.log("投票分析", res);
voteAnalysisList.value = res.data;
} catch (error) {
console.error("投票分析 error", error);
}
......@@ -1152,8 +1221,10 @@ onMounted(async () => {
}
}
.box3-main-center-content {
height: 682px;
overflow: auto;
.box3-main-center-content-box {
width: 830px;
width: 805px;
height: 160px;
box-sizing: border-box;
border: 1px solid rgba(243, 243, 244, 1);
......
......@@ -35,12 +35,12 @@
<div
class="item"
:class="{ itemActive: companyActiveIndex === idx }"
@click="handleClickCompany(idx)"
@click="handleClickCompany(val, idx)"
v-for="(val, idx) in curCompanyList"
:key="idx"
>
<div class="id">{{ idx + 1 }}</div>
<div class="title" :class="{ titleActive: companyActiveIndex === idx }">
<div class="id">{{ (currentPage - 1) * pageSize + idx + 1 }}</div>
<div class="title" :class="{ titleActive: companyActiveIndex === ((currentPage - 1) * pageSize + idx) }">
{{ val.name }}
</div>
<div class="icon">
......@@ -169,12 +169,12 @@
<div class="dialog-box1">
<div class="dialog-box1-header">
<div class="icon">
<img :src="companyInfo.data1.icon" alt="" />
<img :src="companyInfo.data1?.icon" alt="" />
</div>
<div class="dialog-box1-title">{{ companyInfo.data1.title }}</div>
<div class="dialog-box1-title">{{ companyInfo.data1?.title }}</div>
</div>
<div class="dialog-box1-main">
<div class="item" v-for="(val, idx) in companyInfo.data1.list" :key="idx">
<div class="item" v-for="(val, idx) in companyInfo.data1?.list" :key="idx">
<div class="item-left">
<!-- <img :src="uncheckIcon" alt=""> -->
<img :src="checkedIcon" alt="" />
......@@ -186,18 +186,18 @@
<div class="dialog-box2">
<div class="dialog-box2-header">
<div class="icon">
<img :src="companyInfo.data2.icon" alt="" />
<img :src="companyInfo.data2?.icon" alt="" />
</div>
<div class="dialog-box2-title">{{ companyInfo.data2.title }}</div>
<div class="dialog-box2-title">{{ companyInfo.data2?.title }}</div>
</div>
<div class="dialog-box2-main" id="chart2"></div>
</div>
<div class="dialog-box3">
<div class="dialog-box3-header">
<div class="icon">
<img :src="companyInfo.data3.icon" alt="" />
<img :src="companyInfo.data3?.icon" alt="" />
</div>
<div class="dialog-box3-title">{{ companyInfo.data3.title }}</div>
<div class="dialog-box3-title">{{ companyInfo.data3?.title }}</div>
</div>
<div class="dialog-box3-main" id="chart3"></div>
</div>
......@@ -210,7 +210,7 @@
<script setup>
import { ref, onMounted, nextTick, computed } from "vue";
import * as echarts from "echarts";
import { getCompanyList, getIndustryHyly, getHylyList } from "@/api/influence";
import { getCompanyList, getIndustryHyly, getHylyList, getCompanyDetail } from "@/api/influence";
import getBarChart from "./utils/barChart";
import getLineChart from "./utils/lineChart";
import getBarChart1 from "./utils/barChart1";
......@@ -232,19 +232,20 @@ import Fishbone from "./components/fishbone.vue";
import CompanyImg from "./assets/images/symbol.png";
const isShowCompanyDialog = ref(true);
const isShowCompanyDialog = ref(false);
const box1BtnActive = ref(0);
const handleClickBox1Btn = (industry, index) => {
box1BtnActive.value = index;
curHylyId.value = industry.hylyid;
curHylyId.value = industry.id;
handleGetCompanyListById();
};
// 绘制echarts图表
const setChart = (option, chartId) => {
let chartDom = document.getElementById(chartId);
if (!chartDom) return;
chartDom.removeAttribute("_echarts_instance_");
let chart = echarts.init(chartDom);
chart.setOption(option);
......@@ -252,34 +253,45 @@ const setChart = (option, chartId) => {
};
const chart1Data = ref({
// name: ["新能源", "半导体", "跨境电商", "金融业", "军工", "贸易"],
// value: [109, 95, 79, 25, 21, 50],
name: [],
value: [],
});
const industryActiveIndex = ref(0);
const companyActiveIndex = ref(0);
const showAllChart1 = ref(false);
const fullChart1Data = ref({ name: [], value: [] });
const handleClickCompany = index => {
companyActiveIndex.value = index;
isShowCompanyDialog.value = true;
// const handleToggleChart1 = () => {
// showAllChart1.value = !showAllChart1.value;
// renderChart1();
// };
setTimeout(() => {
const chart2Data = {
dataX: ["2025-01", "2025-02", "2025-03", "2025-04", "2025-05", "2025-06", "2025-07", "2025-08"],
dataY: [1.2, 1.5, 1.4, 1.8, 1.3, 1.5, 1.6, 1.4]
};
const renderChart1 = () => {
let dataName = fullChart1Data.value.name;
let dataValue = fullChart1Data.value.value;
let chart2 = getLineChart(chart2Data.dataX, chart2Data.dataY);
setChart(chart2, "chart2");
// if (!showAllChart1.value && dataName.length > 5) {
// dataName = dataName.slice(0, 5);
// dataValue = dataValue.slice(0, 5);
// }
const chart3Data = {
name: ["2023Q3", "2023Q4", "2024Q1", "2024Q2", "2024Q3", "2024Q4", "2025Q1", "2025Q2"],
value: [49, 53, 52, 54, 52, 50, 51, 54]
};
let chart1 = getBarChart(dataName, dataValue);
setChart(chart1, "chart1");
};
const industryActiveIndex = ref(0);
const companyActiveIndex = ref(0);
const curCompanyId = ref("");
const handleClickCompany = (val, index) => {
companyActiveIndex.value = (currentPage.value - 1) * pageSize.value + index;
if (val) {
curCompanyId.value = val.id;
handleGetCompanyDetail();
companyInfo.value.name = val.name;
companyInfo.value.status = val.status || companyInfo.value.status;
}
isShowCompanyDialog.value = true;
let chart3 = getBarChart1(chart3Data.name, chart3Data.value);
setChart(chart3, "chart3");
}, 100);
};
const pageSize = ref(10);
......@@ -307,44 +319,46 @@ const industryList = ref([
]);
const companyInfo = ref({
logo: CompanyLogo,
name: "宁德时代新能源科技股份有限公司",
status: "down",
changeRate: 0.16,
data1: {
icon: icon1,
title: "影响条款",
list: [
"严格限制外国敏感实体(FEOC)参与补贴",
"取消电动汽车补贴(2025年底生效)",
"任何实体若与被禁止外国实体签订超100万美元的关键技术许可协议,则不得向其提供联邦补贴"
]
},
data2: {
icon: icon2,
title: "融资情况",
data: {
time: ["2025-06", "2025-07", "2025-08"],
value: [1.12, 1.42, 1.5]
}
},
data3: {
icon: icon3,
title: "研发投入",
data: {
time: ["2023Q3", "2023Q4", "2024Q1", "2024Q2", "2024Q3", "2024Q4", "2025Q1", "2025Q2"],
value: [50, 53, 52, 54, 58, 60, 51, 56, 64]
}
}
// logo: CompanyLogo,
// name: "宁德时代新能源科技股份有限公司",
// status: "down",
// changeRate: 0.16,
// data1: {
// icon: icon1,
// title: "影响条款",
// list: [
// "严格限制外国敏感实体(FEOC)参与补贴",
// "取消电动汽车补贴(2025年底生效)",
// "任何实体若与被禁止外国实体签订超100万美元的关键技术许可协议,则不得向其提供联邦补贴"
// ]
// },
// data2: {
// icon: icon2,
// title: "融资情况",
// data: {
// time: ["2025-06", "2025-07", "2025-08"],
// value: [1.12, 1.42, 1.5]
// }
// },
// data3: {
// icon: icon3,
// title: "研发投入",
// data: {
// time: ["2023Q3", "2023Q4", "2024Q1", "2024Q2", "2024Q3", "2024Q4", "2025Q1", "2025Q2"],
// value: [50, 53, 52, 54, 58, 60, 51, 56, 64]
// }
// }
});
// 获取行业领域列表
const handleGetHylyList = async () => {
try {
const res = await getHylyList();
console.log("行业领域字典列表", res);
industryList.value = res.data.slice(0,6)
// console.log("行业领域字典列表", res);
industryList.value = res.data
if (res.data && res.data.length > 0) {
curHylyId.value = res.data[0].id;
}
} catch (error) {}
};
......@@ -353,14 +367,17 @@ const curHylyId = ref("");
// 根据行业领域id获取公司列表
const handleGetCompanyListById = async () => {
const params = {
// id: curHylyId.value
id: '0100'
id: curHylyId.value
};
try {
const res = await getCompanyList(params);
// console.log('根据行业id获取公司里列表', res);
if (res.code === 200 && res.data.length) {
companyList.value = res.data;
currentPage.value = 1;
nextTick(() => {
handleClickCompany(companyList.value[0], 0);
});
} else {
companyList.value = [];
}
......@@ -370,173 +387,325 @@ const handleGetCompanyListById = async () => {
// 根据法案ID 获取行业领域统计
const handleGetIndustryHyly = async () => {
const params = {
id: 1
id: window.sessionStorage.getItem("billId")
};
try {
const res = await getIndustryHyly(params);
// console.log('行业领域统计', res);
chart1Data.value.name = res.data.map(item => {
const data = res.data || [];
data.sort((a, b) => b.companyNum - a.companyNum);
fullChart1Data.value.name = data.map(item => {
return item.hylyName;
});
chart1Data.value.value = res.data.map(item => {
fullChart1Data.value.value = data.map(item => {
return item.companyNum;
});
renderChart1();
} catch (error) {}
};
const nodes = ref([
{
id: 0,
name: "泰丰先行",
// category: 0,
symbolSize: 30,
value: 8,
symbol: `image://${CompanyImg}`
},
{
id: 1,
name: "国轩高科",
// category: 0,
symbolSize: 30,
value: 9,
symbol: `image://${CompanyImg}`
},
{
id: 2,
name: "智方纳米",
// category: 2,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`
},
{
id: 3,
name: "香百科技",
// category: 1,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`
},
{
id: 4,
name: "格林滨",
// category: 2,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`
// 根据法案id,公司id,行业领域id获取公司的详情
const handleGetCompanyDetail = async () => {
const params = {
billId: window.sessionStorage.getItem("billId"),
companyId: curCompanyId.value,
id: curHylyId.value
};
try {
const res = await getCompanyDetail(params);
console.log('根据法案id,公司id,行业领域id获取公司的详情', res);
if (res.code === 200 && res.data) {
const data = res.data;
companyInfo.value = {
logo: data.imageUrl || CompanyLogo,
name: data.name || "",
status: "", // 接口未返回,暂时留空或保留默认
changeRate: 0, // 接口未返回,暂时留空
data1: {
icon: icon1,
title: "影响条款",
list: (data.tkContentList || []).filter(item => item) // 过滤掉 null
},
{
id: 5,
name: "江西紫宸",
// category: 2,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`
data2: {
icon: icon2,
title: "融资情况",
data: {
time: (data.marketCapList || []).map(item => item.time),
value: (data.marketCapList || []).map(item => item.marketCap)
}
},
{
id: 6,
name: "紫江企业",
// category: 4,
data3: {
icon: icon3,
title: "研发投入",
data: {
time: (data.investmentList || []).map(item => item.time),
value: (data.investmentList || []).map(item => item.investment)
}
}
};
// 更新左侧关系图表数据
const relationList = data.relationNameList || [];
// 更新树形图数据
const treeChildren = relationList.map((name, index) => ({
id: index,
name: name,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`
},
{
id: 7,
name: "大而美法案",
// category: 4,
symbolSize: 50,
value: 5,
symbol: `image://${CompanyImg}`
},
{
id: 8,
name: "比亚迪",
// category: 0,
symbolSize: 30,
}));
treeData.value = [{
id: relationList.length,
name: data.name,
symbolSize: 50,
value: 10,
symbol: `image://${CompanyImg}`
},
{
id: 9,
name: "铜陵有色",
// category: 3,
symbolSize: 30,
value: 8,
symbol: `image://${CompanyImg}`
},
{
id: 10,
name: "长盛精密",
// category: 1,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`
},
{
id: 11,
name: "天合光能",
// category: 0,
symbolSize: 30,
value: 8,
symbol: `image://${CompanyImg}`
},
{
id: 12,
name: "昆仑化学",
// category: 2,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`
},
{
id: 13,
name: "嘉源科技",
// category: 1,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`
},
{
id: 14,
name: "华阳集团",
// category: 4,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`
},
{
id: 15,
name: "海辰智能",
// category: 1,
symbol: `image://${CompanyImg}`,
children: treeChildren
}];
if (relationList.length > 0) {
const centerNode = {
id: relationList.length, // 中心节点 ID
name: data.name,
symbolSize: 50,
value: 10, // 权重
symbol: `image://${CompanyImg}`,
x: 400, // 假设容器宽度800,中心点x坐标
y: 300, // 假设容器高度600,中心点y坐标
fixed: true // 固定中心点位置
};
const radius = 200; // 圆的半径
const newNodes = relationList.map((name, index) => {
const angle = (index / relationList.length) * 2 * Math.PI; // 计算每个节点的角度
return {
id: index,
name: name,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`
value: 5,
symbol: `image://${CompanyImg}`,
x: 400 + radius * Math.cos(angle), // 计算x坐标
y: 300 + radius * Math.sin(angle), // 计算y坐标
fixed: true // 固定位置,形成圆形布局
};
});
newNodes.push(centerNode);
const newLinks = relationList.map((_, index) => ({
source: index,
target: relationList.length // 指向中心节点
}));
nodes.value = newNodes;
links.value = newLinks;
} else {
// 列表为空,只展示中心节点
nodes.value = [{
id: 0,
name: data.name,
symbolSize: 50,
value: 10,
symbol: `image://${CompanyImg}`,
x: 400,
y: 300,
fixed: true
}];
links.value = [];
}
// 重新渲染图表
nextTick(() => {
const chart2Data = companyInfo.value.data2.data;
if (chart2Data.time && chart2Data.time.length > 0) {
let chart2 = getLineChart(chart2Data.time, chart2Data.value);
setChart(chart2, "chart2");
} else {
let chartDom = document.getElementById("chart2");
if (chartDom) {
echarts.dispose(chartDom);
chartDom.innerHTML = ""; // 清空容器内容
}
}
const chart3Data = companyInfo.value.data3.data;
if (chart3Data.time && chart3Data.time.length > 0) {
let chart3 = getBarChart1(chart3Data.time, chart3Data.value);
setChart(chart3, "chart3");
} else {
let chartDom = document.getElementById("chart3");
if (chartDom) {
echarts.dispose(chartDom);
chartDom.innerHTML = ""; // 清空容器内容
}
}
let graphChart = getGraphChart(nodes.value, links.value);
setChart(graphChart, "graphChart");
});
} else {
companyInfo.value = {};
}
} catch (error) {}
};
const nodes = ref([
// {
// id: 0,
// name: "泰丰先行",
// // category: 0,
// symbolSize: 30,
// value: 8,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 1,
// name: "国轩高科",
// // category: 0,
// symbolSize: 30,
// value: 9,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 2,
// name: "智方纳米",
// // category: 2,
// symbolSize: 30,
// value: 7,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 3,
// name: "香百科技",
// // category: 1,
// symbolSize: 30,
// value: 6,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 4,
// name: "格林滨",
// // category: 2,
// symbolSize: 30,
// value: 6,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 5,
// name: "江西紫宸",
// // category: 2,
// symbolSize: 30,
// value: 7,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 6,
// name: "紫江企业",
// // category: 4,
// symbolSize: 30,
// value: 6,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 7,
// name: "大而美法案",
// // category: 4,
// symbolSize: 50,
// value: 5,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 8,
// name: "比亚迪",
// // category: 0,
// symbolSize: 30,
// value: 10,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 9,
// name: "铜陵有色",
// // category: 3,
// symbolSize: 30,
// value: 8,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 10,
// name: "长盛精密",
// // category: 1,
// symbolSize: 30,
// value: 7,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 11,
// name: "天合光能",
// // category: 0,
// symbolSize: 30,
// value: 8,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 12,
// name: "昆仑化学",
// // category: 2,
// symbolSize: 30,
// value: 6,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 13,
// name: "嘉源科技",
// // category: 1,
// symbolSize: 30,
// value: 6,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 14,
// name: "华阳集团",
// // category: 4,
// symbolSize: 30,
// value: 7,
// symbol: `image://${CompanyImg}`
// },
// {
// id: 15,
// name: "海辰智能",
// // category: 1,
// symbolSize: 30,
// value: 7,
// symbol: `image://${CompanyImg}`
// }
]);
const links = ref([
{ source: 0, target: 7 },
{ source: 1, target: 7 },
{ source: 1, target: 7 },
{ source: 8, target: 7 },
{ source: 8, target: 7 },
{ source: 2, target: 7 },
{ source: 2, target: 7 },
{ source: 3, target: 7 },
{ source: 3, target: 7 },
{ source: 3, target: 7 },
{ source: 4, target: 7 },
{ source: 4, target: 7 },
{ source: 5, target: 7 },
{ source: 6, target: 7 },
{ source: 9, target: 7 },
{ source: 10, target: 7 },
{ source: 11, target: 7 },
{ source: 12, target: 7 },
{ source: 13, target: 7 },
{ source: 14, target: 7 },
{ source: 15, target: 7 }
// { source: 0, target: 7 },
// { source: 1, target: 7 },
// { source: 1, target: 7 },
// { source: 8, target: 7 },
// { source: 8, target: 7 },
// { source: 2, target: 7 },
// { source: 2, target: 7 },
// { source: 3, target: 7 },
// { source: 3, target: 7 },
// { source: 3, target: 7 },
// { source: 4, target: 7 },
// { source: 4, target: 7 },
// { source: 5, target: 7 },
// { source: 6, target: 7 },
// { source: 9, target: 7 },
// { source: 10, target: 7 },
// { source: 11, target: 7 },
// { source: 12, target: 7 },
// { source: 13, target: 7 },
// { source: 14, target: 7 },
// { source: 15, target: 7 }
// { source: 0, target: 1, value: 1 },
// { source: 1, target: 8, value: 2 },
// { source: 1, target: 2, value: 1 },
......@@ -558,138 +727,7 @@ const links = ref([
// { source: 12, target: 14, value: 1 },
]);
const treeData = ref([
{
id: 7,
name: "大而美法案",
// category: 4,
symbolSize: 50,
value: 5,
symbol: `image://${CompanyImg}`,
children: [
{
id: 0,
name: "泰丰先行",
// category: 0,
symbolSize: 30,
value: 8,
symbol: `image://${CompanyImg}`
},
{
id: 1,
name: "国轩高科",
// category: 0,
symbolSize: 30,
value: 9,
symbol: `image://${CompanyImg}`
},
{
id: 2,
name: "智方纳米",
// category: 2,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`
},
{
id: 3,
name: "香百科技",
// category: 1,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`
},
{
id: 4,
name: "格林滨",
// category: 2,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`
},
{
id: 5,
name: "江西紫宸",
// category: 2,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`
},
{
id: 6,
name: "紫江企业",
// category: 4,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`
},
{
id: 8,
name: "比亚迪",
// category: 0,
symbolSize: 30,
value: 10,
symbol: `image://${CompanyImg}`
},
{
id: 9,
name: "铜陵有色",
// category: 3,
symbolSize: 30,
value: 8,
symbol: `image://${CompanyImg}`
},
{
id: 10,
name: "长盛精密",
// category: 1,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`
},
{
id: 11,
name: "天合光能",
// category: 0,
symbolSize: 30,
value: 8,
symbol: `image://${CompanyImg}`
},
{
id: 12,
name: "昆仑化学",
// category: 2,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`
},
{
id: 13,
name: "嘉源科技",
// category: 1,
symbolSize: 30,
value: 6,
symbol: `image://${CompanyImg}`
},
{
id: 14,
name: "华阳集团",
// category: 4,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`
},
{
id: 15,
name: "海辰智能",
// category: 1,
symbolSize: 30,
value: 7,
symbol: `image://${CompanyImg}`
}
]
}
]);
const treeData = ref([]);
const handleChangeChart = index => {
if (index === 0) {
......@@ -707,8 +745,9 @@ onMounted(async () => {
await handleGetHylyList();
handleGetCompanyListById();
await handleGetIndustryHyly();
let chart1 = getBarChart(chart1Data.value.name, chart1Data.value.value);
setChart(chart1, "chart1");
// let chart1 = getBarChart(chart1Data.value.name, chart1Data.value.value);
// setChart(chart1, "chart1");
});
</script>
......@@ -745,6 +784,12 @@ onMounted(async () => {
display: flex;
justify-content: flex-end;
gap: 4px;
.more-btn {
font-size: 14px;
color: #1677ff;
cursor: pointer;
line-height: 28px;
}
.icon {
width: 28px;
height: 28px;
......@@ -776,6 +821,7 @@ onMounted(async () => {
margin-left: 17px;
overflow-x: hidden;
width: 445px;
overflow-x: auto;
.left-center-btn-box {
width: 1000px;
margin-top: 10px;
......@@ -785,7 +831,7 @@ onMounted(async () => {
.left-center-btn {
margin-right: 4px;
height: 28px;
width: 70px;
// width: 70px;
text-align: center;
padding: 0 5px;
box-sizing: border-box;
......@@ -798,7 +844,7 @@ onMounted(async () => {
font-weight: 400;
line-height: 28px;
cursor: pointer;
overflow: hidden;
// overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
......
......@@ -3,24 +3,65 @@ import * as echarts from "echarts";
const getBarChart = (nameList, valueList) => {
const colorList = ['#b37feb', '#ffc53e', '#36cfc9', '#5c80f7', '#ff7d7a', '#4a9cff']
const option = {
tooltip: {},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
grid: {
top: '3%',
right: '7%',
bottom: '1%',
left: '1%',
top: '5%',
right: '15%',
bottom: '5%',
left: '3%',
containLabel: true
},
dataZoom: [
{
type: 'slider',
show: valueList.length > 5,
yAxisIndex: 0,
width: 8,
right: 10,
top: 20,
bottom: 20,
startValue: 0,
endValue: 4, // Show 5 items (0-4)
fillerColor: 'rgba(167,183,204,0.4)',
borderColor: 'transparent',
handleSize: 0,
showDetail: false,
brushSelect: false
},
{
type: 'inside',
yAxisIndex: 0,
startValue: 0,
endValue: 4,
zoomOnMouseWheel: false,
moveOnMouseWheel: true,
moveOnTouch: true
}
],
xAxis: {
type: 'value',
splitLine: {
show: false
},
axisLine: {
show: false
},
axisTick: {
show: false
},
axisLabel: {
show: false
}
},
yAxis: {
type: 'category',
data: nameList,
inverse: true, // Display from top to bottom
splitLine: {
show: false
},
......@@ -31,57 +72,40 @@ const getBarChart = (nameList, valueList) => {
show: false
},
axisLabel: {
show: true
show: true,
color: '#333',
fontSize: 14,
width: 100, // Limit width to handle long names
overflow: 'truncate',
ellipsis: '...'
}
},
series: [{
type: 'bar',
data: valueList.map((item,index) => {
data: valueList.map((item, index) => {
// Cycle through colors if more data than colors
const colorIndex = index % colorList.length;
const color = colorList[colorIndex];
return {
value: item,
label: {
textStyle: {
color: colorList[index]
}
}
};
}
),
barWidth: 8,
label: {
show: true,
position: [365, 0],
formatter: function(params) {
return params.value
}
},
itemStyle: {
color: function (params) {
var colorList = [
['#fff', '#b37feb'],
['#fff', '#ffc53e'],
['#fff', '#36cfc9'],
['#fff', '#5c80f7'],
['#fff', '#ff7d7a'],
['#fff', '#4a9cff'],
];
var index = params.dataIndex;
if (params.dataIndex >= colorList.length) {
index = params.dataIndex - colorList.length;
}
return new echarts.graphic.LinearGradient(0, 0, 1, 0,
[{
offset: 0,
color: colorList[index][0]
},
{
offset: 1,
color: colorList[index][1]
}
]);
color: new echarts.graphic.LinearGradient(0, 0, 1, 0, [
{ offset: 0, color: 'rgba(255,255,255,0)' }, // Transparent start
{ offset: 1, color: color } // Solid end
]),
borderRadius: [0, 10, 10, 0]
},
barBorderRadius: 4,
label: {
show: true,
position: 'right',
color: color,
fontSize: 16,
offset: [5, 0] // Add some space between bar and label
}
};
}),
barWidth: 10,
showBackground: false
}]
}
return option
......
......@@ -49,7 +49,7 @@ const getBarChart1 = (nameList, valueList) => {
offset: 1,
color: 'rgba(22,119,255,0)' // 结束颜色:浅色且透明度降低
}]),
barBorderRadius: 4,
borderRadius: 4,
}
}]
}
......
......@@ -41,7 +41,7 @@ const getGraphChart = (nodes, links) => {
itemStyle: {
color: '#73C0DE'
},
layout: 'force',
layout: 'none',
data: nodes,
links: links,
// categories: categories,
......
......@@ -319,7 +319,7 @@
新闻动态
</div>
<div class="btn" :class="{ btnActive: dialogBoxBtnActive === 1 }" @click="handleClcikDialogBoxBtn(1)">
任务履历
人物履历
</div>
</div>
<div class="inner-right-main">
......@@ -1411,6 +1411,11 @@ onMounted(() => {
font-size: 14px;
font-weight: 400;
line-height: 22px;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 3;
overflow: hidden;
text-overflow: ellipsis;
}
.timeline-content1 {
color: rgba(132, 136, 142, 1);
......
......@@ -106,7 +106,7 @@
<div class="home-main-header-item-box">
<div class="item" v-for="(item, index) in govInsList" :key="index" @click="handleToInstitution(item)">
<div class="item-left">
<img :src="item.img" alt="" />
<img :src="item.img?item.img: DefaultIcon2" alt="" />
</div>
<div class="item-right">{{ item.name }}</div>
</div>
......@@ -137,7 +137,7 @@
{{ "查看详情 >" }}
</div>
</div>
<el-carousel ref="carouselRef" trigger="click" height="376px" :autoplay="true">
<el-carousel ref="carouselRef" trigger="click" height="395px" :autoplay="true">
<el-carousel-item v-for="(item, index) in box1DataList" :key="index">
<div class="box1-main">
<div class="box1-main-left">
......@@ -147,19 +147,18 @@
<div class="box1-main-right-title">
{{ item.name }}
</div>
<div class="box1-main-right-info" v-if="item.industryList">
<div class="box1-main-right-info">
<div
class="tag"
:class="{
tag1: tag.status == 1,
tag2: tag.status == 2,
tag3: tag.status == 3,
tag4: tag.status == 4
tag3: tag.status == 3
}"
v-for="(tag, index) in item.industryList"
:key="index"
>
{{ tag.name }}
{{ tag.industryName }}
</div>
</div>
<div class="box1-main-right-center">
......@@ -336,7 +335,7 @@
<DivideHeader id="position4" class="divide4" :titleText="'资源库'"></DivideHeader>
<div class="home-main-footer-header">
<div class="btn-box">
<div class="btn-wrapper">
<div
class="btn"
:class="{ btnActive: activeCate === cate.id }"
......@@ -346,7 +345,7 @@
>
{{ cate.name }}
</div>
</div>
</div>
<div class="select-box">
<div class="paixu-btn" @click="handleSwithSort">
......@@ -420,7 +419,9 @@
<div class="main-item-left">
<div class="left-left">{{ item.time }}</div>
<div class="left-right">
<div class="icon"></div>
<div class="icon">
<img :src="item.orgImage?item.orgImage:DefaultIcon2" alt="">
</div>
<div class="line" v-if="index !== 9 && index !== totalDecreesNum - 1"></div>
</div>
</div>
......@@ -496,6 +497,9 @@ import getCalendarHeatChart from "./utils/cleandarHeat";
import setChart from "@/utils/setChart";
import DefaultIcon1 from '@/assets/icons/default-icon1.png'
import DefaultIcon2 from '@/assets/icons/default-icon2.png'
import p1 from "./assets/images/iconp1.png";
import p2 from "./assets/images/iconp2.png";
import p3 from "./assets/images/iconp3.png";
......@@ -554,46 +558,46 @@ const handleCurrentChange = page => {
// 页面 header
const govInsList = ref([
{
img: Gov1,
name: "美国白宫"
},
{
img: Gov2,
name: "美国财政部"
},
{
img: Gov3,
name: "美国能源部"
},
{
img: Gov4,
name: "美国商务部"
},
{
img: Gov5,
name: "美国战争部"
},
{
img: Gov6,
name: "联邦通信委员会 "
},
{
img: Gov7,
name: "食品药品监督管理局 (FDA)"
},
{
img: Gov8,
name: "美国航空航天局 (NASA)"
},
{
img: Gov9,
name: "美国国家卫生基金会 (NSF)"
},
{
img: Gov10,
name: "美国国立卫生研究院 (NIH)"
}
// {
// img: Gov1,
// name: "美国白宫"
// },
// {
// img: Gov2,
// name: "美国财政部"
// },
// {
// img: Gov3,
// name: "美国能源部"
// },
// {
// img: Gov4,
// name: "美国商务部"
// },
// {
// img: Gov5,
// name: "美国战争部"
// },
// {
// img: Gov6,
// name: "联邦通信委员会 "
// },
// {
// img: Gov7,
// name: "食品药品监督管理局 (FDA)"
// },
// {
// img: Gov8,
// name: "美国航空航天局 (NASA)"
// },
// {
// img: Gov9,
// name: "美国国家卫生基金会 (NSF)"
// },
// {
// img: Gov10,
// name: "美国国立卫生研究院 (NIH)"
// }
]);
const handleGetDepartmentList = async () => {
try {
......@@ -674,7 +678,7 @@ const handleClickToDetail = () => {
console.log("当前 Carousel 激活索引:", activeIndex);
const id = box1DataList.value[activeIndex].id
const id = box1DataList.value[activeIndex].id;
const route = router.resolve({
path: "/decreeLayout",
......@@ -721,36 +725,18 @@ handlegetDecreeRiskSignal();
// 新闻资讯
const newsList = ref([
{
img: News1,
title: "美政府停摆仍持续,拨款法案存缺陷,但两党磋商露曙光",
content: `美国政府停摆已持续34天,距离历史上最长的停摆纪录仅差一天,参议院已先后13次尝试...`,
from: "11-4 · 华盛顿邮报"
},
{
img: News2,
title: "美参议院通过决议,要求终止特朗普全球关税政策",
content: `参议院以51票赞成、47票反对通过一项决议,旨在终止特朗普实施的全面关税政策,四名......`,
from: "11-4 · 纽约时报"
},
{
img: News3,
title: "美众院通过950亿美元对外援助法案,包含对台军援",
content: `国会众议院在4月通过了大规模对外援助法案,其中包括为“印太安全”提供资金的条款,......`,
from: "11-3 · 洛杉矶时报"
},
{
img: News4,
title: "“大而美”法案在激烈争议中通过",
content: `特朗普力推的大规模税收与支出法案在国会以微弱优势通过。该法案因大幅削减医疗补助和......`,
from: "11-3 · 今日美国"
},
{
img: News5,
title: "美政府“停摆”追平历史最长纪录,民生多领域受重创",
content: `联邦政府“停摆”进入第35天,追平历史纪录。食品救济项目资金中断,数百万低收入民......`,
from: "11-2 · ​福克斯新闻网"
}
// {
// img: News1,
// title: "美政府停摆仍持续,拨款法案存缺陷,但两党磋商露曙光",
// content: `美国政府停摆已持续34天,距离历史上最长的停摆纪录仅差一天,参议院已先后13次尝试...`,
// from: "11-4 · 华盛顿邮报"
// },
// {
// img: News2,
// title: "美参议院通过决议,要求终止特朗普全球关税政策",
// content: `参议院以51票赞成、47票反对通过一项决议,旨在终止特朗普实施的全面关税政策,四名......`,
// from: "11-4 · 纽约时报"
// }
]);
const handleGetNews = async () => {
const params = {
......@@ -782,24 +768,19 @@ const handleToNewsAnalysis = () => {
// 社交媒体
const messageList = ref([
{
img: Message1,
name: "唐纳德·特朗普",
time: "15:23 · 发布于真实社交",
content: `埃隆·马斯克在强力支持我竞选总统之前,早就知道我强烈反对‘电动汽车强制令’。这太荒谬了,这一直是我竞选活动的主要部分。电动汽车没问题,但不应该强迫每个人都拥有一辆。埃隆获得的补贴可能远远超过历史上任何一个人。如果没有补贴,埃隆可能不得不关门大吉,回到南非老家。`
},
{
img: Message2,
name: "埃隆·马斯克",
time: "14:49 · 发布于X",
content: `如果这个疯狂的支出法案获得通过,‘美国党’将在第二天成立。`
},
{
img: Message3,
name: "塞巴斯蒂安·马拉比",
time: "11:05 · 发布于X",
content: `提出特朗普政府的AI政策强调技术开放与快速应用,但可能以牺牲安全防范为代价,开启了“潘多拉魔盒”。`
}
// {
// img: Message1,
// name: "唐纳德·特朗普",
// time: "15:23 · 发布于真实社交",
// content: `埃隆·马斯克在强力支持我竞选总统之前,早就知道我强烈反对‘电动汽车强制令’。这太荒谬了,这一直是我竞选活动的主要部分。电动汽车没问题,但不应该强迫每个人都拥有一辆。埃隆获得的补贴可能远远超过历史上任何一个人。如果没有补贴,埃隆可能不得不关门大吉,回到南非老家。`
// },
// {
// img: Message2,
// name: "埃隆·马斯克",
// time: "14:49 · 发布于X",
// content: `如果这个疯狂的支出法案获得通过,‘美国党’将在第二天成立。`
// }
]);
const handleGetMessage = async () => {
const params = {
......@@ -824,7 +805,7 @@ const handleClickPerson = () => {
const route = router.resolve({
path: "/characterPage",
query: {
type: 1 // 1 2 3
type: 3 // 1 2 3
}
});
window.open(route.href, "_blank");
......@@ -832,8 +813,8 @@ const handleClickPerson = () => {
// 行政令发布频度
const chart1Data = ref({
dataX: ["2019", "2020", "2021", "2022", "2023", "2024", "2025"],
dataY: [219, 228, 129, 159, 152, 157, 78]
dataX: [],
dataY: []
});
const handleGetDecreeYearOrder = async () => {
......@@ -865,34 +846,15 @@ const handleBox5 = async () => {
// 政令涉及领域
const chart2Data = ref([
{
name: "集成电路",
value: 50
},
{
name: "人工智能",
value: 46
},
{
name: "通信网络",
value: 40
},
{
name: "量子科技",
value: 32
},
{
name: "能源",
value: 31
},
{
name: "生物科技",
value: 30
},
{
name: "航空航天",
value: 24
}
// {
// name: "集成电路",
// value: 50
// },
// {
// name: "人工智能",
// value: 46
// },
]);
// const colorList = ["#69B1FF", "#FFC069", "#87E8DE", "#85A5FF", "#FF7875", "#B37FEB", "#4096FF"];
......@@ -920,26 +882,17 @@ const handleBox6 = async () => {
// 关键行政令
const keyDecreeList = ref([
{
title: "关于“对等关税”的行政令",
time: "2025年4月",
content: `对所有贸易伙伴设立10%的“最低基准关税”,并对中国商品加征高达34%​​ 的额外关税,使针对中国的总关税水平大幅提升。`
},
{
title: "《美国优先投资政策》备忘录",
time: "2025年2月",
content: `将中国列为“外国对手”,系统性收紧中美在半导体、人工智能、量子技术等前沿科技领域的双向投资,构建对华科技封锁体系。`
},
{
title: "针对TikTok的行政令",
time: "2025年2月",
content: `以所谓“信息安全”为由,要求字节跳动剥离TikTok在美业务,并禁止通过微信、支付宝等中国应用程序进行交易。`
},
{
title: "签署《外国投资风险审查现代化法》",
time: "2025年2月",
content: `极大加强了美国外国投资委员会(CFIUS)的权限,重点关注来自中国的投资。`
}
// {
// title: "关于“对等关税”的行政令",
// time: "2025年4月",
// content: `对所有贸易伙伴设立10%的“最低基准关税”,并对中国商品加征高达34%​​ 的额外关税,使针对中国的总关税水平大幅提升。`
// },
// {
// title: "《美国优先投资政策》备忘录",
// time: "2025年2月",
// content: `将中国列为“外国对手”,系统性收紧中美在半导体、人工智能、量子技术等前沿科技领域的双向投资,构建对华科技封锁体系。`
// },
]);
const handleGetKeyDecree = async () => {
......@@ -970,16 +923,6 @@ const wordCloudData = [
// { name: "选举压力", value: 57 },
// { name: "主张财政紧缩", value: 72 },
// { name: "财政保守", value: 18 },
// { name: "共和党", value: 34 },
// { name: "扩大军费", value: 16 },
// { name: "参议院多数党", value: 72 },
// { name: "地方利益捍卫者", value: 58 },
// { name: "众议院预算委员会", value: 24 },
// { name: "债务与赤字警告", value: 33 },
// { name: "抗议医疗补助条款", value: 47 },
// { name: "深红州", value: 32 },
// { name: "温和派选区", value: 62 },
// { name: "高压游说", value: 51 }
];
const handleGetDecreeKeyInstruction = async () => {
......@@ -1094,78 +1037,6 @@ const decreeList = ref([
// img: 1,
// desc: "123",
// tagList: ["生物科技"]
// },
// {
// type: "总统政令",
// status: 1,
// title: "修改对等关税税率以反映与中华人民共和国会谈情况的行政令",
// time: "2025年9月15日",
// img: 1,
// desc: "123",
// tagList: ["生物科技"]
// },
// {
// type: "总统政令",
// status: 1,
// title: "调整互惠关税范围,并制定实施贸易和安全协议的程序",
// time: "2025年9月15日",
// img: 1,
// desc: "123",
// tagList: ["生物科技"]
// },
// {
// type: "总统政令",
// status: 1,
// title: "持续努力加强国家网络安全,并修订第13694号行政命令和第14144号行政命令",
// time: "2025年9月14日",
// img: 1,
// desc: "123",
// tagList: ["生物科技"]
// },
// {
// type: "总统备忘录",
// status: 3,
// title: "通过第232条款行动确保加工关键矿物及衍生产品的国家安全与经济韧性",
// time: "2025年9月14日",
// img: 1,
// desc: "123",
// tagList: ["生物科技"]
// },
// {
// type: "提名与任命",
// status: 2,
// title: "终止对不可靠、非受控能源的市场扭曲补贴",
// time: "2025年9月11日",
// img: 1,
// desc: "123",
// tagList: ["生物科技"]
// },
// {
// type: "总统政令",
// status: 1,
// title: "对所有国家暂停免关税待遇",
// time: "2025年9月6日",
// img: 1,
// desc: "123",
// tagList: ["生物科技"]
// },
// {
// type: "总统政令",
// status: 1,
// title: "对所有国家暂停免关税待遇",
// time: "2025年9月6日",
// img: 1,
// desc: "123",
// tagList: ["生物科技"]
// },
// {
// type: "总统政令",
// status: 1,
// title: "对所有国家暂停免关税待遇",
// time: "2025年9月6日",
// img: 1,
// desc: "123",
// tagList: ["生物科技"]
// }
]);
......@@ -1201,7 +1072,7 @@ const handleGetDecreeOrderList = async () => {
decreeList.value = [];
}
} catch (error) {
console.error('资源库列表error', error);
console.error("资源库列表error", error);
decreeList.value = [];
}
};
......@@ -1244,11 +1115,8 @@ onMounted(async () => {
handleGetAreaList();
handleGetDecreeOrderList();
handleBox1(); // 最新科技政令
handleBox5();
handleBox6();
handleBox8();
});
</script>
......@@ -1679,12 +1547,16 @@ onMounted(async () => {
margin-left: 28px;
flex: 1;
.box1-main-right-title {
height: 26px;
width: 100%;
// height: 26px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.box1-main-right-info {
margin-top: 14px;
......@@ -1693,18 +1565,29 @@ onMounted(async () => {
.tag {
height: 24px;
line-height: 24px;
padding: 1px 8px;
padding: 0 8px;
box-sizing: border-box;
border-radius: 4px;
margin-right: 5px;
border: 1px solid rgba(255, 163, 158, 1);
color: rgba(245, 34, 45, 1);
background: rgba(255, 241, 240, 1);
}
.tag1 {
border: 1px solid rgba(135, 232, 222, 1);
color: rgba(19, 168, 168, 1);
background: rgba(230, 255, 251, 1);
}
.tag2 {
border: 1px solid rgba(186, 224, 255, 1);
background: rgba(230, 244, 255, 1);
color: rgba(22, 119, 255, 1);
}
.tag3 {
border: 1px solid rgba(255, 229, 143, 1);
color: rgba(250, 173, 20, 1);
background: rgba(255, 251, 230, 1);
}
.tag4 {
border: 1px solid rgba(255, 163, 158, 1);
color: rgba(245, 34, 45, 1);
......@@ -2845,13 +2728,11 @@ onMounted(async () => {
width: 1450px;
overflow-x: auto;
overflow-y: hidden;
.btn-wrapper {
width: 1880px;
display: flex;
gap: 10px;
overflow-x: auto;
overflow-y: hidden;
gap: 8px;
white-space: nowrap;
.btn {
min-width: min-content;
height: 42px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
......@@ -2875,7 +2756,7 @@ onMounted(async () => {
background: rgba(20, 89, 187, 1);
}
}
}
}
.select-box {
margin-top: 5px;
......@@ -3037,7 +2918,11 @@ onMounted(async () => {
width: 24px;
height: 24px;
border-radius: 12px;
background: #ccc;
overflow: hidden;
img{
width: 100%;
height: 100%;
}
}
.line {
height: 112px;
......
......@@ -6,8 +6,8 @@ const getBarChart = (nameList, valueList) => {
grid: {
top: '3%',
right: '3%',
bottom: '1%',
left: '1%',
bottom: '3%',
left: '3%',
containLabel: true
},
yAxis: {
......@@ -18,7 +18,12 @@ const getBarChart = (nameList, valueList) => {
axisLine: {
show: false
},
show: true
show: true,
textStyle: {
color: 'rgba(95, 101, 108, 1)',
fontFamily: 'Microsoft YaHei',
fontsize: 14,
}
},
xAxis: {
type: 'category',
......@@ -33,7 +38,12 @@ const getBarChart = (nameList, valueList) => {
show: true
},
axisLabel: {
show: true
show: true,
textStyle: {
color: 'rgba(95, 101, 108, 1)',
fontFamily: 'Microsoft YaHei',
fontsize: 14,
}
}
},
series: [{
......
......@@ -6,7 +6,7 @@ const getPieChart = (data) => {
radius: [110, 143],
height: '100%',
left: 'center',
width: '100%',
width: '95%',
itemStyle: {
borderColor: '#fff',
borderWidth: 1
......@@ -18,9 +18,16 @@ const getPieChart = (data) => {
edgeDistance: 10,
lineHeight: 24,
rich: {
name: {
color: 'rgba(59, 65, 75, 1)',
fontFamily: 'Microsoft YaHei',
fontSize: 16,
fontWeight: 'bold',
},
time: {
fontSize: 16,
color: '#999'
fontFamily: 'Microsoft YaHei',
color: '#rgba(95, 101, 108, 1)'
}
}
},
......
......@@ -129,26 +129,26 @@ const showList = computed(() => {
});
const siderList = ref([
{
time: "2023",
title: "拜登人工智能政令"
},
{
time: "2023",
title: "拜登人工智能政令"
},
{
time: "2025",
title: "特朗普撤销拜登AI规则"
},
{
time: "2023",
title: "美国AI行动计划"
},
{
time: "2024",
title: "对中国AI芯片限制"
}
// {
// time: "",
// title: ""
// },
// {
// time: "2023",
// title: "拜登人工智能政令"
// },
// {
// time: "2025",
// title: "特朗普撤销拜登AI规则"
// },
// {
// time: "2023",
// title: "美国AI行动计划"
// },
// {
// time: "2024",
// title: "对中国AI芯片限制"
// }
]);
const siderActiveIndex = ref(0);
const handleClickSider = async index => {
......@@ -178,22 +178,22 @@ const handleClickSider = async index => {
};
const decreeInfo = ref({
img: box2InfoImg,
totalTitle: "关于安全、可靠和可信地开发和使用人工智能的行政命令",
eTotalTitle: "Executive Order on the Safe, Secure, and Trustworthy Development and Use of Artificial Intelligence",
signTime: "2025年7月23日",
signOrg: "乔·拜登(Joe Biden)",
img: "",
totalTitle: "",
eTotalTitle: "",
signTime: "",
signOrg: "",
list: [
{
content:
"要求强大AI系统开发者与政府分享安全测试结果(“红队测试”);制定生物合成筛查标准防范风险;建立AI生成内容鉴别标准"
},
{
content: "优先支持隐私保护技术(PET)研发;评估各机构如何收集和使用商业信息;制定评估隐私保护技术有效性的指南。"
},
{
content: "为解决算法歧视提供明确指导;确保刑事司法系统中AI使用的公平性;协调调查和起诉AI相关的民权侵犯行为。"
}
// {
// content:
// "要求强大AI系统开发者与政府分享安全测试结果(“红队测试”);制定生物合成筛查标准防范风险;建立AI生成内容鉴别标准"
// },
// {
// content: "优先支持隐私保护技术(PET)研发;评估各机构如何收集和使用商业信息;制定评估隐私保护技术有效性的指南。"
// },
// {
// content: "为解决算法歧视提供明确指导;确保刑事司法系统中AI使用的公平性;协调调查和起诉AI相关的民权侵犯行为。"
// }
]
});
......
......@@ -6,16 +6,16 @@
<div class="layout-main-header-left-box">
<div class="left-box-top">
<div class="icon">
<img src="./assets/images/USA-logo.png" alt="" />
<img :src="summaryInfo.officialUrl" alt="" />
</div>
<div class="info">
<div class="info-box1">{{ "EO 14320-推动美国人工智能技术栈的出口" }}</div>
<div class="info-box1">{{ summaryInfo.name }}</div>
<div class="info-box2">
<div class="info-box2-item">{{ "总统行动" }}</div>
<div class="info-box2-item">{{ summaryInfo.order }}</div>
|
<div class="info-box2-item">{{ "行政命令" }}</div>
<div class="info-box2-item">{{ summaryInfo.type }}</div>
|
<div class="info-box2-item">{{ "Promoting the Export of the American AI Technology Stack" }}</div>
<div class="info-box2-item">{{ summaryInfo.ename }}</div>
</div>
</div>
</div>
......@@ -39,13 +39,14 @@
</div>
<div class="layout-main-header-right-box">
<div class="right-box-top">
<div class="time">{{ "2025年7月23日" }}</div>
<div class="name">{{ "唐纳德·约翰·特朗普(Donald John Trump)" }}</div>
<div class="time">{{ summaryInfo.postDate }}</div>
<div class="name">{{ summaryInfo.orgName }}</div>
</div>
<div class="right-box-bottom">
<el-button type="plain" size="large" icon="Search" @click="handleSwitchActiveName('法案原文')"
<!-- <el-button type="plain" size="large" icon="Search" @click="handleSwitchActiveName('法案原文')"
>政令原文</el-button
>
> -->
<el-button type="plain" size="large" icon="Search">政令原文</el-button>
<el-button type="primary" size="large" icon="EditPen">分析报告</el-button>
</div>
</div>
......@@ -123,6 +124,7 @@
import { ref, onMounted, onUnmounted } from "vue";
import router from "@/router";
import { useRoute } from "vue-router";
import { getDecreeSummary } from "@/api/decree/introduction";
import search from "./assets/images/search.png";
import icon1 from "./assets/icons/icon1.png";
......@@ -132,12 +134,16 @@ import icon2Active from "./assets/icons/icon2_active.png";
import icon3 from "./assets/icons/icon3.png";
import icon3Active from "./assets/icons/icon3_active.png";
import DefaultIcon2 from '@/assets/icons/default-icon2.png'
const route = useRoute();
const decreeId = ref(route.query.id);
const activeName = ref("分析报告");
const summaryInfo = ref({});
const handleSwitchActiveName = name => {
activeName.value = name;
};
......@@ -189,7 +195,22 @@ const handleClickMainHeaderBtn = item => {
});
};
// 获取全局信息
const handleGetSummary = async () => {
const params = {
id: route.query.id
};
try {
const res = await getDecreeSummary(params);
console.log("全局信息", res);
if (res.code === 200 && res.data) {
summaryInfo.value = res.data;
}
} catch (error) {}
};
onMounted(() => {
handleGetSummary();
if (window.sessionStorage.getItem("activeTitle")) {
activeTitle.value = window.sessionStorage.getItem("activeTitle");
}
......@@ -217,7 +238,7 @@ onUnmounted(() => {
display: flex;
justify-content: space-between;
.layout-main-header-left-box {
width: 800px;
width: 1100px;
margin-left: 160px;
margin-top: 13px;
.left-box-top {
......@@ -226,6 +247,10 @@ onUnmounted(() => {
.icon {
width: 64px;
height: 64px;
img{
width: 100%;
height: 100%;
}
}
.info {
margin-left: 9px;
......
......@@ -30,11 +30,11 @@
</div>
</div>
<div class="box1-list-box">
<div class="box1-item" v-for="(item, index) in showCompanyList" :key="index">
<div class="box1-item" v-for="(item, index) in showCompanyList" :key="index" @click="handleToCompanyDetail">
<div class="id">{{ index + 1 }}</div>
<div class="title">{{ item.name }}</div>
<div class="icon">
<img v-if="item.status === 'up'" src="./assets/images/up.png" alt="" />
<img v-if="item.status >= 0" src="./assets/images/up.png" alt="" />
<img v-else src="./assets/images/down.png" alt="" />
</div>
</div>
......@@ -72,7 +72,7 @@
</div>
<div class="box2-main">
<div class="box2-line-box"></div>
<div class="box2-line-box" v-if="timeLineList.length"></div>
<div
class="box2-item"
:class="{ box2ItemFooter: index % 2 }"
......@@ -156,15 +156,21 @@
</template>
<script setup>
import { ref, computed,watch, onMounted } from "vue";
import { ref, computed, watch, onMounted } from "vue";
import { useRoute } from "vue-router";
import router from "@/router";
import setChart from "@/utils/setChart";
import * as echarts from "echarts";
import getBarChart from "./utils/barChart";
import { getDecreeIndustry, getDecreehylyList, getDecreeCompany, getDecreeAction } from "@/api/decree/influence";
const route = useRoute();
// 跳转企业详情
const handleToCompanyDetail = () => {
const route = router.resolve("/companyPages");
window.open(route.href, "_blank");
};
// 企业影响分析
const companyTotalNum = ref(0); // 企业数量
const isCRelated = ref(false); // 只看中国企业
......@@ -208,7 +214,13 @@ const handelBox1 = async () => {
const box1BtnActiveName = ref("");
const curAreaId = ref(0);
const box1BtnList = ref(["集成电路", "新能源", "人工智能", "先进制造", "量子科技"]);
const box1BtnList = ref([
// "集成电路",
// "新能源",
// "人工智能",
// "先进制造",
// "量子科技"
]);
const handleClickBox1Btn = btn => {
box1BtnActiveName.value = btn.name;
curAreaId.value = btn.id;
......@@ -224,51 +236,32 @@ const handleGetHylyList = async () => {
box1BtnList.value = res.data;
box1BtnActiveName.value = box1BtnList.value[0].name;
curAreaId.value = box1BtnList.value[0].id;
handleGetCompanyListByArea();
}
} catch (error) {}
};
const companyList = ref([
{
name: "宁德时代新能源科技股份有限公司",
status: "down"
},
{
name: "比亚迪股份有限公司",
status: "down"
},
{
name: "隆基绿能科技股份有限公司",
status: "down"
},
{
name: "晶科能源控股有限公司",
status: "down"
},
{
name: "厦门海辰储能科技股份有限公司",
status: "down"
},
{
name: "国轩高科股份有限公司",
status: "up"
},
{
name: "远景科技集团",
status: "down"
},
{
name: "惠州亿纬锂能股份有限公司",
status: "down"
},
{
name: "天合光能股份有限公司",
status: "down"
},
{
name: "晶澳太阳能科技股份有限公司",
status: "up"
}
// {
// name: "宁德时代新能源科技股份有限公司",
// status: "down"
// },
// {
// name: "比亚迪股份有限公司",
// status: "down"
// },
// {
// name: "隆基绿能科技股份有限公司",
// status: "down"
// },
// {
// name: "晶科能源控股有限公司",
// status: "down"
// },
// {
// name: "厦门海辰储能科技股份有限公司",
// status: "down"
// }
]);
const currentPage = ref(1);
const pageSize = ref(10);
......@@ -296,7 +289,7 @@ const handleGetCompanyListByArea = async () => {
return {
name: item.name,
id: item.id,
status: "up"
status: item.marketChange
};
});
companyTotalNum.value = companyList.value.length;
......@@ -312,26 +305,14 @@ const handleGetCompanyListByArea = async () => {
// 政令举措落实分析
const timeLineList = ref([
{
time: "2025年7月25日",
content: "商务部已成立AI出口计划办公室,并开始招募专业人员。"
},
{
time: "2025年7月31日",
content: "英伟达、微软、谷歌等企业已提交初步技术栈提案。"
},
{
time: "2025年8月5日",
content: "国务院开始与盟友国家进行初步磋商。"
},
{
time: "2025年8月9日",
content: "国防部、能源部安全审查流程尚未最终确定。"
},
{
time: "2025年8月12日",
content: "商务部已成立AI出口计划办公室,并开始招募专业人员。"
}
// {
// time: "2025年7月25日",
// content: "商务部已成立AI出口计划办公室,并开始招募专业人员。"
// },
// {
// time: "2025年7月31日",
// content: "英伟达、微软、谷歌等企业已提交初步技术栈提案。"
// }
]);
const handleGetAction = async () => {
......@@ -358,48 +339,48 @@ const handleGetAction = async () => {
// 历史相似举措及落实情况
const box3List = ref([
{
type: "科技法案",
title: "瓦森纳安排",
content: "落实情况:持续有效,但面临技术快速迭代挑战。",
time: "1996-至今",
tag: "人工智能"
},
{
type: "科技法案",
title: "云计算出口管制",
content: "落实情况:部分有效,但执行难度大。",
time: "1996-至今",
tag: "人工智能"
},
{
type: "科技法案",
title: "芯片与科学法案",
content: "落实情况:正在实施,效果待观察。",
time: "2022-至今",
tag: "人工智能"
},
{
type: "科技法案",
title: "AI芯片出口管制",
content: "落实情况:部分有效,但催生中国自主创新。",
time: "1996-至今",
tag: "人工智能"
},
{
type: "科技法案",
title: "瓦森纳安排",
content: "落实情况:持续有效,但面临技术快速迭代挑战。",
time: "1996-至今",
tag: "人工智能"
},
{
type: "科技法案",
title: "瓦森纳安排",
content: "落实情况:持续有效,但面临技术快速迭代挑战。",
time: "1996-至今",
tag: "人工智能"
}
// {
// type: "科技法案",
// title: "瓦森纳安排",
// content: "落实情况:持续有效,但面临技术快速迭代挑战。",
// time: "1996-至今",
// tag: "人工智能"
// },
// {
// type: "科技法案",
// title: "云计算出口管制",
// content: "落实情况:部分有效,但执行难度大。",
// time: "1996-至今",
// tag: "人工智能"
// },
// {
// type: "科技法案",
// title: "芯片与科学法案",
// content: "落实情况:正在实施,效果待观察。",
// time: "2022-至今",
// tag: "人工智能"
// },
// {
// type: "科技法案",
// title: "AI芯片出口管制",
// content: "落实情况:部分有效,但催生中国自主创新。",
// time: "1996-至今",
// tag: "人工智能"
// },
// {
// type: "科技法案",
// title: "瓦森纳安排",
// content: "落实情况:持续有效,但面临技术快速迭代挑战。",
// time: "1996-至今",
// tag: "人工智能"
// },
// {
// type: "科技法案",
// title: "瓦森纳安排",
// content: "落实情况:持续有效,但面临技术快速迭代挑战。",
// time: "1996-至今",
// tag: "人工智能"
// }
]);
watch(
......@@ -411,7 +392,6 @@ watch(
);
onMounted(() => {
handleGetCompanyListByArea();
handleGetChart1Data();
handleGetHylyList();
handleGetAction();
......@@ -529,6 +509,10 @@ onMounted(() => {
border-bottom: 1px solid rgba(234, 236, 238, 1);
border-radius: 4px;
display: flex;
cursor: pointer;
&:hover {
background: var(--color-bg-hover);
}
.id {
width: 24px;
height: 24px;
......
......@@ -31,7 +31,12 @@ const getBarChart = (nameList, valueList) => {
show: false
},
axisLabel: {
show: true
show: true,
textStyle: {
fontSize: 16,
fontFamily: 'Microsoft YaHei',
color: 'rgba(59, 65, 75, 1)'
}
}
},
series: [{
......
......@@ -126,12 +126,12 @@ const handleClickBox1Btn = btn => {
};
const backgroundListNum = ref(0);
const backgroundList = ref([
{
content: "认为人工智能(AI)是一项将决定未来几十年经济增长、国家安全和全球竞争力的基础性技术"
},
{
content: "要求美国不仅必须在开发通用和前沿AI能力方面领先,还必须确保美国的人工智能技术、标准和治理模式在全球范围内被采用"
},
// {
// content: "认为人工智能(AI)是一项将决定未来几十年经济增长、国家安全和全球竞争力的基础性技术"
// },
// {
// content: "要求美国不仅必须在开发通用和前沿AI能力方面领先,还必须确保美国的人工智能技术、标准和治理模式在全球范围内被采用"
// },
]);
const handleGetBackground = async () => {
const params = {
......@@ -155,39 +155,14 @@ const handleGetBackground = async () => {
// 相关事件
const relatedEvents = ref([
{
image: Img1,
title: "中美AI模型性能差距迅速缩小",
content:
"斯坦福大学《2025年人工智能指数报告》显示,中美顶尖AI模型在MMLU(大规模多任务语言理解)等主流基准测试中的性能...",
time: "2025-08-30"
},
{
image: Img2,
title: "中国模型以更低成本实现高性能",
content: "2025年1月,中国公司深度求索(DeepSeek)发布高性能AI推理模型R1,以其极低的训练成本和媲美顶级模型的推理能力受...",
time: "2025-05-16"
},
{
image: Img3,
title: "美国发布《赢得AI竞赛:美国AI行动计划》​",
content:
"特朗普政府发布该计划,核心包括加速创新​(解除监管)、建设AI基础设施​(加速数据中心审批、保障能源供应)和引领国际...",
time: "2025-07-23"
},
{
image: Img4,
title: "中国深入推进“人工智能+”行动",
content: "中国国务院常务会议审议通过《关于深入实施“人工智能+”行动的意见》,大力推进AI在各领域的规模化商业化应用和和深...",
time: "2025-07-31"
},
{
image: Img5,
title: "美国对华AI芯片出口管制持续升级",
content:
"美国商务部宣布撤销拜登时期的《AI扩散规则》,要求全球使用美国技术的芯片厂商停止向中国出口AI芯片,直接影响英伟达...",
time: "2025-05-20"
}
// {
// image: Img1,
// title: "中美AI模型性能差距迅速缩小",
// content:
// "斯坦福大学《2025年人工智能指数报告》显示,中美顶尖AI模型在MMLU(大规模多任务语言理解)等主流基准测试中的性能...",
// time: "2025-08-30"
// }
]);
const handleGetRelateEvents = async () => {
const params = {
......@@ -215,34 +190,19 @@ const handleGetRelateEvents = async () => {
// 法律依据
const laws = ref([
{
name: "《美国法典》",
info: "第3编第301条",
content:
"允许总统通过行政命令(Executive Order)​​ 或其它书面形式授权行政部门或机构的负责人​(如国务卿、财政部长等)代行本属于总统的法定职能(由国会立法授予总统的职能)。"
},
{
name: "《出口管制改革法案》",
info: "",
content:
"该法案授权政府出于国家安全和外交政策目的对特定技术、商品和软件的出口进行管制。确保AI技术不流向“对手国家”是其题中应有之义。"
},
{
name: "《国际紧急经济权力法》",
info: "",
content:
"授予总统在应对“不寻常且极其严重的威胁”时,监管商业和金融交易的广泛权力,包括实施出口管制。这在以往的贸易和科技管制中常被引用。"
},
{
name: "《2019年通过外交捍卫美国商业法》",
info: "第708(c)(3)条",
content: "授权小企业管理局局长和OSTP主任任命其各自行政部门和机构的高级官员担任EDAG成员。"
},
{
name: "《关于安全、可靠和可信地开发和使用人工智能的行政命令》",
info: "",
content: "要求强大AI系统的开发者与政府共享安全测试结果,并为AI安全、隐私保护、公平权利及创新竞争等方面制定标准。"
}
// {
// name: "《美国法典》",
// info: "第3编第301条",
// content:
// "允许总统通过行政命令(Executive Order)​​ 或其它书面形式授权行政部门或机构的负责人​(如国务卿、财政部长等)代行本属于总统的法定职能(由国会立法授予总统的职能)。"
// },
// {
// name: "《出口管制改革法案》",
// info: "",
// content:
// "该法案授权政府出于国家安全和外交政策目的对特定技术、商品和软件的出口进行管制。确保AI技术不流向“对手国家”是其题中应有之义。"
// }
]);
const handleGetLaws = async () => {
const params = {
......
......@@ -127,7 +127,7 @@
<div class="box3-top">
<div class="box3-top-top">
<div class="left">
<img :src="box3TopData.logo" alt="" />
<img :src="box3TopData.logo?box3TopData.logo:DefaultIcon2" alt="" />
</div>
<div class="right">
<div class="name">{{ box3TopData.name }}</div>
......@@ -147,13 +147,6 @@
<div class="item-left">{{ "成立时间:" }}</div>
<div class="item-right">{{ box3TopData.clsj }}</div>
</div>
<div class="main-item">
<div class="item-icon"></div>
<div class="item-left">{{ "主要职责:" }}</div>
<div class="item-right">
{{ box3TopData.zyzz }}
</div>
</div>
<div class="main-item">
<div class="item-icon"></div>
<div class="item-left">{{ "总部地址:" }}</div>
......@@ -206,20 +199,23 @@ import box1Img from "./assets/images/box1-img.png";
import Box3Logo from "./assets/images/box3-img.png";
import { getDecreeBasicInfo, getDecreeMainContent, getDecreeOrganization } from "@/api/decree/introduction";
import DefaultIcon1 from '@/assets/icons/default-icon1.png'
import DefaultIcon2 from '@/assets/icons/default-icon2.png'
const route = useRoute();
const decreeId = ref(route.query.id);
// 基本信息
const basicInfo = ref({
img: box1Img,
name: "推动美国人工智能技术栈出口",
eName: "Promoting the Export of the American AI Technology Stack",
areaList: ["人工智能", "出口管制", "半导体产业", "关税", "光伏产业"],
signTime: "2025年7月23日",
signPeople: "唐纳德·约翰·特朗普(Donald John Trump)",
bh: "第14320号行政命令 (EO 14320)",
deadline: "签署后90天内建立机制并开始实施"
img: "",
name: "",
eName: "",
areaList: [],
signTime: "",
signPeople: "",
bh: "",
deadline: ""
});
const handleGetBasicInfo = async () => {
......@@ -246,10 +242,10 @@ handleGetBasicInfo();
// 主要指令
const majorList = ref([
{
id: 1,
content: '要求商务部在90天内建立"全栈式"美国AI出口机制。'
}
// {
// id: 1,
// content: '要求商务部在90天内建立"全栈式"美国AI出口机制。'
// }
]);
const currentPage = ref(1);
const pageSize = ref(5);
......@@ -285,8 +281,8 @@ const handleMajorList = async () => {
handleMajorList();
// 执行机构
const box3BtnList = ref(["商务部", "经济外交行动组"]);
const box3ActiveBtn = ref("商务部");
const box3BtnList = ref([]);
const box3ActiveBtn = ref("");
const box3BtnActiveIndex = ref(0);
const handleClickBox3Btn = (btn, index) => {
box3ActiveBtn.value = btn;
......@@ -296,7 +292,6 @@ const handleClickBox3Btn = (btn, index) => {
box3TopData.value.name = box3Data.value[index].name;
box3TopData.value.eName = box3Data.value[index].ename;
box3TopData.value.clsj = box3Data.value[index].foundingDate;
box3TopData.value.zyzz = "暂无数据";
box3TopData.value.zbdz = box3Data.value[index].address;
box3TopData.value.bz = box3Data.value[index].leaderName;
eventList.value = box3Data.value[index].newsList.map(val => {
......@@ -310,32 +305,29 @@ const handleClickBox3Btn = (btn, index) => {
const box3Data = ref([]);
const box3TopData = ref({
logo: Box3Logo,
name: "美国商务部",
eName: "United States Department of Commerce",
clsj: "1903年2月14日",
zbdz: "华盛顿宪法大道1401号胡佛大楼",
bz: "霍华德·卢特尼克"
logo: "",
name: "",
eName: "",
clsj: "",
zbdz: "",
bz: ""
});
// 机构动态
const eventList = ref([
{
time: "2025-07-31",
title: "美商务部发布指南,警告全球企业使用华为昇腾芯片可能违反美国出口管制。意在限制中国AI产业发展,阻碍其获得先进算力。"
},
{
time: "2025-07-25",
title: "美商务部持续对多种中国产品发起“双反”(反倾销、反补贴)调查并作出裁决,涉及产品从工业原料到日常用品,且裁定的税率普遍较高。"
},
{
time: "2025-07-21",
title: "美商务部进一步收紧对华先进半导体出口管制,将更多中国实体列入“实体清单”。限制14纳米及以下先进芯片、DRAM等对华出口"
},
{
time: "2025-07-12",
title: "美商务部发起第三次反倾销和反补贴日落复审调查。"
}
// {
// time: "2025-07-31",
// title: "美商务部发布指南,警告全球企业使用华为昇腾芯片可能违反美国出口管制。意在限制中国AI产业发展,阻碍其获得先进算力。"
// },
// {
// time: "2025-07-25",
// title: "美商务部持续对多种中国产品发起“双反”(反倾销、反补贴)调查并作出裁决,涉及产品从工业原料到日常用品,且裁定的税率普遍较高。"
// },
// {
// time: "2025-07-21",
// title: "美商务部进一步收紧对华先进半导体出口管制,将更多中国实体列入“实体清单”。限制14纳米及以下先进芯片、DRAM等对华出口"
// }
]);
const handleGetOrgnization = async () => {
......@@ -356,6 +348,7 @@ const handleGetOrgnization = async () => {
box3TopData.value.clsj = res.data[0].foundingDate;
box3TopData.value.zbdz = res.data[0].address;
box3TopData.value.bz = res.data[0].leaderName;
box3ActiveBtn.value = res.data[0].name;
eventList.value = res.data[0].newsList.map(val => {
return {
time: val.newsDate,
......
......@@ -177,7 +177,7 @@ export default {
/* 向上节点:线往下伸 */
.dot.up::after {
bottom: 100%;
height: 180px;
height: 165px;
/* 圆环底部 → 卡片顶 */
}
......@@ -185,15 +185,15 @@ export default {
.dot.down::after {
top: 100%;
height: 180px;
height: 165px;
}
.card {
position: absolute;
height: 180px;
width:320px;
height: 165px;
width: 320px;
padding: 8px 12px;
text-align: left;
cursor: pointer;
......@@ -208,6 +208,7 @@ export default {
line-height: 26px;
letter-spacing: 0px;
text-align: justify;
margin-bottom: 10px;
}
.title {
......@@ -218,6 +219,7 @@ export default {
line-height: 26px;
letter-spacing: 0px;
text-align: justify;
margin-bottom: 10px;
}
.content {
......
......@@ -52,27 +52,20 @@
}}
</div>
</div>
<img
class="item-card-content-title-image"
:src="organizationNews[organizationNewsShow].image"
alt=""
/>
<img class="item-card-content-title-image" :src="organizationNews[organizationNewsShow].image"
alt="" />
</div>
<div class="item-header-divider"></div>
<div class="item-card-content-text">
{{ organizationNews[organizationNewsShow].content }}
</div>
<div style="display: flex; margin-top: 30px">
<div
class="item-card-content-tag"
v-for="(tag, index) in organizationNews[organizationNewsShow].tag"
:key="index"
:style="{
<div class="item-card-content-tag" v-for="(tag, index) in organizationNews[organizationNewsShow].tag"
:key="index" :style="{
color: tag.textColor,
background: tag.color,
border: `1px solid ${tag.textColor}`
}"
>
}">
{{ tag.text }}
</div>
</div>
......@@ -114,13 +107,10 @@
<div style="padding: 30px 23px; height: 400px">
<div class="waring-item" v-for="(item, index) in warningList" :key="index">
<div style="display: flex; height: 47px">
<div
class="waring-status"
:style="{
<div class="waring-status" :style="{
color: item.status === 0 ? '#CE4F51' : item.status === 1 ? '#FA8C16' : '#52C41A',
backgroundColor: item.status === 0 ? '#FFF1F0' : item.status === 1 ? '#FFF7E6' : '#F6FFED'
}"
>
}">
{{ item.status === 0 ? "特别重大" : item.status === 1 ? "重大风险" : "一般风险" }}
</div>
<div class="waring-text">
......@@ -424,7 +414,7 @@ function changeOrganizationNews(type) {
: (organizationNewsShow.value = organizationNewsShow.value + 1);
}
}
onMounted(() => {});
onMounted(() => { });
</script>
<style lang="scss" scoped>
......@@ -450,6 +440,7 @@ onMounted(() => {});
box-sizing: border-box;
padding-left: 160px;
position: relative;
.header-search-box {
position: absolute;
top: 14px;
......@@ -457,6 +448,7 @@ onMounted(() => {});
display: flex;
gap: 12px;
justify-content: flex-end;
.header-search-left {
width: 360px;
height: 36px;
......@@ -464,18 +456,22 @@ onMounted(() => {});
border-radius: 4px;
background: rgba(255, 255, 255, 0.3);
display: flex;
.input-box {
width: 324px;
}
.icon {
width: 36px;
height: 36px;
img {
width: 100%;
height: 100%;
}
}
}
.header-search-right {
width: 36px;
height: 36px;
......@@ -483,10 +479,12 @@ onMounted(() => {});
border-radius: 4px;
background: rgba(255, 255, 255, 0.3);
cursor: pointer;
.header-img-box {
width: 19px;
height: 24px;
margin: 4px auto;
img {
width: 100%;
height: 100%;
......@@ -590,6 +588,7 @@ onMounted(() => {});
font-size: 14px;
}
}
.item-header-text-1 {
// width: 150px;
height: 48px;
......@@ -641,7 +640,7 @@ onMounted(() => {});
}
.item-card-content-tag {
width: 74px;
width: 76px;
height: 24px;
padding: 1px 8px 1px 8px;
margin: 2px;
......@@ -682,7 +681,7 @@ onMounted(() => {});
.item-card-content {
height: 100%;
width: calc(100% - 50px);
width: 454px;
padding: 20px;
.item-card-content-header {
......@@ -1002,10 +1001,12 @@ onMounted(() => {});
}
}
}
:deep(.el-input__wrapper) {
box-shadow: none;
background: none;
}
:deep(.el-input__wrapper:hover) {
box-shadow: none !important;
}
......@@ -1013,6 +1014,7 @@ onMounted(() => {});
:deep(.el-input__wrapper.is-focus) {
box-shadow: none !important;
}
:deep(.el-input__inner::placeholder) {
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
......
......@@ -86,7 +86,8 @@ const switchTab = name => {
<style lang="scss" scoped>
.wrap {
width: 1920px;
height: 984px;
// height: 984px;
.header {
width: 1920px;
height: 188px;
......@@ -95,12 +96,14 @@ const switchTab = name => {
border-top: 1px solid rgba(234, 236, 238, 1);
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.header-top {
margin-top: 20px;
margin-left: 248px;
display: flex;
justify-content: space-between;
margin-right: 160px;
.header-top-left {
.title {
height: 26px;
......@@ -112,6 +115,7 @@ const switchTab = name => {
letter-spacing: 0px;
text-align: left;
}
.en-title {
height: 24px;
color: rgba(95, 101, 108, 1);
......@@ -122,10 +126,12 @@ const switchTab = name => {
letter-spacing: 0px;
text-align: left;
}
.tag-box {
margin-top: 11px;
display: flex;
gap: 8px;
.tag {
height: 26px;
padding: 0 8px;
......@@ -143,6 +149,7 @@ const switchTab = name => {
}
}
}
.header-top-right {
.name {
height: 24px;
......@@ -154,6 +161,7 @@ const switchTab = name => {
letter-spacing: 0px;
text-align: right;
}
.time {
height: 24px;
margin-top: 5px;
......@@ -167,6 +175,7 @@ const switchTab = name => {
}
}
}
.header-bottom {
margin: 0 auto;
margin-top: 30px;
......@@ -174,13 +183,15 @@ const switchTab = name => {
height: 48px;
display: flex;
justify-content: space-between;
.tab-box {
width: 224px;
height: 48px;
display: flex;
gap: 24px;
.tab {
width: 92px;
width: 94px;
height: 48px;
display: flex;
align-items: center;
......@@ -188,14 +199,17 @@ const switchTab = name => {
gap: 4px;
cursor: pointer;
border-bottom: 2px solid transparent;
.icon {
width: 16px;
height: 16px;
img {
width: 100%;
height: 100%;
}
}
.text {
height: 24px;
color: rgba(59, 65, 75, 1);
......@@ -204,18 +218,22 @@ const switchTab = name => {
font-weight: 400;
line-height: 24px;
}
.textActive {
color: rgba(5, 95, 194, 1);
font-weight: 700;
}
}
.tabActive {
border-bottom: 2px solid rgba(5, 95, 194, 1);
}
}
.btn-box {
display: flex;
gap: 12px;
.btn {
width: 120px;
height: 36px;
......@@ -227,16 +245,19 @@ const switchTab = name => {
align-items: center;
justify-content: center;
gap: 8px;
.icon {
width: 16px;
height: 16px;
img {
width: 100%;
height: 100%;
}
}
.text {
width: 64px;
width: 66px;
height: 22px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
......@@ -247,17 +268,20 @@ const switchTab = name => {
text-align: center;
}
}
.btn1 {
border-radius: 6px;
background: var(--color-main-active);
.text{
color: rgba(255,255,255,1);
.text {
color: rgba(255, 255, 255, 1);
}
}
}
}
}
.main{
.main {
width: 100%;
}
}
......
......@@ -17,10 +17,10 @@
<div class="box1-main">
<div class="box1-item" v-for="(item, index) in box1Data" :key="index">
<div class="left">
{{ item.id }}
{{ index + 1 }}
</div>
<div class="center">
<div class="title">{{ item.title }}</div>
<div class="title">{{ item.content }}</div>
<div class="tag-box">
<div class="tag" v-for="(val, idx) in item.tagList" :key="idx">
{{ val }}
......@@ -28,8 +28,15 @@
</div>
<div class="file-box">
<div class="file-item" v-for="(vall, idxx) in item.fileList" :key="idxx">
<div class="file-item-left">{{ vall.type }}</div>
<div class="file-item-center">{{ vall.name }}</div>
<div class="file-item-left">法案</div>
<div class="file-item-center">{{ vall.relationBillsList }}</div>
<div class="file-item-right">
<img src="@/assets/images/icon-right-circle.png" alt="" />
</div>
</div>
<div class="file-item" v-for="(vall, idxx) in item.fileList" :key="idxx">
<div class="file-item-left">政令</div>
<div class="file-item-center">{{ vall.relationAdList }}</div>
<div class="file-item-right">
<img src="@/assets/images/icon-right-circle.png" alt="" />
</div>
......@@ -46,14 +53,7 @@
</div>
</div>
</div>
<div class="box1-footer">
<div class="info">
{{ `共105项调查` }}
</div>
<div class="page-box">
<el-pagination :page-size="10" background layout="prev, pager, next" :total="120" />
</div>
</div>
</div>
</div>
......@@ -79,13 +79,13 @@
<div class="line" v-if="index < 5"></div>
</div>
<div class="box2-item-center">
<div class="title">{{ item.title }}</div>
<div class="content">{{ item.content }}</div>
<div class="title">{{ item.sjbt }}</div>
<div class="content">{{ item.sjnr }}</div>
</div>
<div class="box2-item-right">
<div class="time">{{ item.time }}</div>
<div class="img-box">
<img :src="item.img" alt="" />
<img :src="item.imageUrl" alt="" />
</div>
</div>
</div>
......@@ -102,7 +102,12 @@
<script setup>
import { ref, onMounted } from "vue";
import {
getThinkTankReportPolicy,
getThinkTankReportPolicyAction
} from "@/api/thinkTank/overview";
import { useRouter } from "vue-router";
const router = useRouter();
// 政策建议落实情况
const box1Data = ref([
{
......@@ -257,6 +262,19 @@ const box1Data = ref([
}
]);
const handleGetThinkTankReportPolicy = async () => {
try {
const res = await getThinkTankReportPolicy(router.currentRoute._value.params.id);
console.log("政策建议落实情况", res);
if (res.code === 200 && res.data) {
box1Data.value = res.data
}
} catch (error) {
console.error("获取政策建议落实情况rror", error);
}
};
// 相关政策动态
const box2Data = ref([
{
......@@ -296,6 +314,24 @@ const box2Data = ref([
img: 1
}
]);
const handleGetThinkTankReportPolicyAction = async () => {
try {
const res = await getThinkTankReportPolicyAction(router.currentRoute._value.params.id);
console.log("相关政策动态", res);
if (res.code === 200 && res.data) {
box2Data.value = res.data
}
} catch (error) {
console.error("获取相关政策动态rror", error);
}
};
onMounted(async () => {
handleGetThinkTankReportPolicy()
handleGetThinkTankReportPolicyAction()
});
</script>
<style lang="scss" scoped>
......@@ -303,11 +339,14 @@ const box2Data = ref([
display: flex;
justify-content: center;
gap: 16px;
height: 100%;
.box-header {
width: 100%;
height: 50px;
display: flex;
position: relative;
.header-left {
margin-top: 18px;
width: 8px;
......@@ -315,6 +354,7 @@ const box2Data = ref([
border-radius: 0 4px 4px 0;
background: var(--color-main-active);
}
.title {
margin-left: 14px;
margin-top: 14px;
......@@ -325,6 +365,7 @@ const box2Data = ref([
font-size: 20px;
font-weight: 700;
}
.header-btn-box {
position: absolute;
top: 15px;
......@@ -332,6 +373,7 @@ const box2Data = ref([
display: flex;
justify-content: flex-end;
gap: 8px;
.btn {
height: 28px;
padding: 0 8px;
......@@ -345,11 +387,13 @@ const box2Data = ref([
font-weight: 400;
line-height: 28px;
}
.btnActive {
color: var(--color-main-active);
border: 1px solid var(--color-main-active);
}
}
.header-right {
position: absolute;
top: 14px;
......@@ -357,9 +401,11 @@ const box2Data = ref([
display: flex;
justify-content: flex-end;
gap: 4px;
.icon {
width: 28px;
height: 28px;
img {
width: 100%;
height: 100%;
......@@ -367,26 +413,33 @@ const box2Data = ref([
}
}
}
.left {
height: 1442px;
height: 100%;
.box1 {
margin-top: 16px;
width: 1104px;
height: 1405px;
height: 100%;
margin-bottom: 16px;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.box1-main {
width: 1056px;
height: 1280px;
margin: 0 auto;
overflow: hidden;
overflow-y: auto;
.box1-item {
height: 128px;
border-bottom: 1px solid rgba(234, 236, 238, 1);
display: flex;
position: relative;
.left {
width: 28px;
height: 28px;
......@@ -402,8 +455,11 @@ const box2Data = ref([
font-weight: 400;
letter-spacing: 0px;
}
.center {
width: 850px;
margin-left: 18px;
.title {
margin-top: 16px;
height: 24px;
......@@ -415,10 +471,12 @@ const box2Data = ref([
letter-spacing: 0px;
text-align: left;
}
.tag-box {
display: flex;
margin-top: 7px;
gap: 8px;
.tag {
height: 22px;
padding: 0 8px;
......@@ -435,10 +493,12 @@ const box2Data = ref([
text-align: left;
}
}
.file-box {
margin-top: 7px;
display: flex;
gap: 8px;
.file-item {
height: 32px;
padding: 0 8px;
......@@ -446,6 +506,7 @@ const box2Data = ref([
background: rgba(246, 250, 255, 1);
display: flex;
align-items: center;
.file-item-left {
height: 22px;
padding: 0 4px;
......@@ -460,6 +521,7 @@ const box2Data = ref([
letter-spacing: 0px;
text-align: left;
}
.file-item-center {
margin-left: 12px;
color: var(--color-main-active);
......@@ -470,10 +532,12 @@ const box2Data = ref([
letter-spacing: 0px;
text-align: left;
}
.file-item-right {
margin-left: 12px;
width: 20px;
height: 20px;
img {
width: 100%;
height: 100%;
......@@ -482,6 +546,7 @@ const box2Data = ref([
}
}
}
.right {
position: absolute;
top: 16px;
......@@ -491,6 +556,7 @@ const box2Data = ref([
justify-content: flex-end;
align-items: center;
gap: 9px;
.text {
height: 24px;
font-family: Microsoft YaHei;
......@@ -501,9 +567,11 @@ const box2Data = ref([
letter-spacing: 0px;
text-align: right;
}
.icon {
width: 16px;
height: 16px;
img {
width: 100%;
height: 100%;
......@@ -512,12 +580,14 @@ const box2Data = ref([
}
}
}
.box1-footer {
height: 50px;
display: flex;
justify-content: space-between;
box-sizing: border-box;
padding: 20px;
.info {
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
......@@ -539,24 +609,30 @@ const box2Data = ref([
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.box2-main {
margin: 0 auto;
margin-top: 15px;
width: 459px;
height: 654px;
overflow: hidden;
.box2-item {
height: 109px;
display: flex;
.box2-item-left {
.point {
margin-left: 14px;
width: 10px;
height: 10px;
img {
width: 100%;
height: 100%;
}
}
.line {
width: 2px;
height: 109px;
......@@ -564,8 +640,10 @@ const box2Data = ref([
margin-left: 18px;
}
}
.box2-item-center {
margin-left: 11px;
.title {
width: 314px;
height: 24px;
......@@ -580,6 +658,7 @@ const box2Data = ref([
text-overflow: ellipsis;
white-space: nowrap;
}
.content {
width: 314px;
height: 48px;
......@@ -593,8 +672,10 @@ const box2Data = ref([
overflow: hidden;
}
}
.box2-item-right {
margin-left: 18px;
.time {
height: 22px;
color: rgba(95, 101, 108, 1);
......@@ -608,11 +689,13 @@ const box2Data = ref([
text-overflow: ellipsis;
white-space: nowrap;
}
.img-box {
margin-top: 14px;
width: 78px;
height: 50px;
border-radius: 2px;
img {
width: 100%;
height: 100%;
......@@ -621,6 +704,7 @@ const box2Data = ref([
}
}
}
.box2-footer {
margin: 10px auto;
width: 108px;
......@@ -630,9 +714,11 @@ const box2Data = ref([
justify-content: center;
gap: 4px;
cursor: pointer;
&:hover {
background: var(--color-bg-hover);
}
.text {
color: var(--color-main-active);
height: 22px;
......@@ -642,9 +728,11 @@ const box2Data = ref([
line-height: 22px;
letter-spacing: 0px;
}
.icon {
width: 16px;
height: 16px;
img {
width: 100%;
height: 100%;
......
......@@ -44,9 +44,9 @@
:class="{ tagActive: activeArea === item }"
v-for="(item, index) in areaList"
:key="index"
@click="handleClickArea(item)"
@click="handleClickArea(item.status)"
>
{{ item }}
{{ item.industryName }}
</div>
</div>
<div class="box2-content" id="box2Chart"></div>
......@@ -82,11 +82,14 @@
{{ item.id }}
</div>
<div class="center">
<div class="title">{{ item.title }}</div>
<div class="desc">{{ item.desc }}</div>
<div class="title">{{ item.content }}</div>
<div class="desc">{{ item.econtent }}</div>
</div>
<div class="right">
<div class="tag" v-for="(val, idx) in item.tagList" :key="idx">
<div class="tag" v-for="(val, idx) in item.hylyList" :key="idx">
{{ val.name }}
</div>
<div class="tag" v-for="(val, idx) in item.serialNum" :key="idx">
{{ val.name }}
</div>
</div>
......@@ -96,11 +99,16 @@
</div>
</div>
<div class="box3-main-footer">
<div class="info">
{{ `共105项调查` }}
</div>
<div class="info">{{ total }}项调查</div>
<div class="page-box">
<el-pagination :page-size="10" background layout="prev, pager, next" :total="120" />
<el-pagination
:page-size="12"
background
layout="prev, pager, next"
:total="total"
@current-change="handleCurrentChange"
:current-page="currentPage"
/>
</div>
</div>
</div>
......@@ -126,53 +134,112 @@
import { ref, onMounted } from "vue";
import setChart from "@/utils/setChart";
import getWordCloudChart from "./utils/worldCloudChart";
import {
getThinkTankReportAbstract,
getThinkTankReportContent,
getThinkTankReportIndustry,
getThinkTankReportIndustryCloud
} from "@/api/thinkTank/overview";
import { useRouter } from "vue-router";
const router = useRouter();
// 内容摘要
const box1Data =
ref(`包括经济竞争在内的美中竞争自2017年以来一直在定义美国外交政策。这两个经济体是世界上第一和第二大国家经济体,并且深深交织在一起。改变关系,无论多么必要,可能是昂贵的。因此,美国面临着一项挑战,确保其经济在耦合的战略竞争条件下满足国家的需求。
为了应对这一挑战,兰德大学的研究人员对美中竞争进行了经济和制度分析,进行了参与式的远见练习,以了解确保美国经济健康的长期路径,并创建了两个经济竞争游戏,探索多个国家在相互交流的同时确保经济健康的动态...`);
//获取内容摘要
const handleGetThinkTankReportAbstract = async () => {
try {
const res = await getThinkTankReportAbstract(router.currentRoute._value.params.id);
console.log("内容摘要", res);
if (res.code === 200 && res.data) {
box1Data.value = res.data;
}
} catch (error) {
console.error("获取内容摘要error", error);
}
};
// 涉及科技领域
const areaList = ref(["人工智能", "半导体与高科技", "经济与贸易", "地缘政治", "军事与安全", "国际规则与多边体系"]);
const activeArea = ref("人工智能");
const areaList = ref([]);
const activeArea = ref(6);
const handleClickArea = area => {
activeArea.value = area;
handleGetThinkTankReportIndustryCloud();
};
const box2Data = ref([
{
name: "通用人工智能",
value: 100
},
{
name: "AI芯片",
value: 66
},
{
name: "计算能力又是",
value: 72
},
{
name: "基准测试",
value: 88
},
{
name: "出口管制",
value: 78
},
{
name: "军事AI",
value: 85
},
{
name: "生态系统",
value: 88
},
{
name: "模型能力",
value: 89
}
// {
// name: "通用人工智能",
// value: 100
// },
// {
// name: "AI芯片",
// value: 66
// },
// {
// name: "计算能力又是",
// value: 72
// },
// {
// name: "基准测试",
// value: 88
// },
// {
// name: "出口管制",
// value: 78
// },
// {
// name: "军事AI",
// value: 85
// },
// {
// name: "生态系统",
// value: 88
// },
// {
// name: "模型能力",
// value: 89
// }
]);
//获取科技领域词云
const handleGetThinkTankReportIndustryCloud = async () => {
try {
const params = {
id: router.currentRoute._value.params.id,
industryId: activeArea.value
};
const res = await getThinkTankReportIndustryCloud(params);
console.log("科技领域词云", res);
if (res.code === 200 && res.data) {
const data = [];
res.data.map(item => {
data.push({
name: item.clause,
value: item.count
});
box2Data.value = data;
const box2Chart = getWordCloudChart(box2Data.value);
setChart(box2Chart, "box2Chart");
});
}
} catch (error) {
console.error("获取科技领域词云error", error);
}
};
//涉及科技领域
const handleGetThinkTankReportIndustry = async () => {
try {
const res = await getThinkTankReportIndustry(router.currentRoute._value.params.id);
console.log("涉及科技领域", res);
if (res.code === 200 && res.data) {
areaList.value = res.data;
}
} catch (error) {
console.error("获取涉及科技领域error", error);
}
};
// 主要观点
const majorOpinions = ref([
{
......@@ -314,10 +381,30 @@ const majorOpinions = ref([
]
}
]);
// 处理页码改变事件
const currentPage = ref(1);
const handleCurrentChange = page => {
currentPage.value = page;
handleGetThinkDynamicsReport();
};
//获取报告主要观点
const handleGetThinkTankReportContent = async () => {
try {
const res = await getThinkTankReportContent(router.currentRoute._value.params.id);
console.log("主要观点", res);
if (res.code === 200 && res.data) {
majorOpinions.value = res.data.content;
}
} catch (error) {
console.error("获取主要观点error", error);
}
};
onMounted(() => {
const box2Chart = getWordCloudChart(box2Data.value);
setChart(box2Chart, "box2Chart");
handleGetThinkTankReportAbstract();
handleGetThinkTankReportContent();
handleGetThinkTankReportIndustry();
handleGetThinkTankReportIndustryCloud();
});
</script>
......@@ -326,11 +413,13 @@ onMounted(() => {
display: flex;
justify-content: center;
gap: 16px;
.box-header {
width: 100%;
height: 50px;
display: flex;
position: relative;
.header-left {
margin-top: 18px;
width: 8px;
......@@ -338,6 +427,7 @@ onMounted(() => {
border-radius: 0 4px 4px 0;
background: var(--color-main-active);
}
.title {
margin-left: 14px;
margin-top: 14px;
......@@ -348,6 +438,7 @@ onMounted(() => {
font-size: 20px;
font-weight: 700;
}
.header-btn-box {
position: absolute;
top: 15px;
......@@ -355,6 +446,7 @@ onMounted(() => {
display: flex;
justify-content: flex-end;
gap: 8px;
.btn {
height: 28px;
padding: 0 8px;
......@@ -368,11 +460,13 @@ onMounted(() => {
font-weight: 400;
line-height: 28px;
}
.btnActive {
color: var(--color-main-active);
border: 1px solid var(--color-main-active);
}
}
.header-right {
position: absolute;
top: 14px;
......@@ -380,9 +474,11 @@ onMounted(() => {
display: flex;
justify-content: flex-end;
gap: 4px;
.icon {
width: 28px;
height: 28px;
img {
width: 100%;
height: 100%;
......@@ -390,6 +486,7 @@ onMounted(() => {
}
}
}
.left {
.box1 {
margin-top: 17px;
......@@ -399,10 +496,12 @@ onMounted(() => {
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.box1-main {
margin: 5px auto;
width: 428px;
height: 282px;
/* 9行 * 30px/行 = 270px,这里可以稍微调整 */
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
......@@ -410,7 +509,17 @@ onMounted(() => {
line-height: 30px;
letter-spacing: 0px;
text-align: justify;
overflow-y: auto;
// display: -webkit-box;
// /* 使用Webkit的弹性盒模型 */
// -webkit-box-orient: vertical;
// /* 垂直排列 */
// -webkit-line-clamp: 9;
// /* 限制显示9行 */
// overflow: hidden;
// /* 隐藏超出部分 */
}
.box1-footer {
margin: 0 auto;
width: 108px;
......@@ -420,9 +529,11 @@ onMounted(() => {
justify-content: center;
gap: 4px;
cursor: pointer;
&:hover {
background: var(--color-bg-hover);
}
.text {
height: 22px;
color: var(--color-main-active);
......@@ -433,9 +544,11 @@ onMounted(() => {
letter-spacing: 0px;
text-align: left;
}
.icon {
width: 16px;
height: 16px;
img {
width: 100%;
height: 100%;
......@@ -443,6 +556,7 @@ onMounted(() => {
}
}
}
.box2 {
margin-top: 16px;
width: 480px;
......@@ -451,10 +565,12 @@ onMounted(() => {
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.box2-main {
width: 430px;
height: 320px;
margin: 0 auto;
.box2-main-tag-box {
display: flex;
flex-wrap: wrap;
......@@ -462,6 +578,7 @@ onMounted(() => {
box-sizing: border-box;
padding: 8px 0;
gap: 8px;
.tag {
height: 28px;
line-height: 28px;
......@@ -472,12 +589,14 @@ onMounted(() => {
background: rgba(255, 255, 255, 1);
cursor: pointer;
}
.tagActive {
color: var(--color-main-active);
border: 1px solid var(--color-main-active);
background: rgba(231, 243, 255, 1);
}
}
.box2-content {
width: 430px;
height: 231px;
......@@ -489,8 +608,10 @@ onMounted(() => {
}
}
}
.right {
margin-top: 17px;
.box3 {
width: 1103px;
height: 946px;
......@@ -499,13 +620,16 @@ onMounted(() => {
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
position: relative;
.box3-main {
width: 1057px;
height: 800px;
margin: 0 auto;
.box3-main-main {
height: 720px;
overflow: hidden;
.box3-item {
width: 1057px;
height: 72px;
......@@ -513,6 +637,7 @@ onMounted(() => {
border-radius: 4px;
display: flex;
position: relative;
.left {
margin-top: 24px;
margin-left: 15px;
......@@ -528,12 +653,14 @@ onMounted(() => {
font-weight: 400;
letter-spacing: 0px;
}
.center {
width: 770px;
margin-left: 13px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
.title {
margin-top: 12px;
height: 26px;
......@@ -544,7 +671,11 @@ onMounted(() => {
line-height: 26px;
letter-spacing: 0px;
text-align: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.desc {
height: 22px;
color: rgba(95, 101, 108, 1);
......@@ -554,8 +685,12 @@ onMounted(() => {
line-height: 22px;
letter-spacing: 0px;
text-align: left;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.right {
margin-top: 26px;
width: 180px;
......@@ -563,6 +698,7 @@ onMounted(() => {
display: flex;
gap: 8px;
justify-content: flex-end;
.tag {
height: 22px;
padding: 0 8px;
......@@ -577,29 +713,34 @@ onMounted(() => {
line-height: 20px;
}
}
.more {
width: 16px;
height: 16px;
position: absolute;
top: 28px;
right: 20px;
img {
width: 100%;
height: 100%;
}
}
}
.box3-item:nth-child(2n-1) {
border-bottom: 1px solid rgba(234, 236, 238, 1);
border-top: 1px solid rgba(234, 236, 238, 1);
background: rgba(247, 248, 249, 1);
}
}
.box3-main-footer {
height: 80px;
display: flex;
justify-content: space-between;
padding: 30px 5px;
.info {
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
......@@ -611,6 +752,7 @@ onMounted(() => {
}
}
}
.box3-footer {
position: absolute;
left: 22px;
......@@ -625,14 +767,17 @@ onMounted(() => {
align-items: center;
justify-content: center;
gap: 13px;
.footer-left {
width: 19px;
height: 20px;
img {
width: 100%;
height: 100%;
}
}
.footer-center {
width: 964px;
height: 48px;
......@@ -644,9 +789,11 @@ onMounted(() => {
letter-spacing: 0px;
text-align: justify;
}
.footer-right {
width: 24px;
height: 24px;
img {
width: 100%;
height: 100%;
......
......@@ -12,7 +12,13 @@
<div class="box-main">
<div class="select-box">
<el-select v-model="box1SelectYear" placeholder="选择时间" style="width: 100px">
<el-option v-for="item in box1YearList" :key="item.value" :label="item.label" :value="item.value" />
<el-option
v-for="(item, index) in box1YearList"
:key="index"
:label="item.label"
:value="item.value"
@click="handleGetThinkPolicyIndustry()"
/>
</el-select>
</div>
<div id="box1Chart"></div>
......@@ -29,26 +35,32 @@
<div class="box-main">
<div class="select-box">
<el-select v-model="box2SelectYear" placeholder="选择时间" style="width: 100px">
<el-option v-for="item in box2YearList" :key="item.value" :label="item.label" :value="item.value" />
<el-option
v-for="item in box2YearList"
:key="item.value"
:label="item.label"
:value="item.value"
@click="handleGetThinkPolicyIndustryTotal()"
/>
</el-select>
</div>
<div id="box2Chart">
<div class="box2-item" v-for="(item, index) in box2Data" :key="index">
<div class="icon" :style="{ background: item.color }"></div>
<div class="name">{{ item.name }}</div>
<div class="name">{{ item.industry }}</div>
<el-progress
:show-text="false"
:color="item.color"
style="width: 220px"
:color="box2ColorList[index]"
style="width: 170px"
stroke-width="8"
:percentage="item.per"
:percentage="item.percent"
/>
<div class="num">{{ item.value + "项" }} / {{ item.total + "项" }}</div>
<div class="per">{{ item.per + "%" }}</div>
<div class="num">{{ item.amount + "项" }} / {{ item.totalAmount + "项" }}</div>
<div class="per">{{ item.percent + "%" }}</div>
</div>
<div class="box2-item">
<!-- <div class="box2-item">
<el-progress :percentage="50" />
</div>
</div> -->
</div>
</div>
</div>
......@@ -63,7 +75,13 @@
<div class="box-main">
<div class="select-box">
<el-select v-model="box3SelectYear" placeholder="选择时间" style="width: 100px">
<el-option v-for="item in box3YearList" :key="item.value" :label="item.label" :value="item.value" />
<el-option
v-for="item in box3YearList"
:key="item.value"
:label="item.label"
:value="item.value"
@click="handleGetThinkPolicyIndustryChange()"
/>
</el-select>
</div>
<div id="box3Chart"></div>
......@@ -79,9 +97,13 @@
</div>
</div>
<div class="select-box">
<el-select v-model="selectedYear" placeholder="选择时间" style="width: 120px">
<el-select v-model="selectedYear" placeholder="选择时间" style="width: 120px" @click="handleGetThinkPolicy()">
<el-option v-for="item in yearList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-select v-model="sort" placeholder="发布时间" style="width: 120px; margin-left: 8px">
<el-option @click="handleGetThinkPolicy()" :key="true" label="正序" :value="true" />
<el-option @click="handleGetThinkPolicy()" :key="false" label="倒序" :value="false" />
</el-select>
</div>
</div>
<div class="bottom-main">
......@@ -93,14 +115,19 @@
</div>
<div class="select-main">
<div class="checkbox-group">
<!-- <el-checkbox v-for="(item, index) in areaList" :key="index" v-model="selectedAreaList" :label="item"
class="filter-checkbox">
{{ item }}
</el-checkbox> -->
<el-checkbox
v-for="(item, index) in areaList"
:key="index"
style="width: 180px"
v-for="research in areaList"
:key="research.id"
v-model="selectedAreaList"
:label="item"
:label="research.id"
class="filter-checkbox"
>
{{ item }}
{{ research.name }}
</el-checkbox>
</div>
</div>
......@@ -110,34 +137,46 @@
<div class="right-main">
<div class="right-main-item" v-for="(item, index) in policyList" :key="index">
<div class="item-left">
<img :src="item.img" alt="" />
<img :src="item.imageUrl" alt="" />
</div>
<div class="item-right">
<div class="title">{{ item.title }}</div>
<div class="info">{{ item.time }} · {{ item.desc }}</div>
<div class="title">{{ item.name }}</div>
<div class="info">{{ item.times }} · {{ item.content }}</div>
<div class="tag-box">
<div class="tag" v-for="(tag, idx) in item.tagList" :key="idx">
{{ tag }}
</div>
</div>
<div class="file-box">
<div class="file" v-for="(file, idxx) in item.fileList" :key="idxx">
<div class="type">{{ file.type }}</div>
<div class="title">{{ file.title }}</div>
<div class="file" v-for="(file, idxx) in item.relationBillsList" :key="idxx">
<div class="type">法案</div>
<div class="title">{{ file.billName }}</div>
<div class="more">
<img src="./images/arrow-right.png" alt="" />
</div>
</div>
<div class="file" v-for="(file, idxx) in item.relationAdList" :key="idxx">
<div class="type">政令</div>
<div class="title">{{ file.adName }}</div>
<div class="more">
<img src="./images/arrow-right.png" alt="" />
</div>
</div>
</div>
</div>
<div class="right-footer">
<div class="info">
{{ `共105项调查` }}
</div>
</div>
<div class="right-footer">
<div class="info">{{ total }}项调查</div>
<div class="page-box">
<el-pagination :page-size="10" background layout="prev, pager, next" :total="120" />
<el-pagination
:page-size="12"
background
layout="prev, pager, next"
:total="total"
@current-change="handleCurrentChange"
:current-page="currentPage"
/>
</div>
</div>
</div>
......@@ -147,53 +186,63 @@
</template>
<script setup>
import { ref, onMounted } from "vue";
import { ref, watch, onMounted } from "vue";
import setChart from "@/utils/setChart";
import getPieChart from "./utils/piechart";
import getMultiLineChart from "./utils/multiLineChart";
import {
getThinkPolicyIndustry,
getThinkPolicyIndustryTotal,
getThinkPolicyIndustryChange,
getHylyList,
getThinkPolicy
} from "@/api/thinkTank/overview";
import Img1 from "./images/img1.png";
import Img2 from "./images/img2.png";
import Img3 from "./images/img3.png";
import Img4 from "./images/img4.png";
import { useRouter } from "vue-router";
const router = useRouter();
// import Img1 from "./images/img1.png";
// import Img2 from "./images/img2.png";
// import Img3 from "./images/img3.png";
// import Img4 from "./images/img4.png";
// 提出建议领域分布
const box1Data = ref([
{
name: "半导体",
value: 50,
color: "#4096FF"
},
{
name: "电子设备",
value: 46,
color: "#FFA39E"
},
{
name: "显示技术",
value: 40,
color: "#ADC6FF"
},
{
name: "新能源",
value: 32,
color: "#FFC069"
},
{
name: "通信设备",
value: 31,
color: "#B5F5EC"
},
{
name: "汽车",
value: 30,
color: "#B37FEB"
},
{
name: "其他",
value: 24,
color: "#D6E4FF"
}
// {
// name: "半导体",
// value: 50,
// color: "#4096FF"
// },
// {
// name: "电子设备",
// value: 46,
// color: "#FFA39E"
// },
// {
// name: "显示技术",
// value: 40,
// color: "#ADC6FF"
// },
// {
// name: "新能源",
// value: 32,
// color: "#FFC069"
// },
// {
// name: "通信设备",
// value: 31,
// color: "#B5F5EC"
// },
// {
// name: "汽车",
// value: 30,
// color: "#B37FEB"
// },
// {
// name: "其他",
// value: 24,
// color: "#D6E4FF"
// }
]);
const box1SelectYear = ref("2025");
......@@ -212,52 +261,78 @@ const box1YearList = ref([
}
]);
const handleGetThinkPolicyIndustry = async () => {
try {
const parmas = {
id: router.currentRoute._value.params.id,
year: box1SelectYear.value
};
const res = await getThinkPolicyIndustry(parmas);
console.log("提出建议领域分布", res);
if (res.code === 200 && res.data) {
let data = [];
res.data.map(item => {
data.push({
name: item.industry,
value: item.amount,
percent: item.percent
});
});
box1Data.value = data;
const box1Chart = getPieChart(box1Data.value);
setChart(box1Chart, "box1Chart");
}
} catch (error) {
console.error("获取提出建议领域分布error", error);
}
};
// 相关政策领域分布
const box2Data = ref([
{
name: "集成电路",
value: 2,
total: 10,
per: 20,
color: "#CE4F51"
},
{
name: "人工智能",
value: 1,
total: 6,
per: 17,
color: "#055FC2"
},
{
name: "通信网络",
value: 2,
total: 7,
per: 26,
color: "#13A8A8"
},
{
name: "量子科技",
value: 1,
total: 2,
per: 50,
color: "#722ED1"
},
{
name: "生物科技",
value: 3,
total: 7,
per: 43,
color: "#FA8C16"
},
{
name: "能源",
value: 11,
total: 20,
per: 55,
color: "#69B1FF"
}
// {
// name: "集成电路",
// value: 2,
// total: 10,
// per: 20,
// color: "#CE4F51"
// },
// {
// name: "人工智能",
// value: 1,
// total: 6,
// per: 17,
// color: "#055FC2"
// },
// {
// name: "通信网络",
// value: 2,
// total: 7,
// per: 26,
// color: "#13A8A8"
// },
// {
// name: "量子科技",
// value: 1,
// total: 2,
// per: 50,
// color: "#722ED1"
// },
// {
// name: "生物科技",
// value: 3,
// total: 7,
// per: 43,
// color: "#FA8C16"
// },
// {
// name: "能源",
// value: 11,
// total: 20,
// per: 55,
// color: "#69B1FF"
// }
]);
const box2ColorList = ref(["#CE4F51", "#055FC2", "#13A8A8", "#722ED1", "#FA8C16", "#69B1FF"]);
const box2SelectYear = ref("2025");
const box2YearList = ref([
{
......@@ -274,26 +349,38 @@ const box2YearList = ref([
}
]);
const handleGetThinkPolicyIndustryTotal = async () => {
try {
const parmas = {
id: router.currentRoute._value.params.id,
year: box2SelectYear.value
};
const res = await getThinkPolicyIndustryTotal(parmas);
console.log("相关政策领域分布", res);
if (res.code === 200 && res.data) {
box2Data.value = res.data;
}
} catch (error) {
console.error("获取相关政策领域分布error", error);
}
};
// 热门研究方向变化趋势
const box3Data = ref({
title: ["2014", "2015", "2016", "2017", "2018", "2019", "2020", "2021", "2022", "2023", "2024", "2025"],
data: [
{
name: "人工智能",
value: [73, 32, 42, 48, 38, 49, 63, 75, 70, 86, 95, 87]
},
{
name: "集成电路",
value: [8, 3, 2, 8, 9, 10, 12, 18, 16, 18, 20, 22]
},
{
name: "量子科技",
value: [1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 2, 3]
}
]
// title: ["2024-Q1", "2024-Q2", "2024-Q3", "2024-Q4"],
// data: [
// {
// name: "新能源",
// value: [1,3,4,6]
// },
// {
// name: "人工智能",
// value: [1,3,4,2]
// },
// ...
// ]
});
const box3SelectYear = ref("2025");
const box3SelectYear = ref("2024");
const box3YearList = ref([
{
label: "2025",
......@@ -309,201 +396,203 @@ const box3YearList = ref([
}
]);
const handleGetThinkPolicyIndustryChange = async () => {
try {
const parmas = {
id: router.currentRoute._value.params.id,
year: box3SelectYear.value
};
const res = await getThinkPolicyIndustryChange(parmas);
console.log("热门研究方向变化趋势", res);
if (res.code === 200 && res.data) {
// 提取所有季度信息
const quarters = res.data.map(item => item.yearQuarter);
quarters.sort(); // 按时间排序
// 提取所有行业名称
const industries = new Set();
res.data.forEach(item => {
item.industryList.forEach(industry => {
industries.add(industry.industry);
});
});
// 构建前端数据结构
const frontendData = {
title: quarters,
data: []
};
industries.forEach(industry => {
const industryData = {
name: industry,
value: quarters.map(quarter => {
const quarterData = res.data.find(q => q.yearQuarter === quarter);
const industryAmount = quarterData?.industryList.find(i => i.industry === industry)?.amount || 0;
return industryAmount;
})
};
frontendData.data.push(industryData);
});
box3Data.value = frontendData;
let box3Chart = getMultiLineChart(
box3Data.value.title,
box3Data.value.data[0].value,
box3Data.value.data[1].value,
box3Data.value.data[2].value
);
setChart(box3Chart, "box3Chart");
}
} catch (error) {
console.error("获取热门研究方向变化趋势error", error);
}
};
// 搜索政策建议
const searchPolicy = ref("");
const yearList = ref([
{
label: "近一年发布",
value: "近一年发布"
value: 1
},
{
label: "近两年发布",
value: "近两年发布"
value: 2
},
{
label: "近三年发布",
value: "近三年发布"
value: 3
}
]);
const selectedYear = ref("近一年发布");
const selectedYear = ref(1);
// 科技领域
const areaList = ref(["人工智能", "半导体/芯片", "能源与气候", "国际关系", "经济政策", "国防与安全"]);
const selectedAreaList = ref(["人工智能", "半导体/芯片"]);
const areaList = ref([]);
const selectedAreaList = ref([]);
//获取科技领域
const handleGetHylyList = async () => {
try {
const res = await getHylyList();
console.log("智库研究类型信息", res);
if (res.code === 200 && res.data) {
areaList.value = res.data;
}
} catch (error) {
console.error("获取研究类型error", error);
}
};
const policyList = ref([
{
img: Img1,
title: "创建并定制针对人工智能技术的验证、确认与评估技术。",
time: "2025年6月26日",
desc: "保持美国在人工智能与机器学习领域的优势",
tagList: ["人工智能", "集成电路"],
fileList: [
{
type: "法案",
title: "2024《芯片科学法案》"
},
{
type: "法案",
title: "2024《芯片科学法案》"
}
]
},
{
img: Img1,
title: "为运用人工智能的新作战概念建立开发、测试与评估流程。",
time: "2025年6月26日",
desc: "保持美国在人工智能与机器学习领域的优势",
tagList: ["人工智能", "集成电路"],
fileList: [
{
type: "法案",
title: "2024《芯片科学法案》"
},
{
type: "法案",
title: "2024《芯片科学法案》"
}
]
},
{
img: Img1,
title: "通过制定和维护一个前瞻性的人工智能发展路线图来管理预期,该路线图应阐明国防部在近期(一至两年)、中期(三至五年)和远期(六至十年)部署人工智能的现实目标",
time: "2025年6月26日",
desc: "保持美国在人工智能与机器学习领域的优势",
tagList: ["人工智能", "集成电路"],
fileList: [
{
type: "法案",
title: "2024《芯片科学法案》"
},
{
type: "政令",
title: "2025《关于优化美军作战决策结构的建议》"
}
]
},
{
img: Img2,
title: "考虑采取更全面的方法来打击全球供应链中强迫劳动使用的选项。",
time: "2025年3月15日",
desc: " 美国贸易执法是否发挥了作用,能否做得更多?",
tagList: ["人工智能", "集成电路"],
fileList: [
{
type: "法案",
title: "2024《维吾尔强迫劳动预防法》"
}
]
},
{
img: Img2,
title: "与利益相关者共同收集证据,为关于贸易执法的公共讨论提供信息。",
time: "2025年3月15日",
desc: "美国贸易执法是否发挥了作用,能否做得更多?",
tagList: ["人工智能", "集成电路"],
fileList: [
{
type: "法案",
title: "2024《维吾尔强迫劳动预防法》"
}
]
},
{
img: Img2,
title: "推动清洁能源生产供内用,化石燃料重新配置出口。",
time: "2025年6月26日",
desc: "美国贸易执法是否发挥了作用,能否做得更多?",
tagList: ["人工智能", "集成电路"],
fileList: [
{
type: "法案",
title: "2024《重塑美国人口结构法案》"
},
{
type: "法案",
title: "2024《重塑美国人口结构法案》"
}
]
},
{
img: Img2,
title: "允许OPT的国际学生出国旅行并持多次入境签证重新进入美国。",
time: "2025年6月26日",
desc: "中美经济竞争:复杂经济和地缘政治关系中的收益与风险",
tagList: ["人工智能", "集成电路"],
fileList: [
{
type: "法案",
title: "2024《重塑美国人口结构法案》"
},
{
type: "法案",
title: "2025《开放人才法案》"
}
]
},
{
img: Img3,
title: "增加中国公民可获得的 H-1B 签证数量。",
time: "2025年6月26日",
desc: "中美经济竞争:复杂经济和地缘政治关系中的收益与风险",
tagList: ["人工智能", "集成电路"],
fileList: [
{
type: "法案",
title: "2024《重塑美国人口结构法案》"
},
{
type: "法案",
title: "2025《GENIUS法案》"
}
]
},
{
img: Img3,
title: "通过就业偏好类别增加绿卡的数量。",
time: "2025年6月26日",
desc: "中美经济竞争:复杂经济和地缘政治关系中的收益与风险",
tagList: ["人工智能", "集成电路"],
fileList: [
{
type: "法案",
title: "2024《重塑美国人口结构法案》"
},
{
type: "法案",
title: "2025《开放人才法案》"
}
]
},
{
img: Img4,
title: "推动清洁能源生产供内用,化石燃料重新配置出口。",
time: "2025年6月26日",
desc: "美国传统能源产业的未来:是走向终结还是持续发展?",
tagList: ["人工智能", "集成电路"],
fileList: [
{
type: "法案",
title: "2024《能源法案》"
}
]
}
// {
// img: Img1,
// title: "创建并定制针对人工智能技术的验证、确认与评估技术。",
// time: "2025年6月26日",
// desc: "保持美国在人工智能与机器学习领域的优势",
// tagList: ["人工智能", "集成电路"],
// fileList: [
// {
// type: "法案",
// title: "2024《芯片科学法案》"
// },
// {
// type: "法案",
// title: "2024《芯片科学法案》"
// }
// ]
// },
// {
// img: Img1,
// title: "为运用人工智能的新作战概念建立开发、测试与评估流程。",
// time: "2025年6月26日",
// desc: "保持美国在人工智能与机器学习领域的优势",
// tagList: ["人工智能", "集成电路"],
// fileList: [
// {
// type: "法案",
// title: "2024《芯片科学法案》"
// },
// {
// type: "法案",
// title: "2024《芯片科学法案》"
// }
// ]
// },
// {
// img: Img1,
// title: "通过制定和维护一个前瞻性的人工智能发展路线图来管理预期,该路线图应阐明国防部在近期(一至两年)、中期(三至五年)和远期(六至十年)部署人工智能的现实目标",
// time: "2025年6月26日",
// desc: "保持美国在人工智能与机器学习领域的优势",
// tagList: ["人工智能", "集成电路"],
// fileList: [
// {
// type: "法案",
// title: "2024《芯片科学法案》"
// },
// {
// type: "政令",
// title: "2025《关于优化美军作战决策结构的建议》"
// }
// ]
// },
]);
//获取当前时间x年前的日期
function getDateYearsAgo(years) {
// 获取当前日期
const currentDate = new Date();
// 计算指定年数之前的日期
const pastDate = new Date(currentDate.getFullYear() - years, currentDate.getMonth(), currentDate.getDate());
// 格式化日期为 "YYYY-MM-DD" 的形式
const year = pastDate.getFullYear();
const month = String(pastDate.getMonth() + 1).padStart(2, "0"); // 月份从0开始,需要加1
const day = String(pastDate.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
}
const total = ref(0);
const sort = ref(true);
const currentPage = ref(1);
// 处理页码改变事件
const handleCurrentChange = page => {
currentPage.value = page;
handleGetThinkPolicy();
};
const handleGetThinkPolicy = async () => {
try {
const parmas = {
id: router.currentRoute._value.params.id,
startDate: getDateYearsAgo(selectedYear.value),
sortFun: sort.value,
currentPage: currentPage.value,
pageSize: 10,
researchTypeIds: selectedAreaList.value.join(',')
};
const res = await getThinkPolicy(parmas);
console.log("智库政策", res);
if (res.code === 200 && res.data) {
policyList.value = res.data.content;
total.value = res.data.totalElements;
}
} catch (error) {
console.error("获取智库政策error", error);
}
};
watch(
() => selectedAreaList.value,
val => {
handleGetThinkPolicy();
}
);
onMounted(() => {
const box1Chart = getPieChart(box1Data.value);
setChart(box1Chart, "box1Chart");
let box3Chart = getMultiLineChart(
box3Data.value.title,
box3Data.value.data[0].value,
box3Data.value.data[1].value,
box3Data.value.data[2].value
);
setChart(box3Chart, "box3Chart");
handleGetThinkPolicyIndustry();
handleGetThinkPolicyIndustryTotal();
handleGetThinkPolicyIndustryChange();
handleGetHylyList();
handleGetThinkPolicy();
});
</script>
......@@ -511,12 +600,14 @@ onMounted(() => {
.wrap {
width: 100%;
height: 100%;
.top {
height: 420px;
width: 1600px;
margin: 24px 0;
display: flex;
gap: 16px;
.box {
width: 520px;
height: 420px;
......@@ -525,22 +616,26 @@ onMounted(() => {
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.box-header {
width: 520px;
height: 48px;
border-bottom: 1px solid rgba(234, 236, 238, 1);
display: flex;
position: relative;
.icon {
width: 20px;
height: 20px;
margin-top: 15px;
margin-left: 22px;
img {
width: 100%;
height: 100%;
}
}
.title {
margin-top: 11px;
margin-left: 18px;
......@@ -553,6 +648,7 @@ onMounted(() => {
letter-spacing: 0px;
text-align: left;
}
.box-header-right {
position: absolute;
top: 12px;
......@@ -567,30 +663,38 @@ onMounted(() => {
text-align: right;
}
}
.box-main {
height: 360px;
position: relative;
overflow: hidden;
#box1Chart {
height: 360px;
}
#box2Chart {
width: 470px;
margin: 0 auto;
margin-top: 50px;
height: 300px;
overflow: hidden;
overflow-y: auto;
.box2-item {
height: 30px;
margin-top: 20px;
display: flex;
align-items: center;
.icon {
width: 12px;
height: 12px;
border-radius: 6px;
}
.name {
width: 80px;
width: 120px;
margin-left: 7px;
margin-right: 23px;
height: 24px;
......@@ -602,8 +706,9 @@ onMounted(() => {
letter-spacing: 0px;
text-align: left;
}
.num {
width: 80px;
width: 100px;
margin-left: 10px;
height: 22px;
color: rgba(95, 101, 108, 1);
......@@ -613,6 +718,7 @@ onMounted(() => {
line-height: 22px;
text-align: right;
}
.per {
margin-left: 5px;
height: 22px;
......@@ -624,9 +730,11 @@ onMounted(() => {
}
}
}
#box3Chart {
height: 360px;
}
.select-box {
position: absolute;
z-index: 999;
......@@ -638,12 +746,15 @@ onMounted(() => {
}
}
}
.bottom {
width: 1600px;
.bottom-header {
height: 48px;
display: flex;
justify-content: space-between;
.search-box {
display: flex;
width: 300px;
......@@ -652,37 +763,44 @@ onMounted(() => {
border: 1px solid rgba(230, 231, 232, 1);
border-radius: 4px;
background: rgba(255, 255, 255, 1);
.icon {
width: 16px;
height: 16px;
margin: 8px 7px;
cursor: pointer;
img {
width: 100%;
height: 100%;
}
}
}
.select-box {
margin-right: 5px;
}
}
.bottom-main {
display: flex;
justify-content: space-between;
.left {
width: 300px;
height: 483px;
height: 800px;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.select-box {
margin-top: 21px;
.select-box-header {
display: flex;
gap: 17px;
.icon {
margin-top: 4px;
width: 8px;
......@@ -690,6 +808,7 @@ onMounted(() => {
background: var(--color-main-active);
border-radius: 0 4px 4px 0;
}
.title {
height: 26px;
color: var(--color-main-active);
......@@ -701,15 +820,18 @@ onMounted(() => {
text-align: left;
}
}
.select-main {
margin-left: 25px;
width: 160px;
}
.select-main1 {
width: 100px;
}
}
}
.right {
width: 1284px;
height: 1670px;
......@@ -718,27 +840,33 @@ onMounted(() => {
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.right-main {
margin: 17px auto;
width: 1209px;
height: 1540px;
.right-main-item {
height: 154px;
box-sizing: border-box;
padding-top: 8px;
border-bottom: 1px solid rgba(234, 236, 238, 1);
display: flex;
.item-left {
width: 57px;
height: 77px;
margin-top: 3px;
img {
width: 100%;
height: 100%;
}
}
.item-right {
margin-left: 15px;
.title {
// height: 24px;
color: rgba(59, 65, 75, 1);
......@@ -749,6 +877,7 @@ onMounted(() => {
letter-spacing: 0px;
text-align: left;
}
.info {
margin-top: 7px;
height: 22px;
......@@ -760,10 +889,12 @@ onMounted(() => {
letter-spacing: 0px;
text-align: left;
}
.tag-box {
margin-top: 7px;
display: flex;
gap: 8px;
.tag {
height: 22px;
padding: 0 8px;
......@@ -778,10 +909,12 @@ onMounted(() => {
line-height: 20px;
}
}
.file-box {
margin-top: 7px;
display: flex;
gap: 8px;
.file {
height: 32px;
padding: 0 8px;
......@@ -791,6 +924,7 @@ onMounted(() => {
gap: 8px;
border-radius: 4px;
background: rgba(246, 250, 255, 1);
.type {
height: 22px;
padding: 0 4px;
......@@ -802,6 +936,7 @@ onMounted(() => {
font-weight: 400;
line-height: 22px;
}
.title {
height: 24px;
color: rgba(5, 95, 194, 1);
......@@ -810,9 +945,11 @@ onMounted(() => {
font-weight: 400;
line-height: 24px;
}
.more {
width: 20px;
height: 20px;
img {
width: 100%;
height: 100%;
......@@ -823,12 +960,14 @@ onMounted(() => {
}
}
}
.right-footer {
margin: 0 auto;
width: 1209px;
height: 96px;
display: flex;
justify-content: space-between;
.info {
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
......
......@@ -3,19 +3,19 @@
<div class="header">
<div class="header-top">
<div class="header-top-left">
<img src="" alt="" />
<img :src="thinkTank.imageUrl" alt="" />
</div>
<div class="header-top-center">
<div class="center-top">
<div class="name">{{ "兰德公司" }}</div>
<div class="e-name">{{ "RAND Corporation" }}</div>
<div class="name">{{ thinkTank.name }}</div>
<div class="e-name">{{ thinkTank.ename }}</div>
</div>
<div class="center-center">
{{ "全球顶尖政策研究机构,专注于国家安全、科技政策、医疗卫生、能源政策、公共安全等领域的研究。 " }}
{{ thinkTank.describe }}
</div>
<div class="center-footer">
<div class="tag">{{ "国家安全" }}</div>
<div class="tag">{{ "科技政策" }}</div>
<div class="tag" v-for="tag,index in thinkTank.tags" :key="index">{{ tag.industryName }}</div>
</div>
</div>
<!-- <div class="header-top-right">{{ '查看智库官网' }}</div> -->
......@@ -58,19 +58,44 @@ import { ref, reactive, computed, onMounted } from "vue";
import ThinkDaynamics from "./thinkDynamics/index.vue"
import PolicyTracking from "./PolicyTracking/index.vue";
import ThinkInfo from "./thinkInfo/index.vue";
import {
getThinkTankSummary
} from "@/api/thinkTank/overview";
import { useRouter } from "vue-router";
const router = useRouter();
const tabActiveName = ref("智库动态");
const switchTab = name => {
tabActiveName.value = name;
};
const thinkTank = ref({})
// 获取智库基本信息
const handleGetThinkTankSummary = async () => {
try {
const parmas = {
id: router.currentRoute._value.params.id
}
const res = await getThinkTankSummary(parmas);
console.log("智库信息", res);
if (res.code === 200 && res.data) {
thinkTank.value = res.data
}
} catch (error) {
console.error("获取智库列表error", error);
}
};
onMounted(async () => {
handleGetThinkTankSummary()
});
</script>
<style lang="scss" scoped>
.wrap {
width: 1920px;
height: 984px;
.header {
width: 1920px;
height: 188px;
......@@ -81,18 +106,26 @@ const switchTab = name => {
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
position: relative;
.header-top {
margin-top: 24px;
display: flex;
.header-top-left {
width: 88px;
height: 88px;
background: purple;
img{
width: 100%;
height: 100%;
}
}
.header-top-center {
margin-left: 22px;
.center-top {
display: flex;
.name {
height: 26px;
color: rgba(59, 65, 75, 1);
......@@ -103,6 +136,7 @@ const switchTab = name => {
letter-spacing: 0px;
text-align: left;
}
.e-name {
margin-left: 11px;
height: 26px;
......@@ -115,6 +149,7 @@ const switchTab = name => {
text-align: left;
}
}
.center-center {
margin-top: 4px;
width: 769px;
......@@ -126,10 +161,12 @@ const switchTab = name => {
line-height: 24px;
letter-spacing: 0px;
}
.center-footer {
margin-top: 9px;
display: flex;
gap: 8px;
.tag {
height: 26px;
line-height: 26px;
......@@ -148,6 +185,7 @@ const switchTab = name => {
}
}
}
.header-footer {
width: 340px;
height: 48px;
......@@ -156,8 +194,9 @@ const switchTab = name => {
left: 160px;
display: flex;
gap: 24px;
.tab {
width: 92px;
width: 94px;
height: 48px;
display: flex;
align-items: center;
......@@ -165,14 +204,17 @@ const switchTab = name => {
gap: 4px;
cursor: pointer;
border-bottom: 2px solid transparent;
.icon {
width: 16px;
height: 16px;
img {
width: 100%;
height: 100%;
}
}
.text {
height: 24px;
color: rgba(59, 65, 75, 1);
......@@ -181,23 +223,28 @@ const switchTab = name => {
font-weight: 400;
line-height: 24px;
}
.textActive {
color: rgba(5, 95, 194, 1);
font-weight: 700;
}
}
.tabActive {
border-bottom: 2px solid rgba(5, 95, 194, 1);
}
}
}
.main {
margin: 0 auto;
width: 1600px;
.main-header {
height: 64px;
display: flex;
justify-content: space-between;
.search-box {
margin-top: 16px;
display: flex;
......@@ -207,25 +254,30 @@ const switchTab = name => {
border: 1px solid rgba(230, 231, 232, 1);
border-radius: 4px;
background: rgba(255, 255, 255, 1);
.icon {
width: 16px;
height: 16px;
margin: 8px 7px;
cursor: pointer;
img {
width: 100%;
height: 100%;
}
}
}
.select-box {
margin-top: 16px;
margin-right: 5px;
}
}
.main-content {
display: flex;
gap: 16px;
.left {
width: 300px;
height: 806px;
......@@ -235,11 +287,14 @@ const switchTab = name => {
box-shadow: 0px 0px 20px 0px rgba(94, 95, 95, 0.1);
background: rgba(255, 255, 255, 1);
position: relative;
.select-box {
margin-top: 21px;
.select-box-header {
display: flex;
gap: 17px;
.icon {
margin-top: 4px;
width: 8px;
......@@ -247,6 +302,7 @@ const switchTab = name => {
background: var(--color-main-active);
border-radius: 0 4px 4px 0;
}
.title {
height: 24px;
color: var(--color-main-active);
......@@ -258,39 +314,47 @@ const switchTab = name => {
text-align: left;
}
}
.select-main {
margin-left: 25px;
}
.select-main1 {
width: 100px;
}
}
}
.right {
width: 1284px;
height: 1377px;
.card-box {
width: 1284px;
height: 1248px;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.footer-card {
width: 418px;
height: 300px;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.footer-card-top {
width: 384px;
height: 206px;
margin: 0 auto;
margin-top: 15px;
img {
width: 100%;
height: 100%;
}
}
.footer-card-title {
margin: 0 auto;
margin-top: 13px;
......@@ -302,6 +366,7 @@ const switchTab = name => {
font-weight: 700;
line-height: 24px;
}
.footer-card-footer {
margin: 0 auto;
margin-top: 5px;
......@@ -317,10 +382,12 @@ const switchTab = name => {
}
}
}
.right-footer {
margin-top: 43px;
display: flex;
justify-content: space-between;
.info {
height: 19px;
color: rgba(132, 136, 142, 1);
......@@ -341,6 +408,7 @@ const switchTab = name => {
box-shadow: none;
border-radius: 10px;
}
:deep(.el-input__wrapper:hover) {
box-shadow: none !important;
}
......
......@@ -2,17 +2,25 @@
<div class="wrap">
<div class="main-header">
<div class="search-box">
<el-input placeholder="搜索智库报告" v-model="searchReport" style="width: 270px" />
<div class="icon">
<img src="./images/search-icon.png" alt="" />
<img src="./images/search-icon.png" alt="" @click="handleGetThinkDynamicsReport()" />
</div>
</div>
<div>
<div class="select-box">
<el-select v-model="selectedYear" placeholder="选择时间" style="width: 120px">
<el-option v-for="item in yearList" :key="item.value" :label="item.label" :value="item.value" />
<el-option @click="handleGetThinkDynamicsReport()" v-for="item in yearList" :key="item.value"
:label="item.label" :value="item.value" />
</el-select>
<el-select v-model="sort" placeholder="发布时间" style="width: 120px; margin-left: 8px;">
<el-option @click="handleGetThinkDynamicsReport()" :key="true" label="正序" :value="true" />
<el-option @click="handleGetThinkDynamicsReport()" :key="false" label="倒序" :value="false" />
</el-select>
</div>
</div>
</div>
<div class="main-content">
<div class="left">
<div class="select-box">
......@@ -22,14 +30,9 @@
</div>
<div class="select-main">
<div class="checkbox-group">
<el-checkbox
v-for="type in reportTypeList"
:key="type.id"
v-model="selectedReportTypeList"
:label="type.id"
class="filter-checkbox"
>
{{ type.name }}
<el-checkbox v-for="type in reportTypeList" :key="type.id" v-model="selectedReportTypeList"
:label="type.id" class="filter-checkbox" @change="handleGetThinkDynamicsReport()">
{{ type.typeName }}
</el-checkbox>
</div>
</div>
......@@ -41,13 +44,8 @@
</div>
<div class="select-main">
<div class="checkbox-group">
<el-checkbox
v-for="type in researchTypeList"
:key="type.id"
v-model="selectedResearchTypeList"
:label="type.id"
class="filter-checkbox"
>
<el-checkbox v-for="type in researchTypeList" :key="type.id" v-model="selectedResearchTypeList"
:label="type.id" class="filter-checkbox" @change="handleGetThinkDynamicsReport()">
{{ type.name }}
</el-checkbox>
</div>
......@@ -59,31 +57,33 @@
<div class="title">{{ "作者" }}</div>
</div>
<div class="input-main">
<el-input placeholder="输入作者名字" v-model="author" />
<el-input placeholder="输入作者名字" v-model="author" @input="handleGetThinkDynamicsReport()" />
</div>
</div>
</div>
<div class="right">
<div class="card-box">
<div class="footer-card" v-for="(item, index) in curFooterList" :key="index" @click="handleToReportDetail()">
<div class="footer-card" v-for="(item, index) in curFooterList" :key="index"
@click="handleToReportDetail(item.id)">
<div class="footer-card-top">
<img :src="item.img" alt="" />
<img :src="item.imageUrl" alt="" />
</div>
<div class="footer-card-title">
{{ item.title }}
{{ item.name }}
</div>
<div class="footer-card-footer">
<div class="time">{{ item.time }}</div>
<div class="from">{{ item.from }}</div>
<div class="time">{{ item.times }}</div>
<div class="from">{{ item.thinkTankName }}</div>
</div>
</div>
</div>
<div class="right-footer">
<div class="info">
{{ `共1059篇智库报告` }}
{{ total }}篇智库报告
</div>
<div class="page-box">
<el-pagination :page-size="12" background layout="prev, pager, next" :total="120" />
<el-pagination :page-size="12" background layout="prev, pager, next" :total="total"
@current-change="handleCurrentChange" :current-page="currentPage" />
</div>
</div>
</div>
......@@ -93,25 +93,34 @@
<script setup>
import { ref, reactive, onMounted } from "vue";
import router from "@/router";
import Img1 from "./images/img1.png";
import Img2 from "./images/img2.png";
import Img3 from "./images/img3.png";
import Img4 from "./images/img4.png";
import Img5 from "./images/img5.png";
import Img6 from "./images/img6.png";
import Img7 from "./images/img7.png";
import Img8 from "./images/img8.png";
import Img9 from "./images/img9.png";
import Img10 from "./images/img10.png";
import Img11 from "./images/img11.png";
import Img12 from "./images/img12.png";
const handleToReportDetail = () => {
// import Img1 from "./images/img1.png";
// import Img2 from "./images/img2.png";
// import Img3 from "./images/img3.png";
// import Img4 from "./images/img4.png";
// import Img5 from "./images/img5.png";
// import Img6 from "./images/img6.png";
// import Img7 from "./images/img7.png";
// import Img8 from "./images/img8.png";
// import Img9 from "./images/img9.png";
// import Img10 from "./images/img10.png";
// import Img11 from "./images/img11.png";
// import Img12 from "./images/img12.png";
//getThinkDynamicsReport
import {
getThinkDynamicsReportType,
getHylyList,
getThinkDynamicsReport
} from "@/api/thinkTank/overview";
import { useRouter } from "vue-router";
const router = useRouter();
const searchReport = ref('')
const handleToReportDetail = (id) => {
const route = router.resolve({
name: 'ReportDetail',
params: {
id: 1
id: id
}
});
window.open(route.href, "_blank");
......@@ -135,7 +144,7 @@ const reportTypeList = ref([
name: '期刊文章',
},
])
const selectedReportTypeList = ref(['研究报告'])
const selectedReportTypeList = ref([])
const researchTypeList = ref([
{
......@@ -155,108 +164,195 @@ const researchTypeList = ref([
name: '期刊文章',
},
])
const selectedResearchTypeList = ref(['研究报告'])
const selectedResearchTypeList = ref([])
const author = ref('') // 作者
const curFooterList = ref([
{
title: "中国对AI的转型产业政策",
time: "2025年6月26日",
from: "兰德科技智库",
img: Img1
},
{
title: "中美对抗、竞争和合作跨越人工智能通用领域...",
time: "2025年6月26日",
from: "兰德科技智库",
img: Img2
},
{
title: "中国、智慧城市和中东:地区和美国的选择",
time: "2025年6月26日",
from: "兰德科技智库",
img: Img3
},
{
title: "中国对AI的转型产业政策",
time: "2025年6月26日",
from: "兰德科技智库",
img: Img4
},
{
title: "中美经济竞争:复杂经济和地缘政治关系中的...",
time: "2025年6月26日",
from: "兰德科技智库",
img: Img5
},
{
title: "中国、智慧城市和中东:留给地区和美国的选择",
time: "2025年6月26日",
from: "兰德科技智库",
img: Img6
},
{
title: "中国对AI的转型产业政策",
time: "2025年6月26日",
from: "兰德科技智库",
img: Img7
},
{
title: "中美对抗、竞争和合作跨越人工智能通用领域...",
time: "2025年6月26日",
from: "",
img: Img8
},
{
title: "中国、智慧城市和中东:地区和美国的选择",
time: "2025年6月26日",
from: "兰德科技智库",
img: Img9
},
{
title: "中国对AI的转型产业政策",
time: "2025年6月26日",
from: "兰德科技智库",
img: Img10
},
{
title: "中美对抗、竞争和合作跨越人工智能通用领域...",
time: "2025年6月26日",
from: "兰德科技智库",
img: Img11
},
{
title: "中国、智慧城市和中东:地区和美国的选择",
time: "2025年6月26日",
from: "兰德科技智库",
img: Img12
}
// {
// title: "中国对AI的转型产业政策",
// time: "2025年6月26日",
// from: "兰德科技智库",
// img: Img1
// },
// {
// title: "中美对抗、竞争和合作跨越人工智能通用领域...",
// time: "2025年6月26日",
// from: "兰德科技智库",
// img: Img2
// },
// {
// title: "中国、智慧城市和中东:地区和美国的选择",
// time: "2025年6月26日",
// from: "兰德科技智库",
// img: Img3
// },
// {
// title: "中国对AI的转型产业政策",
// time: "2025年6月26日",
// from: "兰德科技智库",
// img: Img4
// },
// {
// title: "中美经济竞争:复杂经济和地缘政治关系中的...",
// time: "2025年6月26日",
// from: "兰德科技智库",
// img: Img5
// },
// {
// title: "中国、智慧城市和中东:留给地区和美国的选择",
// time: "2025年6月26日",
// from: "兰德科技智库",
// img: Img6
// },
// {
// title: "中国对AI的转型产业政策",
// time: "2025年6月26日",
// from: "兰德科技智库",
// img: Img7
// },
// {
// title: "中美对抗、竞争和合作跨越人工智能通用领域...",
// time: "2025年6月26日",
// from: "",
// img: Img8
// },
// {
// title: "中国、智慧城市和中东:地区和美国的选择",
// time: "2025年6月26日",
// from: "兰德科技智库",
// img: Img9
// },
// {
// title: "中国对AI的转型产业政策",
// time: "2025年6月26日",
// from: "兰德科技智库",
// img: Img10
// },
// {
// title: "中美对抗、竞争和合作跨越人工智能通用领域...",
// time: "2025年6月26日",
// from: "兰德科技智库",
// img: Img11
// },
// {
// title: "中国、智慧城市和中东:地区和美国的选择",
// time: "2025年6月26日",
// from: "兰德科技智库",
// img: Img12
// }
]);
const yearList = ref([
{
label: "近一年发布",
value: "近一年发布"
value: 1
},
{
label: "近两年发布",
value: "近两年发布"
value: 2
},
{
label: "近三年发布",
value: "近三年发布"
value: 3
}
]);
const selectedYear = ref("近一年发布");
const selectedYear = ref(1);
const sort = ref(true)
//获取当前时间x年前的日期
function getDateYearsAgo(years) {
// 获取当前日期
const currentDate = new Date();
// 计算指定年数之前的日期
const pastDate = new Date(currentDate.getFullYear() - years, currentDate.getMonth(), currentDate.getDate());
// 格式化日期为 "YYYY-MM-DD" 的形式
const year = pastDate.getFullYear();
const month = String(pastDate.getMonth() + 1).padStart(2, "0"); // 月份从0开始,需要加1
const day = String(pastDate.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
}
//获取智库研究类型
const handleGetThinkDynamicsReportType = async () => {
try {
const res = await getThinkDynamicsReportType();
console.log("智库研究类型信息", res);
if (res.code === 200 && res.data) {
reportTypeList.value = res.data
}
} catch (error) {
console.error("获取研究类型error", error);
}
};
//获取行业领域字典
// getHylyList
const handleGetHylyList = async () => {
try {
const res = await getHylyList();
console.log("行业领域字典", res);
if (res.code === 200 && res.data) {
researchTypeList.value = res.data;
}
} catch (error) {
console.error("获取行业领域字典error", error);
}
};
const currentPage = ref(1);
// 处理页码改变事件
const handleCurrentChange = page => {
currentPage.value = page;
handleGetThinkDynamicsReport()
};
// 获取智库动态报告
const handleGetThinkDynamicsReport = async () => {
console.log(selectedReportTypeList.value, 'selectedReportTypeList.value')
console.log(selectedResearchTypeList.value, 'selectedResearchTypeList.value')
try {
const parmas = {
id: router.currentRoute._value.params.id,
startDate: getDateYearsAgo(selectedYear.value),
parmas: {
sortFun: sort.value,
authorName: author.value ? author.value : null,
currentPage: currentPage.value,
pageSize: 12,
reportTypeIds: selectedReportTypeList.value ? selectedReportTypeList.value : null,
researchTypeIds: selectedResearchTypeList.value ? selectedResearchTypeList.value : null
}
}
const res = await getThinkDynamicsReport(parmas);
console.log("智库动态报告", res);
if (res.code === 200 && res.data) {
curFooterList.value = res.data.content
total.value = res.data.totalElements
}
} catch (error) {
console.error("获取智库动态报告error", error);
}
};
const total = ref(0)
onMounted(async () => {
handleGetThinkDynamicsReportType()
handleGetHylyList()
handleGetThinkDynamicsReport()
});
</script>
<style lang="scss" scoped>
.main-header {
height: 64px;
width: 1600px;
display: flex;
justify-content: space-between;
.search-box {
margin-top: 16px;
display: flex;
......@@ -266,39 +362,48 @@ const selectedYear = ref("近一年发布");
border: 1px solid rgba(230, 231, 232, 1);
border-radius: 4px;
background: rgba(255, 255, 255, 1);
.icon {
width: 16px;
height: 16px;
margin: 8px 7px;
cursor: pointer;
img {
width: 100%;
height: 100%;
}
}
}
.select-box {
margin-top: 16px;
margin-right: 5px;
}
}
.main-content {
display: flex;
gap: 16px;
.left {
width: 300px;
height: 520px;
height: 100%;
padding-bottom: 36px;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(94, 95, 95, 0.1);
background: rgba(255, 255, 255, 1);
position: relative;
.select-box {
margin-top: 21px;
.select-box-header {
display: flex;
gap: 17px;
.icon {
margin-top: 4px;
width: 8px;
......@@ -306,6 +411,7 @@ const selectedYear = ref("近一年发布");
background: var(--color-main-active);
border-radius: 0 4px 4px 0;
}
.title {
height: 26px;
color: var(--color-main-active);
......@@ -317,13 +423,16 @@ const selectedYear = ref("近一年发布");
text-align: left;
}
}
.select-main {
margin-left: 25px;
}
.select-main1 {
width: 100px;
}
.input-main{
.input-main {
margin: 10px auto;
width: 250px;
height: 34px;
......@@ -332,15 +441,18 @@ const selectedYear = ref("近一年发布");
}
}
}
.right {
width: 1284px;
height: 1377px;
.card-box {
width: 1284px;
height: 1248px;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.footer-card {
width: 418px;
height: 300px;
......@@ -348,21 +460,26 @@ const selectedYear = ref("近一年发布");
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
transition: transform 0.3s ease, box-shadow 0.3s ease;
&:hover {
transform: translateY(-3px);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
}
cursor: pointer;
.footer-card-top {
width: 384px;
height: 206px;
margin: 0 auto;
margin-top: 15px;
img {
width: 100%;
height: 100%;
}
}
.footer-card-title {
margin: 0 auto;
margin-top: 13px;
......@@ -373,7 +490,11 @@ const selectedYear = ref("近一年发布");
font-size: 18px;
font-weight: 700;
line-height: 24px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.footer-card-footer {
margin: 0 auto;
margin-top: 5px;
......@@ -389,10 +510,12 @@ const selectedYear = ref("近一年发布");
}
}
}
.right-footer {
margin-top: 43px;
display: flex;
justify-content: space-between;
.info {
height: 19px;
color: rgba(132, 136, 142, 1);
......@@ -410,4 +533,85 @@ const selectedYear = ref("近一年发布");
.filter-checkbox {
width: 180px;
}
.page {
width: 1600px;
height: 40px;
display: flex;
align-items: center;
justify-content: space-between;
margin: 36px 0 0 0;
padding-left: 11px;
.count {
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
}
:deep(.el-pagination) {
display: flex;
align-items: center;
}
:deep(.el-pagination.is-background .el-pager li) {
min-width: 32px;
height: 32px;
line-height: 32px;
border-radius: 6px;
margin: 0 6px;
border: 1px solid rgba(0, 0, 0, 0.15);
background-color: #fff;
color: rgb(95, 101, 108);
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
}
:deep(.el-pagination.is-background .el-pager li.is-active) {
background-color: #fff;
color: rgba(22, 119, 255, 1);
border-color: rgba(22, 119, 255, 1);
}
:deep(.el-pagination.is-background .el-pager li.is-ellipsis) {
border: none;
background-color: transparent;
color: rgb(95, 101, 108);
min-width: 16px;
margin: 0 6px;
}
:deep(.el-pagination.is-background .btn-prev),
:deep(.el-pagination.is-background .btn-next) {
min-width: 32px;
height: 32px;
border-radius: 6px;
border: 1px solid rgba(0, 0, 0, 0.15);
background-color: #fff;
color: rgb(95, 101, 108);
font-size: 16px;
font-family: "Microsoft YaHei";
margin: 0 6px;
}
:deep(.el-pagination.is-background .btn-prev.is-disabled),
:deep(.el-pagination.is-background .btn-next.is-disabled) {
color: rgba(95, 101, 108, 0.45);
border-color: rgb(235, 238, 242);
background-color: #fff;
}
</style>
\ No newline at end of file
......@@ -8,7 +8,7 @@
</div>
<div class="left-top-main">
<div class="img-box">
<img :src="basicInfo.img" alt="" />
<img :src="basicInfo.imageUrl" alt="" />
</div>
<div class="left-top-item">
<div class="item-left">{{ "国家:" }}</div>
......@@ -16,7 +16,7 @@
</div>
<div class="left-top-item">
<div class="item-left">{{ "成立时间:" }}</div>
<div class="item-right">{{ basicInfo.time }}</div>
<div class="item-right">{{ basicInfo.foundingDate }}</div>
</div>
<div class="left-top-item">
<div class="item-left">{{ "总部位置:" }}</div>
......@@ -24,15 +24,15 @@
</div>
<div class="left-top-item">
<div class="item-left">{{ "机构性质:" }}</div>
<div class="item-right">{{ basicInfo.type }}</div>
<div class="item-right">{{ basicInfo.nature }}</div>
</div>
<div class="left-top-item">
<div class="item-left">{{ "员工数量:" }}</div>
<div class="item-right">{{ basicInfo.num }}</div>
<div class="item-right">{{ basicInfo.memnum }}名员工</div>
</div>
<div class="left-top-item">
<div class="item-left">{{ "年度预算:" }}</div>
<div class="item-right">{{ basicInfo.money }}</div>
<div class="item-right">{{ basicInfo.budget }}亿美元</div>
</div>
</div>
</div>
......@@ -42,11 +42,11 @@
<div class="title">{{ "全球分支机构" }}</div>
</div>
<div class="left-bottom-main">
<div class="left-bottom-item">
<div class="item-left">{{ "北美:" }}</div>
<div class="item-right">{{ worldInfo.position1 }}</div>
<div class="left-bottom-item" v-for="item in worldInfo">
<div class="item-left">{{ item.area }}:</div>
<div class="item-right">{{ item.city }}</div>
</div>
<div class="left-bottom-item">
<!-- <div class="left-bottom-item">
<div class="item-left">{{ "欧洲:" }}</div>
<div class="item-right">{{ worldInfo.position2 }}</div>
</div>
......@@ -57,7 +57,7 @@
<div class="left-bottom-item">
<div class="item-left">{{ "澳大利亚:" }}</div>
<div class="item-right">{{ worldInfo.position4 }}</div>
</div>
</div> -->
</div>
</div>
</div>
......@@ -82,15 +82,15 @@
<div class="box1-main-left">
<div class="card1">
<div class="card-title">{{ "总计" }}</div>
<div class="card-num">{{ box1LeftData.total }}</div>
<div class="card-num">{{ box1LeftData.totalJe / 100000000 }}亿美元</div>
</div>
<div class="card2">
<div class="card-title">{{ "政府部门" }}</div>
<div class="card-num">{{ box1LeftData.gov }}</div>
<div class="card-num">{{ box1LeftData.zfJe }}亿美元</div>
</div>
<div class="card3">
<div class="card-title">{{ "其他机构" }}</div>
<div class="card-num">{{ box1LeftData.other }}</div>
<div class="card-num">{{ box1LeftData.otherJe }}亿美元</div>
</div>
</div>
<div class="box1-main-right" id="box1Chart"></div>
......@@ -120,12 +120,8 @@
<img src="@/assets/images/icon/card-btn-right.png" alt="" />
</div>
<div class="box2-line-box"></div>
<div
class="box2-item"
:class="{ box2ItemFooter: index % 2 }"
v-for="(item, index) in timeLineList"
:key="index"
>
<div class="box2-item" :class="{ box2ItemFooter: index % 2 }" v-for="(item, index) in timeLineList"
:key="index">
<div class="point" :class="{ pointFooter: index % 2 }">
<img src="./images/point.png" alt="" />
</div>
......@@ -133,7 +129,7 @@
<div class="title">{{ item.time }}</div>
</div>
<div class="box2-item-content">
{{ item.content }}
{{ item.describe }}
</div>
</div>
</div>
......@@ -159,14 +155,14 @@
<div class="box3-main-right">
<div class="box3-right-item" v-for="(item, index) in box3RightData" :key="index">
<div class="icon">
<img :src="item.img" alt="" />
<img :src="item.imageUrl" alt="" />
</div>
<div class="info">
<div class="info-header">
<div class="name">{{ item.name }}</div>
<div class="position">{{ item.postion }}</div>
<div class="position">{{ item.positionTitle }}</div>
</div>
<div class="info-footer">{{ item.desc }}</div>
<div class="info-footer">{{ item.describe }}</div>
</div>
</div>
</div>
......@@ -181,7 +177,18 @@ import { ref, onMounted } from "vue";
import setChart from "@/utils/setChart";
import getPieChart from "./utils/piechart";
import getTreeMapChart from "./utils/treeMapChart";
import {
getThinkTankInfoBasic,
getThinkTankInfoBranch,
getThinkTankFundsTotal,
getThinkTankFundsSource,
getThinkTankResearchAreae,
getThinkTankPerson
} from "@/api/thinkTank/overview";
import { useRouter } from "vue-router";
const router = useRouter();
import InfoImg from "./images/img.png";
import Icon1 from "./images/icon1.png";
import Icon2 from "./images/icon2.png";
......@@ -191,14 +198,29 @@ import Icon5 from "./images/icon5.png";
// 基本信息
const basicInfo = ref({
img: InfoImg,
country: "美国",
time: "1948年",
position: "美国加利福尼亚州圣莫尼卡 ",
type: "非营利性研究与分析机构 ",
num: "约1,700名员工 ",
money: "约3.5亿美元 "
// img: InfoImg,
// country: "美国",
// time: "1948年",
// position: "美国加利福尼亚州圣莫尼卡 ",
// type: "非营利性研究与分析机构 ",
// num: "约1,700名员工 ",
// money: "约3.5亿美元 "
});
// getThinkTankInfoBasic
const handleGetThinkTankInfoBasic = async () => {
try {
const res = await getThinkTankInfoBasic(router.currentRoute._value.params.id);
console.log("基本信息", res);
if (res.code === 200 && res.data) {
basicInfo.value = res.data
}
} catch (error) {
console.error("获取基本信息error", error);
}
};
// 全球分支机构
const worldInfo = ref({
position1: "圣莫尼卡(总部)、华盛顿特区、匹兹堡、波士顿",
......@@ -207,6 +229,41 @@ const worldInfo = ref({
position4: "堪培拉 "
});
// 全球分支机构
const handleGetThinkTankInfoBranch = async () => {
try {
const res = await getThinkTankInfoBranch(router.currentRoute._value.params.id);
console.log("全球分支机构", res);
if (res.code === 200 && res.data) {
// 创建一个对象来存储分组后的数据
const groupedData = {};
// 遍历数据,按 area 分组
res.data.forEach(item => {
if (!groupedData[item.area]) {
groupedData[item.area] = {
area: item.area,
city: []
};
}
groupedData[item.area].city.push(item.city);
});
// 将每个分组中的 city 转换为逗号分隔的字符串
const result = Object.values(groupedData).map(group => ({
area: group.area,
city: group.city.join(", ")
}));
worldInfo.value = result
}
} catch (error) {
console.error("获取全球分支机构error", error);
}
};
// 经费来源
const box1LeftData = ref({
total: "4.358亿美元",
......@@ -252,6 +309,41 @@ const box1ChartData = ref([
}
]);
const handleGetThinkTankFundsTotal = async () => {
try {
const res = await getThinkTankFundsTotal(router.currentRoute._value.params.id);
console.log("获取经费来源统计", res);
if (res.code === 200 && res.data) {
box1LeftData.value = res.data
}
} catch (error) {
console.error("获取经费来源统计error", error);
}
};
const handleGetThinkTankFundsSource = async () => {
try {
const res = await getThinkTankFundsSource(router.currentRoute._value.params.id);
console.log("获取经费来源", res);
if (res.code === 200 && res.data) {
let data = []
res.data.map(item => {
data.push({
name: item.institution,
value: item.amount,
})
})
box1ChartData.value = data
const box1Chart = getPieChart(box1ChartData.value);
setChart(box1Chart, "box1Chart");
}
} catch (error) {
console.error("获取经费来源error", error);
}
};
// 研究领域演变
const timeLineList = ref([
{
......@@ -276,7 +368,18 @@ const timeLineList = ref([
}
]);
const handleGetThinkTankResearchAreae = async () => {
try {
const res = await getThinkTankResearchAreae(router.currentRoute._value.params.id);
console.log("研究领域演变", res);
if (res.code === 200 && res.data) {
timeLineList.value = res.data
}
} catch (error) {
console.error("获取研究领域演变error", error);
}
};
// 核心研究人员
const handleBox3Chart = () => {
// 将分类数据转换为树状图格式
......@@ -361,9 +464,26 @@ const box3RightData = ref([
}
]);
const handleGetThinkPerson = async () => {
try {
const res = await getThinkTankPerson(router.currentRoute._value.params.id);
console.log("核心研究人员", res);
if (res.code === 200 && res.data) {
box3RightData.value = res.data
}
} catch (error) {
console.error("获取核心研究人员error", error);
}
};
onMounted(() => {
const box1Chart = getPieChart(box1ChartData.value);
setChart(box1Chart, "box1Chart");
handleGetThinkTankInfoBasic()
handleGetThinkTankInfoBranch()
handleGetThinkTankFundsTotal()
handleGetThinkTankFundsSource()
handleGetThinkTankResearchAreae()
handleGetThinkPerson()
handleBox3Chart();
});
......@@ -375,17 +495,20 @@ onMounted(() => {
height: 100%;
display: flex;
gap: 16px;
.left {
margin-top: 16px;
width: 480px;
height: 796px;
height: 100%;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.left-box-header {
display: flex;
.icon {
margin-top: 5px;
width: 8px;
......@@ -393,6 +516,7 @@ onMounted(() => {
border-radius: 0 4px 4px 0;
background: var(--color-main-active);
}
.title {
margin-left: 14px;
color: var(--color-main-active);
......@@ -404,26 +528,31 @@ onMounted(() => {
text-align: left;
}
}
.left-top {
margin-top: 14px;
height: 515px;
.img-box {
width: 437px;
height: 204px;
margin: 0 auto;
margin-top: 16px;
margin-bottom: 22px;
img {
width: 100%;
height: 100%;
}
}
.left-top-item {
display: flex;
margin-top: 12px;
width: 332px;
height: 24px;
margin-left: 34px;
.item-left {
width: 88px;
height: 24px;
......@@ -435,6 +564,7 @@ onMounted(() => {
letter-spacing: 1px;
text-align: left;
}
.item-right {
width: 240px;
height: 24px;
......@@ -448,14 +578,17 @@ onMounted(() => {
}
}
}
.left-bottom {
.left-bottom-main {
margin-top: 4px;
.left-bottom-item {
display: flex;
width: 354px;
margin-left: 34px;
margin-top: 12px;
.item-left {
width: 88px;
height: 24px;
......@@ -467,6 +600,7 @@ onMounted(() => {
letter-spacing: 1px;
text-align: left;
}
.item-right {
margin-left: 4px;
width: 240px;
......@@ -482,9 +616,11 @@ onMounted(() => {
}
}
}
.right {
width: 1104px;
height: 1245px;
.box {
width: 1104px;
height: 390px;
......@@ -494,10 +630,12 @@ onMounted(() => {
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.box-header {
height: 56px;
display: flex;
position: relative;
.header-left {
margin-top: 20px;
width: 8px;
......@@ -505,6 +643,7 @@ onMounted(() => {
border-radius: 0 4px 4px 0;
background: var(--color-main-active);
}
.title {
margin-left: 14px;
margin-top: 20px;
......@@ -516,6 +655,7 @@ onMounted(() => {
font-weight: 700;
line-height: 16px;
}
.header-right {
position: absolute;
top: 14px;
......@@ -523,9 +663,11 @@ onMounted(() => {
display: flex;
justify-content: flex-end;
gap: 4px;
.icon {
width: 28px;
height: 28px;
img {
width: 100%;
height: 100%;
......@@ -533,17 +675,21 @@ onMounted(() => {
}
}
}
.box1-main {
display: flex;
.box1-main-left {
width: 156px;
margin-left: 41px;
margin-top: 26px;
.card1 {
width: 156px;
height: 72px;
border-radius: 4px;
background: linear-gradient(180deg, rgba(230, 244, 255, 1), rgba(230, 244, 255, 0) 100%);
.card-title {
height: 24px;
margin-top: 8px;
......@@ -556,6 +702,7 @@ onMounted(() => {
letter-spacing: 0px;
text-align: left;
}
.card-num {
margin-top: 5px;
margin-left: 19px;
......@@ -569,12 +716,14 @@ onMounted(() => {
text-align: left;
}
}
.card2 {
margin-top: 20px;
width: 156px;
height: 72px;
border-radius: 4px;
background: linear-gradient(180deg, rgba(255, 241, 240, 1), rgba(255, 241, 240, 0) 100%);
.card-title {
height: 24px;
margin-top: 8px;
......@@ -587,6 +736,7 @@ onMounted(() => {
letter-spacing: 0px;
text-align: left;
}
.card-num {
margin-top: 5px;
margin-left: 19px;
......@@ -600,12 +750,14 @@ onMounted(() => {
text-align: left;
}
}
.card3 {
margin-top: 20px;
width: 156px;
height: 72px;
border-radius: 4px;
background: linear-gradient(180deg, rgba(230, 255, 251, 1), rgba(230, 255, 251, 0) 100%);
.card-title {
height: 24px;
margin-top: 8px;
......@@ -618,6 +770,7 @@ onMounted(() => {
letter-spacing: 0px;
text-align: left;
}
.card-num {
margin-top: 5px;
margin-left: 19px;
......@@ -632,6 +785,7 @@ onMounted(() => {
}
}
}
.box1-main-right {
margin-left: 38px;
margin-top: 26px;
......@@ -639,11 +793,13 @@ onMounted(() => {
height: 270px;
}
}
.box2-main {
height: 320px;
display: flex;
position: relative;
padding-left: 150px;
.box2-arrow-left {
width: 24px;
height: 48px;
......@@ -651,11 +807,13 @@ onMounted(() => {
left: 0;
top: 130px;
z-index: 999;
img {
width: 100%;
height: 100%;
}
}
.box2-arrow-right {
width: 24px;
height: 48px;
......@@ -663,6 +821,7 @@ onMounted(() => {
right: 0;
top: 130px;
z-index: 999;
img {
width: 100%;
height: 100%;
......@@ -677,6 +836,7 @@ onMounted(() => {
width: 1100px;
background: url("./images/line-bg.png") repeat;
}
.box2-item {
margin-top: 4px;
width: 300px;
......@@ -686,9 +846,11 @@ onMounted(() => {
padding-left: 13px;
margin-left: -100px;
border-left: 1px solid #0a57a6;
.box2-item-header {
display: flex;
width: 240px;
.title {
color: var(--color-main-active);
height: 26px;
......@@ -697,6 +859,7 @@ onMounted(() => {
font-weight: 700;
}
}
.box2-item-content {
width: 210px;
min-height: 48px;
......@@ -711,28 +874,33 @@ onMounted(() => {
line-height: 24px;
overflow: hidden;
}
.point {
position: absolute;
left: -8px;
bottom: -7px;
width: 15px;
height: 15px;
img {
width: 100%;
height: 100%;
}
}
.pointFooter {
position: absolute;
left: -8px;
top: -7px;
width: 15px;
height: 15px;
img {
width: 100%;
height: 100%;
}
}
.time {
height: 24px;
color: var(--color-main-active);
......@@ -748,6 +916,7 @@ onMounted(() => {
left: 0;
}
}
.box2ItemFooter {
margin-top: 154px;
margin-left: -100px;
......@@ -758,35 +927,43 @@ onMounted(() => {
.box3-main {
display: flex;
.box3-main-left {
width: 536px;
height: 326px;
margin-left: 10px;
}
.box3-main-right {
margin-left: 10px;
width: 536px;
height: 326px;
.box3-right-item {
display: flex;
width: 520px;
height: 64px;
align-items: center;
.icon {
width: 48px;
height: 48px;
margin-left: 8px;
img {
width: 100%;
height: 100%;
}
}
.info {
width: 459px;
margin-left: 13px;
.info-header {
display: flex;
justify-content: space-between;
.name {
height: 24px;
color: rgba(59, 65, 75, 1);
......@@ -796,6 +973,7 @@ onMounted(() => {
line-height: 24px;
letter-spacing: 1px;
}
.position {
height: 22px;
color: var(--color-main-active);
......@@ -807,6 +985,7 @@ onMounted(() => {
text-align: right;
}
}
.info-footer {
height: 22px;
color: rgba(95, 101, 108, 1);
......@@ -816,6 +995,12 @@ onMounted(() => {
line-height: 22px;
letter-spacing: 0px;
text-align: left;
white-space: nowrap;
/* 禁止自动换行 */
overflow: hidden;
/* 隐藏超出部分 */
text-overflow: ellipsis;
/* 显示省略号 */
}
}
}
......
......@@ -78,17 +78,12 @@
</div>
<div class="content">{{ item.desc }}</div>
<div class="tag-box">
<div
class="tag"
:class="{
<div class="tag" :class="{
tag1: val.status === 1,
tag2: val.status === 2,
tag3: val.status === 3,
tag4: val.status === 4
}"
v-for="(val, idx) in item.tagList"
:key="idx"
>
}" v-for="(val, idx) in item.tagList" :key="idx">
{{ val.name }}
</div>
</div>
......@@ -112,26 +107,34 @@
<div class="title">{{ "智库发布" }}</div>
</div>
</div>
<div style="display: flex">
<img src="./assets/images/right-left-icon1.png" alt=""
style="margin-top: 174px; width: 24px; height: 48px" @click="changeBox1Data('previous')" />
<div class="box1-main">
<div class="box1-main-left">
<img :src="box1Data.img" alt="" />
<img :src="box1Data[box1DataIndex]?.imageUrl" alt="" />
</div>
<div class="box1-main-right">
<div class="title">{{ box1Data.title }}</div>
<div class="title">{{ box1Data[box1DataIndex]?.reportName }}</div>
<div class="tag-box">
<div class="tag" v-for="(item, index) in box1Data.tagList" :key="index">{{ item }}</div>
<div class="tag" v-for="(item, index) in box1Data[box1DataIndex]?.industryVOList" :key="index">
{{ item }}
</div>
<div class="content">{{ box1Data.content }}</div>
</div>
<div class="content">{{ box1Data[box1DataIndex]?.summary }}</div>
<div class="box1-right-footer">
<div class="time">{{ box1Data.time }}</div>
<div class="time">{{ box1Data[box1DataIndex]?.time }}</div>
<div class="name">
<div class="logo">
<img :src="box1Data.logo" alt="" />
<img :src="box1Data[box1DataIndex]?.thinkTankImage" alt="" />
</div>
<div class="text">{{ box1Data[box1DataIndex]?.reportDate }}</div>
</div>
<div class="text">{{ box1Data.from }}</div>
</div>
</div>
</div>
<img src="./assets/images/right-left-icon2.png" alt=""
style="margin-top: 174px; width: 24px; height: 48px" @click="changeBox1Data('next')" />
</div>
</div>
<div class="box2">
......@@ -146,14 +149,11 @@
</div>
<div class="box2-main">
<div class="box2-main-item" v-for="(item, index) in warningList" :key="index">
<div
class="item-left"
:class="{
<div class="item-left" :class="{
itemLeftStatus1: item.status === '一般风险 ' || item.status === '暂无数值',
itemLeftStatus2: item.status === '重大风险',
itemLeftStatus3: item.status === '特别重大'
}"
>
}">
{{ item.status || "一般风险" }}
</div>
<div class="item-right">
......@@ -207,20 +207,14 @@
<div class="header-title">{{ "智库人物动态" }}</div>
</div>
<div class="box4-tag-box">
<div
class="tag"
:class="{
<div class="tag" :class="{
tagActive: box4ActiveTag === tag.name,
tag1: tag.status === 1,
tag2: tag.status === 2,
tag3: tag.status === 3,
tag4: tag.status === 4,
tag5: tag.status === 5
}"
v-for="(tag, index) in box4TagList"
:key="index"
@click="handleClickBox4Tag(tag.name)"
>
}" v-for="(tag, index) in box4TagList" :key="index" @click="handleClickBox4Tag(tag.name)">
{{ tag.name }}
</div>
</div>
......@@ -252,12 +246,8 @@
</div>
<div class="box5-select-box">
<el-select v-model="box5selectetedYear" placeholder="选择时间" style="width: 120px">
<el-option
v-for="item in box5YearList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
<el-option v-for="item in box5YearList" :key="item.value" :label="item.label" :value="item.value"
@click="changeBox5Data(item.value)" />
</el-select>
</div>
</div>
......@@ -271,12 +261,8 @@
<div class="header-title">{{ "政策建议领域分布" }}</div>
<div class="box6-select-box">
<el-select v-model="box6selectetedYear" placeholder="选择时间" style="width: 120px">
<el-option
v-for="item in box6YearList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
<el-option v-for="item in box6YearList" :key="item.value" :label="item.label" :value="item.value"
@click="handleBox6()" />
</el-select>
</div>
</div>
......@@ -305,30 +291,22 @@
</div>
<div class="box8-select-box">
<el-select v-model="box8selectetedYear" placeholder="选择时间" style="width: 120px">
<el-option
v-for="item in box8YearList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
<el-option v-for="item in box8YearList" :key="item.value" :label="item.label" :value="item.value"
@click="changeBox8Data(item.value)" />
</el-select>
</div>
</div>
<div class="box8-main">
<div class="box8-item" v-for="(item, index) in box8Data" :key="index">
<div
class="item-left"
:class="{ itemBold1: index === 0, itemBold2: index === 1, itemBold3: index === 2 }"
>
<div class="item-left"
:class="{ itemBold1: index === 0, itemBold2: index === 1, itemBold3: index === 2 }">
{{ index + 1 }}
</div>
<div
class="item-center"
:class="{ itemBold1: index === 0, itemBold2: index === 1, itemBold3: index === 2 }"
>
{{ item.title }}
<div class="item-center"
:class="{ itemBold1: index === 0, itemBold2: index === 1, itemBold3: index === 2 }">
{{ item.clause }}
</div>
<div class="item-right">{{ `${item.report} >` }}</div>
<div class="item-right">{{ `${item.count}份报告 >` }}</div>
</div>
</div>
</div>
......@@ -339,13 +317,8 @@
<DivideHeader id="position4" class="divide-header" :titleText="'资源库'"></DivideHeader>
<div class="home-main-footer-header">
<div class="btn-box">
<div
class="btn"
:class="{ btnActive: activeCate === cate }"
v-for="(cate, index) in categoryList"
:key="index"
@click="handleClickCate(cate)"
>
<div class="btn" :class="{ btnActive: activeCate === cate }" v-for="(cate, index) in categoryList"
:key="index" @click="handleClickCate(cate)">
{{ cate }}
</div>
</div>
......@@ -359,13 +332,11 @@
</div>
<div class="select-main">
<div class="checkbox-group">
<el-checkbox
v-for="research in areaList"
:key="research.id"
v-model="selectedAreaList"
:label="research.id"
class="filter-checkbox"
>
<el-checkbox v-model="checkAll" :indeterminate="isIndeterminate" @change="handleCheckAllChange">
全部领域
</el-checkbox>
<el-checkbox v-for="research in areaList" :key="research.id" v-model="selectedAreaList"
:label="research.id" @change="handleCheckedAreaChange()" class="filter-checkbox">
{{ research.name }}
</el-checkbox>
</div>
......@@ -379,13 +350,8 @@
</div>
<div class="select-main">
<div class="checkbox-group">
<el-checkbox
v-for="time in pubTimeList"
:key="time.id"
v-model="selectedPubTimeList"
:label="time.id"
class="filter-checkbox"
>
<el-checkbox v-for="time in pubTimeList" :key="time.id" v-model="selectedPubTimeList" :label="time.id"
class="filter-checkbox">
{{ time.name }}
</el-checkbox>
</div>
......@@ -396,23 +362,25 @@
<div class="card-box">
<div class="footer-card" v-for="(item, index) in curFooterList" :key="index">
<div class="footer-card-top">
<img :src="item.img" alt="" />
<img :src="item.imageUrl" alt="" />
</div>
<div class="footer-card-title">
{{ item.title }}
{{ item.name }}
</div>
<div class="footer-card-footer">
<div class="time">{{ item.time }}</div>
<div class="from">{{ item.from }}</div>
<div class="time">{{ item.times }}</div>
<div class="from">{{ item.thinkTankName }}</div>
</div>
</div>
</div>
<div class="right-footer">
<div class="info">
{{ `共1059篇智库报告` }}
{{ total }}项调查
</div>
<div class="page-box">
<el-pagination :page-size="12" background layout="prev, pager, next" :total="120" />
<el-pagination :page-size="12" background layout="prev, pager, next" :total="total"
@current-change="handleCurrentChange()" :current-page="currentPage" />
</div>
</div>
</div>
......@@ -434,7 +402,11 @@ import {
getThinkTankRiskSignal,
getThinkTankPolicyIndustryChange,
getThinkTankPolicyIndustry,
getThinkTankDonation
getThinkTankDonation,
getThinkTankHot,
getNewReport,
getHylyList,
getThinkTankReport
} from "@/api/thinkTank/overview";
import getMultiLineChart from "./utils/multiLineChart";
......@@ -472,7 +444,9 @@ import Img12 from "./assets/images/img12.png";
import Box1Img from "./assets/images/box1-img.png";
import Box1Logo from "./assets/images/box1-logo.png";
import { setCanvasCreator } from "echarts/core";
const input = ref(""); //搜索科技人物及观点
// 智库列表
const cardList = ref([
// {
......@@ -536,16 +510,38 @@ const handleGetThinkTankList = async () => {
};
// 智库发布
const box1DataIndex = ref(0);
const box1Data = ref({
img: Box1Img,
title: "中美经济竞争:复杂经济和地缘政治关系中的收益和风险",
tagList: ["外交", "军事", "经济"],
content: `自2017年以来,美中竞争,包括经济竞争,已成为美国外交政策的定义。这两个经济体是世界上第一和第二大国家经济体,彼此紧密交织。无论多么必要的关系变化,都可能付出高昂代价。因此,美国面临着在双重战略竞争条件下确保其经济满足国家需求的挑战。为应对这一挑战,兰德研究人员对美中竞争进行了经济和制度分析,开展了参与式前瞻性研究,以理解确保美国经济健全发展`,
time: "2025年9月16日",
from: "兰德科技智库",
logo: Box1Logo
// img: Box1Img,
// title: "中美经济竞争:复杂经济和地缘政治关系中的收益和风险",
// tagList: ["外交", "军事", "经济"],
// content: `自2017年以来,美中竞争,包括经济竞争,已成为美国外交政策的定义。这两个经济体是世界上第一和第二大国家经济体,彼此紧密交织。无论多么必要的关系变化,都可能付出高昂代价。因此,美国面临着在双重战略竞争条件下确保其经济满足国家需求的挑战。为应对这一挑战,兰德研究人员对美中竞争进行了经济和制度分析,开展了参与式前瞻性研究,以理解确保美国经济健全发展`,
// time: "2025年9月16日",
// from: "兰德科技智库",
// logo: Box1Logo
});
//获取智库发布
const handleGetNewReport = async () => {
try {
const res = await getNewReport();
console.log("智库发布", res);
if (res.code === 200 && res.data) {
box1Data.value = res.data;
}
} catch (error) {
console.error("获取智库列表error", error);
}
};
//前后切换智库发布
function changeBox1Data(type) {
console.log(type, box1DataIndex.value);
if (type === "previous") {
box1DataIndex.value === 0 ? "" : (box1DataIndex.value = box1DataIndex.value - 1);
} else {
box1DataIndex.value === box1Data.value.length - 1 ? "" : (box1DataIndex.value = box1DataIndex.value + 1);
}
}
// 风险信号
const warningList = ref([
{
......@@ -646,9 +642,9 @@ const box4TagList = ref([
}
]);
const box4ActiveTag = ref("通信网络");
const handleClickBox4Tag = (tag) => {
box4ActiveTag.value = tag
}
const handleClickBox4Tag = tag => {
box4ActiveTag.value = tag;
};
const messageList = ref([
{
......@@ -689,25 +685,42 @@ const box5Data = ref({
}
]
});
//获取当前时间x年前的日期
function getDateYearsAgo(years) {
// 获取当前日期
const currentDate = new Date();
// 计算指定年数之前的日期
const pastDate = new Date(currentDate.getFullYear() - years, currentDate.getMonth(), currentDate.getDate());
// 格式化日期为 "YYYY-MM-DD" 的形式
const year = pastDate.getFullYear();
const month = String(pastDate.getMonth() + 1).padStart(2, "0"); // 月份从0开始,需要加1
const day = String(pastDate.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
}
const box5selectetedYear = ref("近十年");
const box5YearList = ref([
{
label: "近十年",
value: "近十年"
value: 10
},
{
label: "近五年",
value: "近五年"
value: 5
},
{
label: "近三年",
value: "近三年"
value: 3
}
]);
function changeBox5Data(value) {
handleBox5(getDateYearsAgo(value));
}
// 政策建议趋势分布
const handleGetThinkTankPolicyIndustryChange = async () => {
const handleGetThinkTankPolicyIndustryChange = async date => {
try {
const res = await getThinkTankPolicyIndustryChange();
const res = await getThinkTankPolicyIndustryChange(date);
console.log("政策建议趋势分布", res);
if (res.code === 200 && res.data) {
} else {
......@@ -717,8 +730,8 @@ const handleGetThinkTankPolicyIndustryChange = async () => {
console.error("获取政策建议趋势分布error", error);
}
};
const handleBox5 = async () => {
await handleGetThinkTankPolicyIndustryChange();
const handleBox5 = async date => {
await handleGetThinkTankPolicyIndustryChange(date);
let box5Chart = getMultiLineChart(
box5Data.value.title,
box5Data.value.data[0].value,
......@@ -789,7 +802,7 @@ const box6YearList = ref([
const handleGetThinkTankPolicyIndustry = async () => {
const params = {
apply: 1,
yaer: box6selectetedYear.value
year: box6selectetedYear.value
};
try {
const res = await getThinkTankPolicyIndustry(params);
......@@ -932,64 +945,83 @@ const handleBox7 = async () => {
// 智库研究热点
const box8Data = ref([
{
title: "人工智能领域竞争发展",
report: "11份报告"
},
{
title: "美元未来与能源出口挂钩",
report: "7份报告"
},
{
title: "量子领域国家合作",
report: "5份报告"
},
{
title: "限制中国产燃油进口",
report: "5份报告"
},
{
title: "禁止政府部门采购受控半导体或服务",
report: "4份报告"
},
{
title: "禁止向部分中国实体提供资金",
report: "3份报告"
},
{
title: "中国生产电池",
report: "2份报告"
},
{
title: "重视新兴中国技术公司威胁",
report: "2份报告"
},
{
title: "禁止卫星出口至中国",
report: "1份报告"
},
{
title: "华为设备",
report: "1份报告"
}
// {
// title: "人工智能领域竞争发展",
// report: "11份报告"
// },
// {
// title: "美元未来与能源出口挂钩",
// report: "7份报告"
// },
// {
// title: "量子领域国家合作",
// report: "5份报告"
// },
// {
// title: "限制中国产燃油进口",
// report: "5份报告"
// },
// {
// title: "禁止政府部门采购受控半导体或服务",
// report: "4份报告"
// },
// {
// title: "禁止向部分中国实体提供资金",
// report: "3份报告"
// },
// {
// title: "中国生产电池",
// report: "2份报告"
// },
// {
// title: "重视新兴中国技术公司威胁",
// report: "2份报告"
// },
// {
// title: "禁止卫星出口至中国",
// report: "1份报告"
// },
// {
// title: "华为设备",
// report: "1份报告"
// }
]);
const box8selectetedYear = ref("近一年");
const box8selectetedYear = ref(1);
const box8YearList = ref([
{
label: "近一年",
value: "近一年"
value: 1
},
{
label: "近两年",
value: "近两年"
value: 2
},
{
label: "近三年",
value: "近三年"
value: 3
}
]);
function changeBox8Data(value) {
handleGetThinkTankHot(getDateYearsAgo(value));
}
//智库研究热点
const handleGetThinkTankHot = async date => {
try {
const res = await getThinkTankHot(date);
console.log("智库研究热点", res);
if (res.code === 200 && res.data) {
box8Data.value = res.data;
} else {
box8Data.value = [];
}
} catch (error) {
console.error("获取智库研究热点error", error);
}
};
// 资源库
const categoryList = ref(["智库报告", "政策建议"]);
const activeCate = ref("智库报告");
......@@ -998,41 +1030,52 @@ const handleClickCate = cate => {
};
const areaList = ref([
{
id: "全部领域",
name: "全部领域"
},
{
id: "人工智能",
name: "人工智能"
},
{
id: "通信网络",
name: "通信网络"
},
{
id: "量子科技",
name: "量子科技"
},
{
id: "能源",
name: "能源"
},
{
id: "生物技术",
name: "生物技术"
},
// {
// id: "全部领域",
// name: "全部领域"
// },
// "通信网络",
// "量子科技",
// "能源"
]);
{
id: "新材料",
name: "新材料"
},
{
id: "海洋",
name: "海洋"
//获取行业领域字典
// getHylyList
const handleGetHylyList = async () => {
try {
const res = await getHylyList();
console.log("行业领域字典", res);
if (res.code === 200 && res.data) {
areaList.value = res.data;
}
]);
const selectedAreaList = ref(["全部领域"]);
} catch (error) {
console.error("获取行业领域字典error", error);
}
};
const checkAll = ref(false);
const isIndeterminate = ref(true);
const selectedAreaList = ref([]);
const handleCheckAllChange = val => {
// console.log(val, "handleCheckAllChange");
if (val) {
isIndeterminate.value = false;
selectedAreaList.value.length !== areaList.value.length
? (selectedAreaList.value = areaList.value.map(obj => obj.id))
: "";
} else {
selectedAreaList.value = [];
}
// selectedAreaList.value = val ? areaList : []
// isIndeterminate.value = false
};
const handleCheckedAreaChange = () => {
// console.log(selectedAreaList.value, "handleCheckedAreaChange");
selectedAreaList.value.length !== areaList.value.length
? (isIndeterminate.value = true)
: ((checkAll.value = true), (isIndeterminate.value = false));
};
const pubTimeList = ref([
{
......@@ -1140,10 +1183,37 @@ const curFooterList = ref([
img: Img12
}
]);
const currentPage = ref(1);
const total = ref(0)
// 处理页码改变事件
const handleCurrentChange = page => {
currentPage.value = page;
handleGetetThinkTankReport()
};
//获取智库报告
const handleGetetThinkTankReport = async () => {
const params = {
currentPage: currentPage.value,
pageSize: 12,
researchTypeIds: selectedAreaList.value,
years: 2025
}
try {
const res = await getThinkTankReport(params);
console.log("智库报告", res);
if (res.code === 200 && res.data) {
curFooterList.value = res.data.content;
total.value = res.data.totalElements
}
} catch (error) {
console.error("获取智库报告error", error);
}
};
const handleClick = tank => {
console.log(tank)
// router.push({ name: "ThinkTankDetail", params: { id: tank.id } });
const curRoute = router.resolve({ name: "ThinkTankDetail", params: { id: tank.id } });
const curRoute = router.resolve({ name: "ThinkTankDetail", params: { id: tank.id, name: tank.name } });
window.open(curRoute.href, "_blank");
};
......@@ -1162,10 +1232,14 @@ const handleToMoreRiskSignal = () => {
onMounted(async () => {
handleGetThinkTankList();
handleGetNewReport();
handleGetThinkTankRiskSignal();
handleBox5();
handleBox5(getDateYearsAgo(10));
handleBox6();
handleBox7();
handleGetHylyList();
handleGetThinkTankHot(getDateYearsAgo(1));
handleGetetThinkTankReport()
});
</script>
......@@ -1173,16 +1247,19 @@ onMounted(async () => {
:deep(.el-input__wrapper) {
box-shadow: none;
}
.home-wrapper {
.home-main {
width: 1920px;
margin: 0 auto;
background: url("./assets/images/background.png");
background-size: 100% 100%;
.home-main-header {
display: flex;
flex-direction: column;
align-items: center;
.home-main-header-top {
box-sizing: border-box;
width: 100%;
......@@ -1199,16 +1276,20 @@ onMounted(async () => {
color: #fff;
padding-left: 160px;
display: flex;
.header-item {
margin: 0 3px;
}
.back-item {
cursor: pointer;
&:hover {
color: #ccc;
}
}
}
.home-main-header-center {
margin-top: 48px;
width: 960px;
......@@ -1220,9 +1301,11 @@ onMounted(async () => {
padding: 1px;
position: relative;
border: 1px solid transparent;
&:hover {
border: 1px solid var(--color-main-active);
}
.search {
position: absolute;
right: -1px;
......@@ -1235,14 +1318,17 @@ onMounted(async () => {
justify-content: center;
align-items: center;
cursor: pointer;
.search-icon {
width: 18px;
height: 18px;
img {
width: 100%;
height: 100%;
}
}
.search-text {
margin-left: 8px;
height: 22px;
......@@ -1254,6 +1340,7 @@ onMounted(async () => {
}
}
}
.home-main-header-footer {
margin-top: 38px;
width: 688px;
......@@ -1261,9 +1348,11 @@ onMounted(async () => {
box-sizing: border-box;
display: flex;
justify-content: space-between;
.home-main-header-footer-item {
padding: 0 10px;
text-align: center;
.item-top {
height: 22px;
color: rgba(20, 89, 187, 1);
......@@ -1272,6 +1361,7 @@ onMounted(async () => {
font-weight: 700;
line-height: 22px;
}
.item-footer {
margin-top: 10px;
height: 30px;
......@@ -1283,12 +1373,14 @@ onMounted(async () => {
}
}
}
.home-main-header-btn-box {
width: 688px;
margin: 0 auto;
margin-top: 39px;
display: flex;
justify-content: space-between;
.btn {
display: flex;
align-items: center;
......@@ -1301,11 +1393,13 @@ onMounted(async () => {
background: #e7f3ff;
cursor: pointer;
position: relative;
&:hover {
background: #cae3fc;
}
.btn-text {
width: 80px;
width: 82px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
......@@ -1314,12 +1408,14 @@ onMounted(async () => {
margin-left: 36px;
text-align: center;
}
.btn-icon {
position: absolute;
top: 16px;
right: 19px;
width: 6px;
height: 12px;
img {
width: 100%;
height: 100%;
......@@ -1327,11 +1423,13 @@ onMounted(async () => {
}
}
}
.home-main-header-card-box {
margin-top: 64px;
width: 1600px;
display: flex;
justify-content: space-between;
.card {
width: 253px;
height: 228px;
......@@ -1342,6 +1440,7 @@ onMounted(async () => {
background: rgba(255, 255, 255, 0.65);
transition: all 0.3s;
cursor: pointer;
&:hover {
transform: translateY(-3px);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
......@@ -1353,14 +1452,17 @@ onMounted(async () => {
margin-top: 19px;
margin-left: 20px;
justify-content: space-between;
.icon {
width: 32px;
height: 32px;
img {
width: 100%;
height: 100%;
}
}
.rank {
width: 100px;
height: 32px;
......@@ -1373,26 +1475,34 @@ onMounted(async () => {
font-weight: 400;
line-height: 32px;
letter-spacing: 0px;
overflow: hidden;
// text-overflow: ellipsis;
// white-space: nowrap;
}
.rank1 {
background: linear-gradient(270deg, rgba(206, 79, 81, 0.3), rgba(206, 79, 81, 0) 100%);
color: rgba(206, 79, 81, 1);
}
.rank2 {
background: linear-gradient(270deg, rgba(255, 172, 77, 0.3), rgba(255, 172, 77, 0) 100%);
color: rgba(255, 149, 77, 1);
}
.rank3 {
background: linear-gradient(270deg, rgba(255, 197, 61, 0.3), rgba(255, 197, 61, 0) 100%);
color: rgba(255, 197, 61, 1);
}
}
.card-title {
margin-top: 13px;
display: flex;
margin-left: 20px;
margin-right: 21px;
justify-content: space-between;
.title-left {
width: 175px;
height: 24px;
......@@ -1404,6 +1514,7 @@ onMounted(async () => {
letter-spacing: 1px;
text-align: left;
}
.title-right {
height: 22px;
color: rgba(132, 136, 142, 1);
......@@ -1415,6 +1526,7 @@ onMounted(async () => {
text-align: right;
}
}
.content {
margin: 13px auto 19px;
width: 212px;
......@@ -1432,10 +1544,12 @@ onMounted(async () => {
overflow: hidden;
text-overflow: ellipsis;
}
.tag-box {
margin: 0 20px;
display: flex;
gap: 8px;
.tag {
height: 22px;
padding: 0 8px;
......@@ -1446,6 +1560,7 @@ onMounted(async () => {
font-weight: 400;
line-height: 20px;
}
.tag1 {
box-sizing: border-box;
border: 1px solid rgba(135, 232, 222, 1);
......@@ -1453,6 +1568,7 @@ onMounted(async () => {
background: rgba(230, 255, 251, 1);
color: rgba(19, 168, 168, 1);
}
.tag2 {
box-sizing: border-box;
border: 1px solid rgba(186, 224, 255, 1);
......@@ -1460,6 +1576,7 @@ onMounted(async () => {
background: rgba(230, 244, 255, 1);
color: rgba(22, 119, 255, 1);
}
.tag3 {
box-sizing: border-box;
border: 1px solid rgba(255, 229, 143, 1);
......@@ -1467,6 +1584,7 @@ onMounted(async () => {
background: rgba(255, 251, 230, 1);
color: rgba(250, 173, 20, 1);
}
.tag4 {
box-sizing: border-box;
border: 1px solid rgba(255, 163, 158, 1);
......@@ -1475,6 +1593,7 @@ onMounted(async () => {
color: rgba(245, 34, 45, 1);
}
}
.more {
margin: 103px auto;
height: 22px;
......@@ -1493,11 +1612,13 @@ onMounted(async () => {
.home-main-center {
margin-top: 34px;
.center-top {
height: 450px;
display: flex;
justify-content: center;
gap: 20px;
.box1 {
width: 1064px;
height: 450px;
......@@ -1506,6 +1627,7 @@ onMounted(async () => {
box-sizing: border-box;
border-radius: 10px;
position: relative;
.box1-left {
position: absolute;
left: 0;
......@@ -1513,11 +1635,13 @@ onMounted(async () => {
width: 24px;
height: 48px;
cursor: pointer;
img {
width: 100%;
height: 100%;
}
}
.box1-right {
position: absolute;
right: 0;
......@@ -1525,28 +1649,34 @@ onMounted(async () => {
width: 24px;
height: 48px;
cursor: pointer;
img {
width: 100%;
height: 100%;
}
}
.box1-header {
height: 48px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
display: flex;
justify-content: space-between;
.box1-header-left {
display: flex;
.icon {
width: 18px;
height: 18px;
margin-left: 19px;
margin-top: 16px;
img {
width: 100%;
height: 100%;
}
}
.title {
width: 112px;
height: 48px;
......@@ -1561,23 +1691,28 @@ onMounted(async () => {
}
}
}
.box1-main {
margin: 24px auto;
width: 948px;
height: 353px;
display: flex;
gap: 28px;
.box1-main-left {
width: 458px;
height: 353px;
border-radius: 4px;
img {
width: 100%;
height: 100%;
}
}
.box1-main-right {
width: 462px;
.title {
width: 462px;
max-height: 52px;
......@@ -1590,6 +1725,7 @@ onMounted(async () => {
letter-spacing: 0px;
text-align: left;
}
.tag-box {
width: 462px;
height: 26px;
......@@ -1597,6 +1733,7 @@ onMounted(async () => {
margin-top: 16px;
display: flex;
gap: 8px;
.tag {
height: 26px;
padding: 0 8px;
......@@ -1613,6 +1750,7 @@ onMounted(async () => {
text-align: left;
}
}
.content {
margin-top: 17px;
width: 462px;
......@@ -1625,14 +1763,17 @@ onMounted(async () => {
letter-spacing: 0px;
text-align: justify;
display: -webkit-box;
-webkit-line-clamp: 6; /* 限制行数为5 */
-webkit-line-clamp: 6;
/* 限制行数为5 */
-webkit-box-orient: vertical;
overflow: hidden;
}
.box1-right-footer {
margin-top: 31px;
display: flex;
justify-content: space-between;
.time {
height: 24px;
color: rgba(95, 101, 108, 1);
......@@ -1643,19 +1784,23 @@ onMounted(async () => {
letter-spacing: 0px;
text-align: left;
}
.name {
display: flex;
justify-content: flex-end;
gap: 6px;
.logo {
margin-top: 5px;
width: 16px;
height: 16px;
img {
width: 100%;
height: 100%;
}
}
.text {
height: 24px;
color: rgba(95, 101, 108, 1);
......@@ -1671,6 +1816,7 @@ onMounted(async () => {
}
}
}
.box2 {
width: 521px;
height: 450px;
......@@ -1678,26 +1824,31 @@ onMounted(async () => {
background: rgba(255, 255, 255, 1);
position: relative;
border-radius: 10px;
.box2-header {
height: 48px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
display: flex;
.icon {
width: 24px;
height: 22px;
margin-left: 18px;
margin-top: 14px;
img {
width: 100%;
height: 100%;
}
}
.title {
display: flex;
width: 148px;
height: 48px;
background: rgba(206, 79, 81, 1);
margin-left: 18px;
.text {
margin-left: 15px;
margin-top: 13px;
......@@ -1708,6 +1859,7 @@ onMounted(async () => {
font-weight: 700;
line-height: 22px;
}
.num {
width: 24px;
height: 20px;
......@@ -1722,6 +1874,7 @@ onMounted(async () => {
background: rgba(255, 255, 255, 0.3);
}
}
.more {
margin-top: 16px;
margin-left: 200px;
......@@ -1733,16 +1886,19 @@ onMounted(async () => {
cursor: pointer;
}
}
.box2-main {
margin-top: 2px;
height: 330px;
overflow-y: auto;
.box2-main-item {
margin-left: 23px;
height: 47px;
width: 464px;
display: flex;
cursor: pointer;
&:hover {
background: var(--color-bg-hover);
}
......@@ -1761,24 +1917,29 @@ onMounted(async () => {
padding: 6px 4px;
text-align: center;
}
.itemLeftStatus1 {
color: rgba(82, 196, 26, 1) !important;
background: rgba(246, 255, 237, 1) !important;
}
.itemLeftStatus2 {
color: rgba(250, 140, 22, 1) !important;
background: rgba(255, 247, 230, 1) !important;
}
.itemLeftStatus3 {
color: rgba(245, 34, 45, 1);
background: rgba(255, 241, 240);
}
.item-right {
margin-left: 13px;
width: 408px;
height: 47px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
display: flex;
.text {
width: 315px;
color: rgba(59, 65, 75, 1);
......@@ -1790,6 +1951,7 @@ onMounted(async () => {
text-overflow: ellipsis;
white-space: nowrap;
}
.time {
margin-left: 10px;
line-height: 47px;
......@@ -1801,6 +1963,7 @@ onMounted(async () => {
}
}
}
.box2-footer {
position: absolute;
left: 30px;
......@@ -1815,14 +1978,17 @@ onMounted(async () => {
background: var(--color-main-active);
gap: 8px;
cursor: pointer;
.icon {
width: 16px;
height: 16px;
img {
width: 100%;
height: 100%;
}
}
.text {
color: rgba(255, 255, 255, 1);
font-family: Microsoft YaHei;
......@@ -1833,17 +1999,20 @@ onMounted(async () => {
}
}
}
.center-center {
margin-top: 21px;
height: 450px;
display: flex;
justify-content: center;
.box3 {
width: 792px;
height: 450px;
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(25, 69, 130, 0.2);
background: rgba(255, 255, 255, 1);
.box3-header {
height: 48px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
......@@ -1852,17 +2021,21 @@ onMounted(async () => {
justify-content: space-between;
padding: 0 20px;
position: relative;
.box3-header-left {
display: flex;
.box3-header-icon {
margin-top: 16px;
width: 19px;
height: 19px;
img {
width: 100%;
height: 100%;
}
}
.box3-header-title {
margin-top: 16px;
margin-left: 19px;
......@@ -1873,6 +2046,7 @@ onMounted(async () => {
font-weight: 700;
line-height: 22px;
}
.more {
width: 49px;
height: 24px;
......@@ -1888,33 +2062,40 @@ onMounted(async () => {
}
}
}
.box3-main {
height: 402px;
overflow-y: auto;
overflow-x: hidden;
padding-top: 6px;
.box3-item {
display: flex;
height: 77px;
width: 749px;
margin-left: 21px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
.left {
width: 72px;
height: 48px;
margin-top: 15px;
img {
width: 100%;
height: 100%;
}
}
.right {
width: 657px;
margin-left: 20px;
.right-top {
width: 657px;
display: flex;
justify-content: space-between;
.title {
margin-top: 13px;
width: 520px;
......@@ -1928,6 +2109,7 @@ onMounted(async () => {
text-overflow: ellipsis;
white-space: nowrap;
}
.time {
flex: 1;
text-align: right;
......@@ -1940,6 +2122,7 @@ onMounted(async () => {
line-height: 22px;
}
}
.right-footer {
width: 657px;
height: 24px;
......@@ -1956,6 +2139,7 @@ onMounted(async () => {
}
}
}
.box4 {
margin-left: 20px;
width: 792px;
......@@ -1963,6 +2147,7 @@ onMounted(async () => {
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(25, 69, 130, 0.2);
background: rgba(255, 255, 255, 1);
.box4-header {
width: 792px;
height: 48px;
......@@ -1971,15 +2156,18 @@ onMounted(async () => {
box-sizing: border-box;
padding-left: 22px;
position: relative;
.header-icon {
margin-top: 15px;
width: 20px;
height: 20px;
img {
width: 100%;
height: 100%;
}
}
.header-title {
margin-top: 16px;
margin-left: 18px;
......@@ -1990,6 +2178,7 @@ onMounted(async () => {
font-weight: 700;
line-height: 22px;
}
.more {
width: 49px;
height: 24px;
......@@ -2004,12 +2193,14 @@ onMounted(async () => {
cursor: pointer;
}
}
.box4-tag-box {
height: 60px;
display: flex;
padding: 0 10px;
align-items: center;
gap: 8px;
.tag {
height: 28px;
line-height: 28px;
......@@ -2018,6 +2209,7 @@ onMounted(async () => {
border-radius: 4px;
cursor: pointer;
}
.tagActive {
height: 36px;
line-height: 36px;
......@@ -2032,37 +2224,44 @@ onMounted(async () => {
line-height: 36px;
letter-spacing: 1px;
}
.tag1 {
border: 1px solid rgba(135, 232, 222, 1);
background: rgba(230, 255, 251, 1);
color: rgba(19, 168, 168, 1);
}
.tag2 {
border: 1px solid rgba(145, 202, 255, 1);
background: rgba(230, 244, 255, 1);
color: rgba(22, 119, 255, 1);
}
.tag3 {
border: 1px solid rgba(255, 213, 145, 1);
background: rgba(255, 247, 230, 1);
color: rgba(250, 140, 22, 1);
}
.tag4 {
border: 1px solid rgba(255, 187, 150, 1);
background: rgba(255, 242, 232, 1);
color: rgba(250, 84, 28, 1);
}
.tag5 {
border: 1px solid rgba(255, 163, 158, 1);
background: rgba(255, 241, 240, 1);
color: rgba(206, 79, 81, 1);
}
}
.box4-main {
height: 342px;
overflow-y: auto;
box-sizing: border-box;
padding: 8px 0;
.box4-main-item {
margin-top: 16px;
display: flex;
......@@ -2072,11 +2271,13 @@ onMounted(async () => {
margin-top: 5px;
width: 36px;
height: 36px;
img {
width: 100%;
height: 100%;
}
}
.right {
margin-left: 10px;
width: 690px;
......@@ -2085,9 +2286,11 @@ onMounted(async () => {
background: rgba(246, 250, 255, 1);
padding: 10px 15px;
border-radius: 4px;
.right-top {
display: flex;
justify-content: space-between;
.name {
height: 24px;
color: rgba(59, 65, 75, 1);
......@@ -2096,6 +2299,7 @@ onMounted(async () => {
font-weight: 700;
line-height: 24px;
}
.time {
height: 30px;
color: rgba(95, 101, 108, 1);
......@@ -2105,6 +2309,7 @@ onMounted(async () => {
line-height: 30px;
}
}
.content {
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
......@@ -2117,12 +2322,14 @@ onMounted(async () => {
}
}
}
.center-footer {
margin-top: 21px;
height: 460px;
display: flex;
justify-content: center;
gap: 15px;
.box5 {
width: 1064px;
height: 460px;
......@@ -2131,6 +2338,7 @@ onMounted(async () => {
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.box5-header {
height: 53px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
......@@ -2139,18 +2347,22 @@ onMounted(async () => {
justify-content: space-between;
padding: 0 20px;
position: relative;
.box5-header-left {
display: flex;
.box5-header-icon {
margin-top: 15px;
margin-left: 2px;
width: 19px;
height: 19px;
img {
width: 100%;
height: 100%;
}
}
.box5-header-title {
margin-top: 12px;
margin-left: 19px;
......@@ -2162,6 +2374,7 @@ onMounted(async () => {
line-height: 26px;
}
}
.box5-select-box {
width: 120px;
height: 28px;
......@@ -2170,10 +2383,12 @@ onMounted(async () => {
right: 25px;
}
}
.box5-main {
height: 397px;
}
}
.box6 {
width: 521px;
height: 460px;
......@@ -2182,6 +2397,7 @@ onMounted(async () => {
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.box6-header {
width: 521px;
height: 53px;
......@@ -2190,15 +2406,18 @@ onMounted(async () => {
border-bottom: 1px solid rgba(240, 242, 244, 1);
display: flex;
position: relative;
.header-icon {
margin-top: 18px;
width: 19px;
height: 19px;
img {
width: 100%;
height: 100%;
}
}
.header-title {
margin-top: 16px;
margin-left: 15px;
......@@ -2209,6 +2428,7 @@ onMounted(async () => {
font-weight: 700;
line-height: 22px;
}
.box6-select-box {
width: 120px;
height: 28px;
......@@ -2217,16 +2437,19 @@ onMounted(async () => {
right: 25px;
}
}
.box6-main {
height: 360px;
}
}
}
.center-footer1 {
margin-top: 16px;
display: flex;
justify-content: center;
gap: 15px;
.box7 {
width: 1064px;
height: 460px;
......@@ -2235,6 +2458,7 @@ onMounted(async () => {
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.box7-header {
height: 53px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
......@@ -2243,18 +2467,22 @@ onMounted(async () => {
justify-content: space-between;
padding: 0 20px;
position: relative;
.box7-header-left {
display: flex;
.box7-header-icon {
margin-top: 15px;
margin-left: 2px;
width: 19px;
height: 19px;
img {
width: 100%;
height: 100%;
}
}
.box7-header-title {
margin-top: 12px;
margin-left: 19px;
......@@ -2266,6 +2494,7 @@ onMounted(async () => {
line-height: 26px;
}
}
.box-header-right {
position: absolute;
height: 24px;
......@@ -2275,14 +2504,17 @@ onMounted(async () => {
justify-content: flex-end;
align-items: center;
gap: 8px;
.icon {
width: 14px;
height: 16px;
img {
width: 100%;
height: 100%;
}
}
.text {
height: 24px;
color: rgba(132, 136, 142, 1);
......@@ -2295,10 +2527,12 @@ onMounted(async () => {
}
}
}
.box7-main {
height: 412px;
}
}
.box8 {
width: 521px;
height: 460px;
......@@ -2307,6 +2541,7 @@ onMounted(async () => {
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.box8-header {
height: 53px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
......@@ -2315,18 +2550,22 @@ onMounted(async () => {
justify-content: space-between;
padding: 0 20px;
position: relative;
.box8-header-left {
display: flex;
.box8-header-icon {
margin-top: 15px;
margin-left: 2px;
width: 19px;
height: 19px;
img {
width: 100%;
height: 100%;
}
}
.box8-header-title {
margin-top: 12px;
margin-left: 19px;
......@@ -2338,6 +2577,7 @@ onMounted(async () => {
line-height: 26px;
}
}
.box8-select-box {
width: 120px;
height: 28px;
......@@ -2346,17 +2586,20 @@ onMounted(async () => {
right: 25px;
}
}
.box8-main {
margin: 0 auto;
margin-top: 5px;
width: 452px;
height: 382px;
overflow: hidden;
.box8-item {
margin-top: 14px;
width: 452px;
height: 24px;
display: flex;
.item-left {
width: 20px;
height: 24px;
......@@ -2384,18 +2627,22 @@ onMounted(async () => {
text-overflow: ellipsis;
white-space: nowrap;
}
.itemBold1 {
color: rgba(206, 79, 81, 1);
font-weight: 700;
}
.itemBold2 {
color: rgba(255, 169, 64, 1);
font-weight: 700;
}
.itemBold3 {
color: rgba(255, 197, 61, 1);
font-weight: 700;
}
.item-right {
width: 92px;
height: 24px;
......@@ -2413,9 +2660,11 @@ onMounted(async () => {
}
}
}
.home-main-footer {
overflow: hidden;
background: rgba(247, 248, 249, 1);
.home-main-footer-header {
width: 1600px;
height: 42px;
......@@ -2423,9 +2672,11 @@ onMounted(async () => {
// background: orange;
display: flex;
justify-content: space-between;
.btn-box {
width: 1000px;
display: flex;
.btn {
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
......@@ -2437,48 +2688,58 @@ onMounted(async () => {
background: rgba(20, 89, 187, 0);
margin-right: 20px;
cursor: pointer;
&:hover {
background: rgba(20, 89, 187, 0.1);
}
}
.btnActive {
padding: 0 24px;
border-radius: 21px;
background: var(--color-main-active);
color: #fff;
font-weight: 700;
&:hover {
color: #fff;
background: var(--color-main-active);
}
}
}
.select-box {
height: 42px;
box-sizing: border-box;
padding: 5px 0;
}
}
.home-main-footer-main {
margin: 0 auto;
margin-top: 36px;
width: 1600px;
display: flex;
gap: 16px;
.left {
width: 300px;
height: 600px;
width: 360px;
height: 100%;
padding-bottom: 36px;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(94, 95, 95, 0.1);
background: rgba(255, 255, 255, 1);
position: relative;
.select-box {
margin-top: 21px;
.header {
display: flex;
gap: 17px;
.icon {
margin-top: 4px;
width: 8px;
......@@ -2486,6 +2747,7 @@ onMounted(async () => {
background: var(--color-main-active);
border-radius: 0 4px 4px 0;
}
.title {
height: 24px;
color: var(--color-main-active);
......@@ -2497,13 +2759,16 @@ onMounted(async () => {
text-align: left;
}
}
.select-main {
margin-left: 25px;
}
.select-main1 {
width: 100px;
}
}
.left-footer-box {
left: 25px;
bottom: 20px;
......@@ -2512,6 +2777,7 @@ onMounted(async () => {
height: 149px;
border-radius: 4px;
background: rgba(246, 250, 255, 1);
.header {
margin-top: 8px;
margin-left: 21px;
......@@ -2524,6 +2790,7 @@ onMounted(async () => {
letter-spacing: 1px;
text-align: left;
}
.content {
margin: 0 auto;
margin-top: 11px;
......@@ -2537,6 +2804,7 @@ onMounted(async () => {
letter-spacing: 0px;
text-align: left;
}
.btn {
margin: 0 auto;
margin-top: 13px;
......@@ -2554,42 +2822,60 @@ onMounted(async () => {
}
}
}
.right {
width: 1284px;
height: 1377px;
.card-box {
width: 1284px;
width: 1226px;
height: 1248px;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
.footer-card {
width: 418px;
width: 398px;
height: 300px;
border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
.footer-card-top {
width: 384px;
height: 206px;
width: 364px;
height: 180px;
margin: 0 auto;
margin-top: 15px;
img {
width: 100%;
height: 100%;
}
}
.footer-card-title {
margin: 0 auto;
margin-top: 13px;
width: 376px;
height: 24px;
height: 48px;
/* 修改高度为两行的高度 */
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 18px;
font-weight: 700;
line-height: 24px;
overflow: hidden;
/* 隐藏超出部分 */
text-overflow: ellipsis;
/* 显示省略号 */
display: -webkit-box;
/* 使用弹性盒模型 */
-webkit-line-clamp: 2;
/* 限制显示两行 */
-webkit-box-orient: vertical;
/* 设置盒模型方向为垂直 */
}
.footer-card-footer {
margin: 0 auto;
margin-top: 5px;
......@@ -2605,10 +2891,12 @@ onMounted(async () => {
}
}
}
.right-footer {
margin-top: 43px;
display: flex;
justify-content: space-between;
.info {
height: 19px;
color: rgba(132, 136, 142, 1);
......@@ -2625,18 +2913,22 @@ onMounted(async () => {
}
}
}
.divide-header {
margin: 0 auto;
margin-top: 52px;
margin-bottom: 36px;
}
.filter-checkbox {
width: 105px;
}
:deep(.el-input__wrapper) {
box-shadow: none;
border-radius: 10px;
}
:deep(.el-input__wrapper:hover) {
box-shadow: none !important;
}
......@@ -2644,4 +2936,85 @@ onMounted(async () => {
:deep(.el-input__wrapper.is-focus) {
box-shadow: none !important;
}
.page {
width: 1600px;
height: 40px;
display: flex;
align-items: center;
justify-content: space-between;
margin: 36px 0 0 0;
padding-left: 11px;
.count {
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
}
:deep(.el-pagination) {
display: flex;
align-items: center;
}
:deep(.el-pagination.is-background .el-pager li) {
min-width: 32px;
height: 32px;
line-height: 32px;
border-radius: 6px;
margin: 0 6px;
border: 1px solid rgba(0, 0, 0, 0.15);
background-color: #fff;
color: rgb(95, 101, 108);
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
}
:deep(.el-pagination.is-background .el-pager li.is-active) {
background-color: #fff;
color: rgba(22, 119, 255, 1);
border-color: rgba(22, 119, 255, 1);
}
:deep(.el-pagination.is-background .el-pager li.is-ellipsis) {
border: none;
background-color: transparent;
color: rgb(95, 101, 108);
min-width: 16px;
margin: 0 6px;
}
:deep(.el-pagination.is-background .btn-prev),
:deep(.el-pagination.is-background .btn-next) {
min-width: 32px;
height: 32px;
border-radius: 6px;
border: 1px solid rgba(0, 0, 0, 0.15);
background-color: #fff;
color: rgb(95, 101, 108);
font-size: 16px;
font-family: "Microsoft YaHei";
margin: 0 6px;
}
:deep(.el-pagination.is-background .btn-prev.is-disabled),
:deep(.el-pagination.is-background .btn-next.is-disabled) {
color: rgba(95, 101, 108, 0.45);
border-color: rgb(235, 238, 242);
background-color: #fff;
}
</style>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论