提交 f0612c8b authored 作者: yanpeng's avatar yanpeng

merge

......@@ -39,10 +39,37 @@ export function getHotBills() {
}
// 获取法案风险信号
export function getBillRiskSignal() {
/**
* @param {moduleId}
*/
export function getBillRiskSignal(params) {
return request({
method: 'GET',
// 这个是之前的接口地址,现在接口地址换成新的了所以使用新地址
// url: '/api/BillOverview/riskSignal',
url: `/api/commonFeature/riskSignal/${params.moduleId}`,
})
}
// 获取新闻资讯
/**
* @param {moduleId}
*/
export function getNews(params) {
return request({
method: 'GET',
url: '/api/BillOverview/riskSignal',
url: `/api/commonFeature/news/${params.moduleId}`,
})
}
// 获取社交媒体
/**
* @param {moduleId}
*/
export function getRemarks(params) {
return request({
method: 'GET',
url: `/api/commonFeature/remarks/${params.moduleId}`,
})
}
......@@ -89,10 +116,27 @@ export function getMemberProposal(params) {
}
// 获取资源库
export function getBills(params) {
export function getBills(params, signal) {
return request({
method: 'GET',
url: `/api/BillOverview/bills`,
params
params,
signal
})
}
// 获取提出部门列表
export function getPostOrgList() {
return request({
method: 'GET',
url: `/api/BillDict/department`,
})
}
// 获取提出议员列表
export function getPostMemberList() {
return request({
method: 'GET',
url: `/api/BillDict/member`,
})
}
\ No newline at end of file
import request from "@/api/request.js";
// 提出背景
/**
* @param {cRelated, currentPage, id, pageSize}
*/
export function getDecreeBackground(params) {
return request({
method: 'GET',
url: `/api/administrativeOrderInfo/background/${params.id}`,
params
})
}
// 相关事件
/**
* @param { id }
*/
export function getDecreeRelatedEvent(params) {
return request({
method: 'GET',
url: `/api/administrativeOrderInfo/relateEvent/${params.id}`,
params
})
}
// 法律依据
/**
* @param { id }
*/
export function getDecreeDepend(params) {
return request({
method: 'GET',
url: `/api/administrativeOrderInfo/depend/${params.id}`,
params
})
}
\ No newline at end of file
import request from "@/api/request.js";
// 根据政令ID获取领域公司信息
/**
* @param {cRelated, id}
*/
export function getDecreeRelateOrder(params) {
return request({
method: 'GET',
url: `/api/administrativeOrderDeepDive/relateOrder/${params.id}`,
params
})
}
\ No newline at end of file
import request from "@/api/request.js";
// 最新科技政令
export function getDepartmentList() {
return request({
method: 'GET',
url: `/api/administrativeDict/department`,
})
}
// 最新科技政令
export function getLatestDecree() {
return request({
method: 'GET',
url: `/api/administrativeOrderOverview/info`,
})
}
// 风险信号
export function getDecreeRiskSignal() {
return request({
method: 'GET',
url: `/api/administrativeOrderOverview/riskSignal`,
})
}
// 行政令发布频度
export function getDecreeYearOrder() {
return request({
method: 'GET',
url: `/api/administrativeOrderOverview/yearOrder`,
})
}
// 政令涉及领域
export function getDecreeArea() {
return request({
method: 'GET',
url: `/api/administrativeOrderOverview/industry`,
})
}
// 关键行政令
export function getKeyDecree() {
return request({
method: 'GET',
url: `/api/administrativeOrderOverview/action`,
})
}
// 政令重点条款
export function getDecreeKeyInstruction() {
return request({
method: 'GET',
url: `/api/administrativeOrderOverview/instruction`,
})
}
// 资源库
/**
* @param {currentPage, pageSize, proposeName, researchTypeIds, sortFun, years}
*/
export function getDecreeOrderList(params) {
return request({
method: 'GET',
url: `/api/administrativeOrderOverview/orderList`,
params
})
}
// 左侧行业领域列表
export function getDecreehylyList(params) {
return request({
method: 'GET',
url: `/api/billImpactAnalysis/industry/hylyList`,
params
})
}
\ No newline at end of file
import request from "@/api/request.js";
// 根据政令ID获取领域公司信息
/**
* @param {cRelated, id}
*/
export function getDecreeIndustry(params) {
return request({
method: 'GET',
url: `/api/administrativeOrderImpactAnalysis/industry/${params.id}`,
params
})
}
// 获取行业领域列表
export function getDecreehylyList() {
return request({
method: 'GET',
url: `/api/billImpactAnalysis/industry/hylyList`,
})
}
// 根据政行业领域ID获取公司列表
/**
* @param {cRelated, id}
*/
export function getDecreeCompany(params) {
return request({
method: 'GET',
url: `/api/administrativeOrderImpactAnalysis/industry/company/${params.id}`,
params
})
}
// 获取政令举措落实分析
/**
* @param {id}
*/
export function getDecreeAction(params) {
return request({
method: 'GET',
url: `/api/administrativeOrderImpactAnalysis/action/${params.id}`,
params
})
}
import request from "@/api/request.js";
// 基本信息
/**
* @param {id}
*/
export function getDecreeBasicInfo(params) {
return request({
method: 'GET',
url: `/api/administrativeOrderInfo/basicInfo/${params.id}`,
params
})
}
// 主要指令
/**
* @param {currentPage, id, pageSize}
*/
export function getDecreeMainContent(params) {
return request({
method: 'GET',
url: `/api/administrativeOrderInfo/mainContent/${params.id}`,
params
})
}
// 执行机构
/**
* @param {id}
*/
export function getDecreeOrganization(params) {
return request({
method: 'GET',
url: `/api/administrativeOrderInfo/organization/${params.id}`,
params
})
}
\ No newline at end of file
import request from "@/api/request.js";
// 新闻资讯
/**
* @param {moduleId}
*/
export function getNews(params) {
return request({
method: 'GET',
url: `/api/commonFeature/news/${params.moduleId}`,
params
})
}
// 社交媒体
/**
* @param {moduleId}
*/
export function getSocialMedia(params) {
return request({
method: 'GET',
url: `/api/commonFeature/remarks/${params.moduleId}`,
params
})
}
// 风险信号
/**
* @param {moduleId}
*/
export function getRiskSignal(params) {
return request({
method: 'GET',
url: `/api/commonFeature/riskSignal/${params.moduleId}`,
params
})
}
\ No newline at end of file
......@@ -6,7 +6,6 @@ import DecreeIntroduction from "@/views/decree/decreeLayout/overview/introductio
import DecreeBackground from "@/views/decree/decreeLayout/overview/background/index.vue";
import DecreeDeepDig from "@/views/decree/decreeLayout/deepdig/index.vue";
import DecreeInfluence from "@/views/decree/decreeLayout/influence/index.vue";
import Institution from "@/views/decree/institution/index.vue"
const decreeRoutes = [
......
import Portal1 from "@/views/portals/portal1/index.vue";
import Portal from "@/views/portals/portal1/index.vue";
import Portal2 from "@/views/portals/portal2/index.vue";
const portalRoutes = [
// 门户
{
path: "/portal1",
name: "portal1",
component: Portal1,
path: "/portal",
name: "portal",
component: Portal,
meta: {
title: "门户"
}
......
......@@ -505,7 +505,7 @@ const handleGetBillPersonAnalyze = async (isOppose) => {
onMounted(() => {
handleGetBillBackground();
handleGetRelatedEvent();
handleGetBillPersonAnalyze(false);
// handleGetBillPersonAnalyze(false);
});
</script>
......
......@@ -214,22 +214,21 @@
class="box2-main-item"
v-for="(item, index) in warningList"
:key="index"
@click="handleClickToDetail()"
>
<div
class="item-left"
:class="{
itemLeftStatus1: item.riskLevel === '特别重大',
itemLeftStatus2: item.riskLevel === '重大风险'
itemLeftStatus1: item.signalLevel === '特别重大',
itemLeftStatus2: item.signalLevel === '重大风险'
}"
>
{{ item.riskLevel ? item.riskLevel : "一般风险" }}
{{ item.signalLevel ? item.signalLevel : "一般风险" }}
</div>
<div class="item-right">
<div class="text">
{{ item.description }}
{{ item.signalTitle }}
</div>
<div class="time">{{ item.introductionDate }}</div>
<div class="time">{{ item.signalTime }}</div>
</div>
</div>
</div>
......@@ -254,16 +253,16 @@
</div>
</div>
<div class="box3-main">
<div class="box3-item" v-for="(news, index) in newsList" :key="index">
<div class="box3-item" v-for="(news, index) in newsList" :key="index" @click="handleClickToNewsDetail()">
<div class="left">
<img :src="news.img" alt="" />
<img :src="news.newsImage || News1" alt="" />
</div>
<div class="right">
<div class="right-top">
<div class="title">{{ news.title }}</div>
<div class="time">{{ news.from }}</div>
<div class="title">{{ news.newsTitle }}</div>
<div class="time">{{ news.newsDate ? news.newsDate.slice(5) : '' }} - {{ news.newsOrg }}</div>
</div>
<div class="right-footer">{{ news.content }}</div>
<div class="right-footer">{{ news.newsContent }}</div>
</div>
</div>
</div>
......@@ -278,14 +277,14 @@
<div class="box4-main">
<div class="box4-main-item" v-for="(item, index) in messageList" :key="index">
<div class="left" @click="handleClcikToCharacter(index)">
<img :src="item.img" alt="" />
<img :src="item.personImage" alt="" />
</div>
<div class="right">
<div class="right-top">
<div class="name">{{ item.name }}</div>
<div class="time">{{ item.time }}</div>
<div class="name">{{ item.personName }}</div>
<div class="time">{{ formatMessageTime(item.time) }}·发布于{{ item.orgName }}</div>
</div>
<div class="content">{{ item.content }}</div>
<div class="content">{{ item.remarks }}</div>
</div>
</div>
</div>
......@@ -311,10 +310,13 @@
<div class="box5-select">
<el-select v-model="box5Select" placeholder="选择领域" @change="handleBox5Change" style="width: 150px">
<el-option label="全部领域" value="全部领域" />
<el-option v-for="item in categoryList.slice(1)" :key="item.id" :label="item.name" :value="item.id" />
<el-option v-for="item in categoryList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</div>
<div class="box5-main" id="box5Chart"></div>
<div class="box5-main" :style="{ display: !box5HasData ? 'flex' : 'block', justifyContent: 'center', alignItems: 'center' }">
<el-empty v-if="!box5HasData" description="暂无数据" :image-size="100" />
<div v-else id="box5Chart" style="width: 100%; height: 100%;"></div>
</div>
</div>
<div class="box6">
<div class="box6-header">
......@@ -358,7 +360,10 @@
/>
</el-select>
</div>
<div class="box7-main" id="box7Chart"></div>
<div class="box7-main" :style="{ display: !box7HasData ? 'flex' : 'block', justifyContent: 'center', alignItems: 'center' }">
<el-empty v-if="!box7HasData" description="暂无数据" :image-size="100" />
<div v-else id="box7Chart" style="width: 100%; height: 100%;"></div>
</div>
</div>
<div class="box8">
<div class="box8-header">
......@@ -385,12 +390,14 @@
/>
</el-select>
</div>
<div class="box8-main">
<div class="box8-main" :style="{ display: box8Data.length === 0 ? 'flex' : 'block', justifyContent: 'center', alignItems: 'center' }">
<el-empty v-if="box8Data.length === 0" description="暂无数据" :image-size="100" />
<div
v-else
class="box8-main-item"
v-for="(item, index) in box8Data"
:key="index"
@click="handleClcikToCharacter(0)"
@click="handleClcikToCharacter(index)"
>
<div class="box8-main-item-left">
<img :src="item.img" alt="" referrerpolicy="no-referrer" class="left-img" />
......@@ -436,7 +443,10 @@
/>
</el-select>
</div>
<div class="box9-main" id="box9Chart"></div>
<div class="box9-main" :style="{ display: !box9HasData ? 'flex' : 'block', justifyContent: 'center', alignItems: 'center' }">
<el-empty v-if="!box9HasData" description="暂无数据" :image-size="100" />
<div v-else id="box9Chart" style="width: 100%; height: 100%;"></div>
</div>
</div>
</div>
</div>
......@@ -447,10 +457,10 @@
<div class="btn-box">
<div
class="btn"
:class="{ btnActive: activeTabName === cate.name }"
:class="{ btnActive: activeTabName === cate.name, disabled: index !== 0 }"
v-for="(cate, index) in tabList"
:key="index"
@click="handleClickTab(cate)"
@click="index === 0 && handleClickTab(cate)"
>
{{ cate.name }}
</div>
......@@ -465,9 +475,12 @@
<div class="title">{{ "科技领域" }}</div>
</div>
<div class="select-main">
<el-checkbox-group class="checkbox-group" v-model="activeAreaList">
<el-checkbox-group class="checkbox-group" v-model="activeAreaList" @change="handleAreaChange">
<el-checkbox class="filter-checkbox" label="全部领域">
全部领域
</el-checkbox>
<el-checkbox
v-for="(area, index) in areaList"
v-for="(area, index) in cateKuList"
:key="area.id"
:label="area.id"
class="filter-checkbox"
......@@ -483,7 +496,7 @@
<div class="title">{{ "党派" }}</div>
</div>
<div class="select-main">
<el-checkbox-group class="checkbox-group" v-model="activeDpList">
<el-checkbox-group class="checkbox-group" v-model="activeDpList" @change="handleDpChange">
<el-checkbox
v-for="(dp, index) in dpList"
:key="dp.id"
......@@ -501,7 +514,7 @@
<div class="title">{{ "议院" }}</div>
</div>
<div class="select-main">
<el-checkbox-group class="checkbox-group" v-model="activeYyList">
<el-checkbox-group class="checkbox-group" v-model="activeYyList" @change="handleYyChange">
<el-checkbox
v-for="(yy, index) in yyList"
:key="yy.id"
......@@ -520,7 +533,7 @@
<div class="title">{{ "发布时间" }}</div>
</div>
<div class="select-main">
<el-checkbox-group class="checkbox-group" v-model="activePubTime">
<el-checkbox-group class="checkbox-group" v-model="activePubTime" @change="handlePubTimeChange">
<el-checkbox
v-for="(time, index) in pubTime"
:key="time.id"
......@@ -536,27 +549,27 @@
<div class="right">
<div class="right-header">
<div class="right-header-box">
<el-select v-model="footerSelect1" placeholder="选择委员会" style="width: 240px">
<el-select v-model="footerSelect1" placeholder="选择委员会" style="width: 240px" @change="handleFooterSelect1Change">
<el-option
v-for="item in footerSelectList1"
:key="item.value"
:label="item.label"
:value="item.value"
v-for="item in postOrgList"
:key="item.departmentId"
:label="item.departmentName"
:value="item.departmentId"
/>
</el-select>
</div>
<div class="right-header-box">
<el-select v-model="footerSelect2" placeholder="选择提出议员" style="width: 240px">
<el-select v-model="footerSelect2" placeholder="选择提出议员" style="width: 240px" @change="handleFooterSelect2Change">
<el-option
v-for="item in footerSelectList2"
:key="item.value"
:label="item.label"
:value="item.value"
v-for="item in postMemberList"
:key="item.memberId"
:label="item.memberName"
:value="item.memberId"
/>
</el-select>
</div>
<div class="right-header-box" style="margin-left: auto;">
<el-select v-model="releaseTime" placeholder="选择发布时间" style="width: 120px">
<el-select v-model="releaseTime" placeholder="选择排序方式" style="width: 120px" @change="handlePxChange">
<el-option
v-for="item in releaseTimeList"
:key="item.value"
......@@ -566,8 +579,8 @@
</el-select>
</div>
</div>
<div class="right-main">
<div class="right-main-box" v-for="(item, index) in footerBillList" :key="index">
<div class="right-main" v-loading="loading">
<div class="right-main-box" v-for="(item, index) in bills" :key="index" @click="handleClickToDetail()">
<div class="header">
<div class="title">{{ item.name }}</div>
<div class="en-title">{{ item.eName }}</div>
......@@ -597,22 +610,19 @@
</div>
</div>
</div>
<div class="right-main-box"></div>
<div class="right-main-box"></div>
<div class="right-main-box"></div>
</div>
<div class="right-footer">
<div class="footer-left">
{{ `共1149项调查` }}
{{ `共${total}项调查` }}
</div>
<div class="footer-right">
<el-pagination
@current-change="handleCurrentChange"
:pageSize="12"
:page-size="pageSize"
:current-page="currentPage"
background
layout="prev, pager, next"
:total="1149"
:total="total"
/>
</div>
</div>
......@@ -637,7 +647,12 @@ import {
getBillOverviewKeyTK,
getBillCount,
getBillPostOrg,
getMemberProposal
getMemberProposal,
getNews,
getRemarks,
getPostOrgList,
getPostMemberList,
getBills
} from "@/api/bill/billHome";
import DivideHeader from "@/components/DivideHeader.vue";
......@@ -692,6 +707,18 @@ import { iteratee } from "lodash";
const searchBillText = ref("");
const formatMessageTime = (timeStr) => {
if (!timeStr) return '';
// 假设格式为 2025-11-02T12:09:45
if (timeStr.includes('T')) {
const [date, time] = timeStr.split('T');
const [year, month, day] = date.split('-');
const [hour, minute] = time.split(':');
return `${year}-${month}-${day} ${hour}:${minute}`;
}
return timeStr;
};
// 跳转人物主页
const handleClcikToCharacter = index => {
let type;
......@@ -722,6 +749,7 @@ const currentPage = ref(1);
// 处理页码改变事件
const handleCurrentChange = page => {
currentPage.value = page;
handleGetBills();
};
const containerRef = ref(null);
......@@ -772,6 +800,12 @@ const handleToMoreRiskSignal = () => {
const route = router.resolve("/riskSignal");
window.open(route.href, "_blank");
};
// 跳转新闻详情页
const handleClickToNewsDetail = () => {
// window.sessionStorage.setItem("newsId", "119_HR_1");
const route = router.resolve("/newsAnalysis");
window.open(route.href, "_blank");
};
// 查看更多新闻资讯
const handleToMoreNews = () => {
......@@ -780,161 +814,135 @@ const handleToMoreNews = () => {
};
// 风险信号
const warningList = ref([
{
title: "美国大而美法案落地,总统签署通过",
time: "一天前",
status: "特别重大"
},
{
title: "美大而美法案7月1日以51:50的票数通过...",
time: "一天前",
status: "特别重大"
},
{
title: "首次提出“限制外国敏感实体获取补贴”",
time: "一天前",
status: "重大风险"
},
{
title: "将中国企业海外子公司、合资公司纳入受...",
time: "一天前",
status: "重大风险"
},
{
title: "H.R.8333《生物安全法案》将华大基因等...",
time: "一天前",
status: "一般风险"
}
]);
const warningList = ref([]);
// 资源库 法案列表
const billList = ref([
{
billName: "大而美法案",
introductionDate: "2025年7月4日",
status: "特别重大风险",
tagList: ["集成电路", "人工智能"],
img: bill1,
yuan: "众议院",
dangpai: "共和党"
},
{
billName: "GENIUS稳定币法案",
introductionDate: "2025年7月5日",
status: "",
tagList: ["集成电路", "人工智能"],
img: bill2,
yuan: "众议院",
dangpai: "共和党"
},
{
billName: "美越贸易协议",
introductionDate: "2025年7月6日",
status: "",
tagList: ["集成电路", "人工智能"],
img: bill3,
yuan: "众议院",
dangpai: "共和党"
},
{
billName: "美越贸易协议",
introductionDate: "2025年7月7日",
status: "特别重大风险",
tagList: ["集成电路", "人工智能"],
img: bill4,
yuan: "众议院",
dangpai: "共和党"
},
{
billName: "汽车零部件25%关税实施规则",
introductionDate: "2025年7月10日",
status: "重大风险",
tagList: ["集成电路", "人工智能"],
img: bill5,
yuan: "众议院",
dangpai: "共和党"
},
{
billName: "汽车零部件25%关税实施规则",
introductionDate: "2025年7月12日",
status: "",
tagList: ["集成电路", "人工智能"],
img: bill6,
yuan: "众议院",
dangpai: "共和党"
},
{
billName: "小额豁免包裹政策调整",
introductionDate: "2025年7月14日",
status: "特别重大风险",
tagList: ["集成电路", "人工智能"],
img: bill7,
yuan: "众议院",
dangpai: "共和党"
},
{
billName: "NIH预算否决案",
introductionDate: "2025年7月15日",
status: "重大风险",
tagList: ["集成电路", "人工智能"],
img: bill8,
yuan: "众议院",
dangpai: "共和党"
},
{
billName: "得州国会选区重划法案",
introductionDate: "2025年7月17日",
status: "一般风险",
tagList: ["集成电路", "人工智能"],
img: bill9,
yuan: "众议院",
dangpai: "共和党"
},
{
billName: "美越贸易协议",
introductionDate: "2025年7月24日",
status: "",
tagList: ["集成电路", "人工智能"],
img: bill10,
yuan: "众议院",
dangpai: "共和党"
},
{
billName: "美越贸易协议",
introductionDate: "2025年8月4日",
status: "",
tagList: ["集成电路", "人工智能"],
img: bill11,
yuan: "众议院",
dangpai: "共和党"
},
{
billName: "美越贸易协议",
introductionDate: "2025年8月8日",
status: "特别重大风险",
tagList: ["集成电路", "人工智能"],
img: bill12,
yuan: "众议院",
dangpai: "共和党"
},
{
billName: "美越贸易协议",
introductionDate: "2025年8月8日",
status: "特别重大风险",
tagList: ["集成电路", "人工智能"],
img: bill12,
yuan: "众议院",
dangpai: "共和党"
}
]);
// const billList = ref([
// {
// billName: "大而美法案",
// introductionDate: "2025年7月4日",
// status: "特别重大风险",
// tagList: ["集成电路", "人工智能"],
// img: bill1,
// yuan: "众议院",
// dangpai: "共和党"
// },
// {
// billName: "GENIUS稳定币法案",
// introductionDate: "2025年7月5日",
// status: "",
// tagList: ["集成电路", "人工智能"],
// img: bill2,
// yuan: "众议院",
// dangpai: "共和党"
// },
// {
// billName: "美越贸易协议",
// introductionDate: "2025年7月6日",
// status: "",
// tagList: ["集成电路", "人工智能"],
// img: bill3,
// yuan: "众议院",
// dangpai: "共和党"
// },
// {
// billName: "美越贸易协议",
// introductionDate: "2025年7月7日",
// status: "特别重大风险",
// tagList: ["集成电路", "人工智能"],
// img: bill4,
// yuan: "众议院",
// dangpai: "共和党"
// },
// {
// billName: "汽车零部件25%关税实施规则",
// introductionDate: "2025年7月10日",
// status: "重大风险",
// tagList: ["集成电路", "人工智能"],
// img: bill5,
// yuan: "众议院",
// dangpai: "共和党"
// },
// {
// billName: "汽车零部件25%关税实施规则",
// introductionDate: "2025年7月12日",
// status: "",
// tagList: ["集成电路", "人工智能"],
// img: bill6,
// yuan: "众议院",
// dangpai: "共和党"
// },
// {
// billName: "小额豁免包裹政策调整",
// introductionDate: "2025年7月14日",
// status: "特别重大风险",
// tagList: ["集成电路", "人工智能"],
// img: bill7,
// yuan: "众议院",
// dangpai: "共和党"
// },
// {
// billName: "NIH预算否决案",
// introductionDate: "2025年7月15日",
// status: "重大风险",
// tagList: ["集成电路", "人工智能"],
// img: bill8,
// yuan: "众议院",
// dangpai: "共和党"
// },
// {
// billName: "得州国会选区重划法案",
// introductionDate: "2025年7月17日",
// status: "一般风险",
// tagList: ["集成电路", "人工智能"],
// img: bill9,
// yuan: "众议院",
// dangpai: "共和党"
// },
// {
// billName: "美越贸易协议",
// introductionDate: "2025年7月24日",
// status: "",
// tagList: ["集成电路", "人工智能"],
// img: bill10,
// yuan: "众议院",
// dangpai: "共和党"
// },
// {
// billName: "美越贸易协议",
// introductionDate: "2025年8月4日",
// status: "",
// tagList: ["集成电路", "人工智能"],
// img: bill11,
// yuan: "众议院",
// dangpai: "共和党"
// },
// {
// billName: "美越贸易协议",
// introductionDate: "2025年8月8日",
// status: "特别重大风险",
// tagList: ["集成电路", "人工智能"],
// img: bill12,
// yuan: "众议院",
// dangpai: "共和党"
// },
// {
// billName: "美越贸易协议",
// introductionDate: "2025年8月8日",
// status: "特别重大风险",
// tagList: ["集成电路", "人工智能"],
// img: bill12,
// yuan: "众议院",
// dangpai: "共和党"
// }
// ]);
// 当前展示法案列表
const curBillList = computed(() => {
const startIndex = (currentPage.value - 1) * 12;
const endIndex = startIndex + 12;
return billList.value.slice(startIndex, endIndex);
});
// const curBillList = computed(() => {
// const startIndex = (currentPage.value - 1) * 12;
// const endIndex = startIndex + 12;
// return billList.value.slice(startIndex, endIndex);
// });
const box7selectetedTime = ref("2025");
const box7YearList = ref([
......@@ -975,52 +983,24 @@ const box8YearList = ref([
value: "2022"
}
]);
const releaseTime = ref("近一年发布"); // 发布时间
// 排序方式
const releaseTime = ref(true);
const releaseTimeList = ref([
{
label: "近半年发布",
value: "近半年发布"
label: "正序",
value: true
},
{
label: "近一年发布",
value: "近一年发布"
},
{
label: "近两年发布",
value: "近两年发布"
},
{
label: "近三年发布",
value: "近三年发布"
},
{
label: "近五年发布",
value: "近五年发布"
label: "倒序",
value: false
}
]);
// 涉华法案数量使用的领域分类列表
const categoryList = ref([]);
// 资源库使用的领域分类列表
const cateKuList = ref([]);
const categoryList = ref([
// "全部分类",
// "生物科技",
// "集成电路",
// "通信网络",
// "量子科技",
// "新能源",
// "新一代信息技术",
// "海洋",
// "先进制造",
// "新材料",
// "航空航天",
]);
const curCategoryList = ref([]);
const curCategoryIndex = ref(0);
const SHOW_COUNT = 10;
const activeCate = ref("全部分类");
const activeHylyId = ref("");
// 获取领域分类
const handleGetHylyList = async () => {
......@@ -1028,79 +1008,14 @@ const handleGetHylyList = async () => {
const res = await getHylyList();
console.log("行业领域列表", res);
categoryList.value = res.data;
const obj = {
id: 0,
pid: "",
name: "全部分类"
};
categoryList.value = [obj, ...categoryList.value];
curCategoryList.value = categoryList.value.slice(0, SHOW_COUNT);
cateKuList.value = res.data;
} catch (error) {}
};
const handleClickCate = cate => {
console.log(cate);
activeCate.value = cate.name;
activeHylyId.value = cate.id;
handleGetBillsByType();
};
// 新闻资讯
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 · ​福克斯新闻网"
}
]);
const newsList = ref([]);
// 社交媒体
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政策强调技术开放与快速应用,但可能以牺牲安全防范为代价,开启了“潘多拉魔盒”。`
}
]);
const messageList = ref([]);
// 获取热门法案
const handleGetHotBills = async () => {
......@@ -1115,8 +1030,11 @@ const handleGetHotBills = async () => {
// 获取法案风险信号
const handleGetBillRiskSignal = async () => {
const params = {
moduleId: "0100"
};
try {
const res = await getBillRiskSignal();
const res = await getBillRiskSignal(params);
console.log("法案风险信号", res);
if (res.code === 200) {
warningList.value = res.data;
......@@ -1124,25 +1042,180 @@ const handleGetBillRiskSignal = async () => {
} catch (error) {}
};
// 根据法案类型获取法案列表
const handleGetBillsByType = async () => {
// 获取新闻资讯
const handleGetNews = async () => {
const params = {
type: activeHylyId.value
moduleId: "0100"
};
try {
const res = await getBillsByType(params);
console.log("根据法案类型获取法案列表", res);
billList.value = res.data.map(item => {
return {
billId: item.billId,
billName: item.billName,
introductionDate: item.introductionDate,
img: bill1
};
});
const res = await getNews(params);
console.log("新闻资讯", res);
if (res.code === 200) {
newsList.value = res.data;
}
} catch (error) {}
};
// 获取社交媒体
const handleGetRemarks = async () => {
const params = {
moduleId: "0100"
};
try {
const res = await getRemarks(params);
console.log("社交媒体", res);
if (res.code === 200) {
messageList.value = res.data;
}
} catch (error) {}
};
// 获取提出部门列表
const postOrgList = ref([{ departmentName: "全部委员会", departmentId: "全部委员会" }]);
const handleGetPostOrgList = async () => {
try {
const res = await getPostOrgList();
console.log("提出部门列表", res);
if (res.code === 200) {
const list = res.data.filter(item => item.departmentId);
postOrgList.value = [
{ departmentName: "全部委员会", departmentId: "全部委员会" },
...list
];
}
} catch (error) {}
};
// 获取提出议员列表
const postMemberList = ref([{ memberName: "全部提出议员", memberId: "全部提出议员" }]);
const handleGetPostMemberList = async () => {
try {
const res = await getPostMemberList();
console.log("提出议员列表", res);
if (res.code === 200) {
const list = res.data.filter(item => item.memberId);
postMemberList.value = [
{ memberName: "全部提出议员", memberId: "全部提出议员" },
...list
];
}
} catch (error) {}
};
// 获取资源库
const bills = ref([]);
const total = ref(0);
const pageSize = ref(4);
const loading = ref(false);
const abortController = ref(null);
const handleGetBills = async () => {
// 取消上一次未完成的请求
if (abortController.value) {
abortController.value.abort();
}
// 创建新的 AbortController
abortController.value = new AbortController();
loading.value = true;
const params = {
currentPage: currentPage.value - 1, // Standard Spring Boot page index is 0-based
pageSize: pageSize.value
};
if (!activeYyList.value.includes("全部议院")) {
params.congressIds = activeYyList.value.join(',');
}
if (footerSelect1.value !== "全部委员会") {
params.departmentId = footerSelect1.value;
}
if (!activeDpList.value.includes("全部党派")) {
params.partyIds = activeDpList.value.join(',');
}
if (footerSelect2.value !== "全部提出议员") {
params.personId = footerSelect2.value;
}
if (!activeAreaList.value.includes("全部领域")) {
params.researchIds = activeAreaList.value.join(',');
}
if (releaseTime.value !== true) {
params.sortFun = releaseTime.value;
}
if (!activePubTime.value.includes("全部时间")) {
params.years = activePubTime.value.join(',');
}
try {
const res = await getBills(params, abortController.value.signal);
console.log("资源库列表", res);
if (res.code === 200) {
if (res.data && res.data.content) {
bills.value = res.data.content.map(item => ({
// id: item.billId,
name: item.billName,
eName: item.billNameEn,
tcr: item.personName,
wyh: item.congressName,
areaList: item.hylyList || [],
zxdy: item.latestAction,
progress: item.stageList || []
}));
total.value = res.data.totalElements;
} else {
bills.value = [];
total.value = 0;
}
}else {
bills.value = [];
total.value = 0;
}
loading.value = false;
} catch (error) {
if (error.name !== 'AbortError') {
console.error(error);
loading.value = false;
}
}
};
// 处理选择委员会变化
const handleFooterSelect1Change = (val) => {
console.log("选择委员会变化", val);
// 等会再做处理
handleGetBills();
};
// 处理选择议员变化
const handleFooterSelect2Change = (val) => {
console.log("选择议员变化", val);
// 等会再做处理
handleGetBills();
};
// 处理选择排序方式变化
const handlePxChange = (val) => {
console.log("选择排序方式变化", val);
// 等会再做处理
handleGetBills();
};
// 根据法案类型获取法案列表
// const handleGetBillsByType = async () => {
// const params = {
// type: activeHylyId.value
// };
// try {
// const res = await getBillsByType(params);
// console.log("根据法案类型获取法案列表", res);
// billList.value = res.data.map(item => {
// return {
// billId: item.billId,
// billName: item.billName,
// introductionDate: item.introductionDate,
// img: bill1
// };
// });
// } catch (error) {}
// };
// 涉华法案数量
const box5Select = ref("全部领域");
const box5Data = ref({
......@@ -1171,6 +1244,7 @@ const box5Data = ref({
}
]
});
const box5HasData = ref(true);
const handleGetBillCount = async () => {
try {
let params = {};
......@@ -1179,7 +1253,8 @@ const handleGetBillCount = async () => {
}
const res = await getBillCount(params);
console.log("涉华法案统计", res);
if (res.code === 200 && res.data) {
if (res.code === 200 && res.data && res.data.length > 0) {
box5HasData.value = true;
const sortedData = res.data.sort((a, b) => a.month.localeCompare(b.month));
box5Data.value = {
title: sortedData.map(item => item.month),
......@@ -1196,24 +1271,45 @@ const handleGetBillCount = async () => {
percent: sortedData.map(item => item.percent)
};
} else {
// 保持默认数据或清空
// box5Data.value = {};
// 接口异常(如500)时,清空图表数据以避免报错或显示错误信息
box5HasData.value = false;
box5Data.value = {
title: [],
data: [
{ name: "提出法案", value: [] },
{ name: "通过法案", value: [] }
],
percent: []
};
}
} catch (error) {
console.error("获取涉华法案统计error", error);
// 发生错误时同样清空数据
box5HasData.value = false;
box5Data.value = {
title: [],
data: [
{ name: "提出法案", value: [] },
{ name: "通过法案", value: [] }
],
percent: []
};
}
};
const handleBox5 = async () => {
await handleGetBillCount();
const proposed = box5Data.value.data[0].value;
const passed = box5Data.value.data[1].value;
const rate = box5Data.value.percent || proposed.map((p, i) => {
const pass = passed[i] || 0;
return p ? ((pass / p) * 100).toFixed(2) : 0;
});
let box5Chart = getMultiLineChart(box5Data.value.title, proposed, passed, rate);
setChart(box5Chart, "box5Chart");
if (box5HasData.value) {
await nextTick();
const proposed = box5Data.value.data[0].value;
const passed = box5Data.value.data[1].value;
const rate = box5Data.value.percent || proposed.map((p, i) => {
const pass = passed[i] || 0;
return p ? ((pass / p) * 100).toFixed(2) : 0;
});
let box5Chart = getMultiLineChart(box5Data.value.title, proposed, passed, rate);
setChart(box5Chart, "box5Chart");
}
};
const handleBox5Change = () => {
......@@ -1221,11 +1317,16 @@ const handleBox5Change = () => {
};
// 法案提出部门
const box7HasData = ref(true);
const handleBox7Data = async () => {
try {
const res = await getBillPostOrg({ year: box7selectetedTime.value });
console.log("法案提出部门", res);
if (res.code === 200 && res.data) {
if (res.code === 200 && res.data && res.data.length > 0) {
box7HasData.value = true;
// 必须等待DOM更新,因为v-if切换可能导致元素刚被创建
await nextTick();
const apiData = res.data;
const houseItems = apiData.filter(i => i.congressName === "House");
......@@ -1250,9 +1351,14 @@ const handleBox7Data = async () => {
const box7Chart = getDoublePieChart(data1, data2);
setChart(box7Chart, "box7Chart");
} else {
// 接口异常(如500)时,清空图表数据以避免报错或显示错误信息
box7HasData.value = false;
setChart({}, "box7Chart");
}
} catch (error) {
console.error("获取法案提出部门数据失败", error);
box7HasData.value = false;
}
};
......@@ -1261,28 +1367,7 @@ watch(box7selectetedTime, () => {
});
// 关键条款
const wordCloudData = ref([
{ name: "限制中国获取能源技术", value: 100 },
{ name: "未实现赤字控制目标", value: 66 },
{ name: "关注核聚变能源研究", value: 77 },
{ name: "抵制外国人才争夺", value: 35 },
{ name: "进行可再生能源税收减免", value: 88 },
{ name: "评估中美现代化技术", value: 57 },
{ name: "应对中国制造2025战略", 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 },
{ name: "减少燃料对外依赖", value: 81 },
{ name: "加强供应链风险管理", value: 73 }
]);
const wordCloudData = ref([]);
const handleGetKeyTK = async () => {
try {
const res = await getBillOverviewKeyTK();
......@@ -1306,37 +1391,7 @@ const handleBox6 = async () => {
};
// 涉华领域分布
const box9ChartColorList = ref(["#4096FF", "#FFA39E", "#ADC6FF", "#FFC069", "#B5F5EC", "#B37FEB", "#D6E4FF"]);
const box9ChartData = ref([
// {
// name: "半导体",
// value: 50
// },
// {
// name: "电子设备",
// value: 46
// },
// {
// name: "显示技术",
// value: 40
// },
// {
// name: "新能源",
// value: 32
// },
// {
// name: "通信设备",
// value: 31
// },
// {
// name: "汽车",
// value: 30
// },
// {
// name: "其他",
// value: 24
// }
]);
const box9ChartData = ref([]);
const box9selectetedTime = ref("2025");
const box9YearList = ref([
{
......@@ -1356,6 +1411,7 @@ const box9YearList = ref([
value: "2022"
}
]);
const box9HasData = ref(true);
const getBox9Data = async () => {
const params = {
year: box9selectetedTime.value
......@@ -1363,98 +1419,37 @@ const getBox9Data = async () => {
try {
const res = await getBillIndustry(params);
console.log("box9-涉华法案领域分布", res.data);
if (res.code === 200 && res.data) {
if (res.code === 200 && res.data && res.data.length > 0) {
box9HasData.value = true;
box9ChartData.value = res.data;
} else {
box9HasData.value = false;
box9ChartData.value = [];
}
} catch (error) {}
} catch (error) {
box9HasData.value = false;
box9ChartData.value = [];
}
};
const handleBox9Data = async () => {
await getBox9Data();
const box9Chart = getPieChart(
box9ChartData.value.map(item => {
return {
name: item.industryName,
value: item.countBill
};
})
);
setChart(box9Chart, "box9Chart");
if (box9HasData.value) {
await nextTick();
const box9Chart = getPieChart(
box9ChartData.value.map(item => {
return {
name: item.industryName,
value: item.countBill
};
})
);
setChart(box9Chart, "box9Chart");
}
};
const box7Data = ref([
[
{
name: "众议院",
value: 298
},
{
name: "参议院",
value: 149
}
],
[
{
name: "拨款委员会",
value: 50,
type: "众议院"
},
{
name: "筹款委员会",
value: 50,
type: "众议院"
},
{
name: "外交事务委员会",
value: 46,
type: "众议院"
},
{
name: "国土安全委员会",
value: 40,
type: "众议院"
},
{
name: "司法委员会",
value: 40,
type: "众议院"
},
{
name: "军事委员会",
value: 40,
type: "众议院"
},
{
name: "能源和商业委员会",
value: 32,
type: "众议院"
},
{
name: "拨款委员会1",
value: 32,
type: "参议院"
},
{
name: "财政委员会",
value: 31,
type: "参议院"
},
{
name: "能源",
value: 30,
type: "参议院"
},
{
name: "能源1",
value: 30,
type: "参议院"
},
{
name: "其他",
value: 24,
type: "参议院"
}
]
]);
watch(box9selectetedTime, () => {
handleBox9Data();
});
const box8Data = ref([]);
......@@ -1471,9 +1466,13 @@ const handleBox8Data = async () => {
dangpai: Cyy,
yuan: item.position === "Democratic" ? Mzd : Ghd
}));
} else {
// 接口异常(如500)时,清空图表数据以避免报错或显示错误信息
box8Data.value = [];
}
} catch (error) {
console.error("获取关键议员提案失败", error);
box8Data.value = [];
}
};
......@@ -1522,97 +1521,137 @@ const handleClickTab = tab => {
activeTabName.value = tab.name;
};
const areaList = [
{ id: "全部领域", name: "全部领域" },
{ id: "人工智能", name: "人工智能" },
{ id: "集成电路", name: "集成电路" },
{ id: "通信网络", name: "通信网络" },
{ id: "先进制造", name: "先进制造" },
{ id: "量子科技", name: "量子科技" },
{ id: "生物科技", name: "生物科技" },
{ id: "能源", name: "能源" },
{ id: "航空航天", name: "航空航天" },
{ id: "新材料", name: "新材料" },
{ id: "海洋", name: "海洋" }
];
const activeAreaList = ref(["全部领域"]);
const handleAreaChange = (val) => {
if (val.includes("全部领域") && val.length > 1) {
if (val[val.length - 1] === "全部领域") {
activeAreaList.value = ["全部领域"];
} else {
activeAreaList.value = val.filter(item => item !== "全部领域");
}
} else if (val.length === 0) {
activeAreaList.value = ["全部领域"];
}
// 打印 activeAreaList.value
console.log(activeAreaList.value);
handleGetBills();
};
const dpList = ref([
{ id: "全部党派", name: "全部党派" },
{ id: "民主党", name: "民主党" },
{ id: "共和党", name: "共和党" }
{ id: "Democratic", name: "民主党" },
{ id: "Republican", name: "共和党" }
]);
const activeDpList = ref(["全部党派"]);
// 处理选择党派变化
const handleDpChange = (val) => {
if (val.includes("全部党派") && val.length > 1) {
if (val[val.length - 1] === "全部党派") {
activeDpList.value = ["全部党派"];
} else {
activeDpList.value = val.filter(item => item !== "全部党派");
}
} else if (val.length === 0) {
activeDpList.value = ["全部党派"];
}
console.log("选择党派变化", activeDpList.value);
handleGetBills();
};
const yyList = ref([
{ id: "全部议院", name: "全部议院" },
{ id: "参议院", name: "参议院" },
{ id: "众议院", name: "众议院" }
{ id: "S", name: "参议院" },
{ id: "H", name: "众议院" }
]);
const activeYyList = ref(["全部议院"]);
// 处理选择议院变化
const handleYyChange = (val) => {
if (val.includes("全部议院") && val.length > 1) {
if (val[val.length - 1] === "全部议院") {
activeYyList.value = ["全部议院"];
} else {
activeYyList.value = val.filter(item => item !== "全部议院");
}
} else if (val.length === 0) {
activeYyList.value = ["全部议院"];
}
console.log("选择议院变化", activeYyList.value);
handleGetBills();
};
const pubTime = ref([
{ id: "全部时间", name: "全部时间" },
{ id: "2025", name: "2025年" },
{ id: "2024", name: "2024年" },
{ id: "2023", name: "2023年" },
{ id: "2022", name: "2022年" },
{ id: "2021", name: "2021年" },
{ id: "更早时间", name: "更早时间" }
{ id: "2025", name: "2025年" },
{ id: "2024", name: "2024年" },
{ id: "2023", name: "2023年" },
{ id: "2022", name: "2022年" },
{ id: "2021", name: "2021年" },
// { id: "更早时间", name: "更早时间" }
]);
const activePubTime = ref(["全部时间"]);
const footerSelectList1 = ref([
{
label: "全部委员会",
value: "全部委员会"
// 处理选择时间变化
const handlePubTimeChange = (val) => {
if (val.includes("全部时间") && val.length > 1) {
if (val[val.length - 1] === "全部时间") {
activePubTime.value = ["全部时间"];
} else {
activePubTime.value = val.filter(item => item !== "全部时间");
}
} else if (val.length === 0) {
activePubTime.value = ["全部时间"];
}
]);
const footerSelect1 = ref("全部委员会");
console.log("选择时间变化", activePubTime.value);
handleGetBills();
};
const footerSelectList2 = ref([
{
label: "全部提出议员",
value: "全部提出议员"
}
]);
const footerSelect1 = ref("全部委员会");
const footerSelect2 = ref("全部提出议员");
const footerBillList = ref([
{
name: "H.R.1-大而美法案",
eName: "One Big Beautiful Bill Act",
tcr: "乔迪·阿灵顿等2人",
wyh: "众议院-预算委员会",
areaList: ["集成电路", "人工智能"],
zxdy: "2025.07.04 成为公法 No: 119-21",
progress: []
},
{
name: "H.R.1-大而美法案",
eName: "One Big Beautiful Bill Act",
tcr: "乔迪·阿灵顿等2人",
wyh: "众议院-预算委员会",
areaList: ["集成电路", "人工智能"],
zxdy: "2025.07.04 成为公法 No: 119-21",
progress: []
},
{
name: "H.R.1-大而美法案",
eName: "One Big Beautiful Bill Act",
tcr: "乔迪·阿灵顿等2人",
wyh: "众议院-预算委员会",
areaList: ["集成电路", "人工智能"],
zxdy: "2025.07.04 成为公法 No: 119-21",
progress: []
}
]);
// const footerBillList = ref([
// {
// name: "H.R.1-大而美法案",
// eName: "One Big Beautiful Bill Act",
// tcr: "乔迪·阿灵顿等2人",
// wyh: "众议院-预算委员会",
// areaList: ["集成电路", "人工智能"],
// zxdy: "2025.07.04 成为公法 No: 119-21",
// progress: []
// },
// {
// name: "H.R.1-大而美法案",
// eName: "One Big Beautiful Bill Act",
// tcr: "乔迪·阿灵顿等2人",
// wyh: "众议院-预算委员会",
// areaList: ["集成电路", "人工智能"],
// zxdy: "2025.07.04 成为公法 No: 119-21",
// progress: []
// },
// {
// name: "H.R.1-大而美法案",
// eName: "One Big Beautiful Bill Act",
// tcr: "乔迪·阿灵顿等2人",
// wyh: "众议院-预算委员会",
// areaList: ["集成电路", "人工智能"],
// zxdy: "2025.07.04 成为公法 No: 119-21",
// progress: []
// }
// ]);
onMounted(async () => {
handleGetHylyList();
// 获取风险信号
handleGetBillRiskSignal();
// 获取新闻资讯
handleGetNews();
// 获取社交媒体
handleGetRemarks();
// 获取提出部门列表
handleGetPostOrgList();
// 获取提出议员列表
handleGetPostMemberList();
// 获取资源库
handleGetBills();
// handleGetBillsByType();
handleBox5(); //涉华法案统计
......@@ -2441,6 +2480,10 @@ onUnmounted(() => {});
width: 749px;
margin-left: 21px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
cursor: pointer;
&:hover {
background: var(--color-bg-hover);
}
.left {
width: 72px;
height: 48px;
......@@ -2459,7 +2502,7 @@ onUnmounted(() => {});
justify-content: space-between;
.title {
margin-top: 13px;
width: 520px;
width: 440px;
height: 24px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
......@@ -3108,6 +3151,13 @@ onUnmounted(() => {});
background: var(--color-main-active);
}
}
.disabled {
cursor: not-allowed;
opacity: 0.5;
&:hover {
background: transparent;
}
}
}
.select-box {
height: 42px;
......@@ -3120,9 +3170,12 @@ onUnmounted(() => {});
height: 1401px;
margin: 0 auto;
display: flex;
justify-content: space-between;
align-items: flex-start;
.left {
width: 300px;
height: 784px;
// min-height: 784px;
padding-bottom: 33px;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 10px;
......@@ -3186,22 +3239,25 @@ onUnmounted(() => {});
}
.right-main {
height: 1264px;
overflow: hidden;
// overflow: hidden;
.right-main-box {
width: 1280px;
height: 300px;
padding-bottom: 24px;
border-radius: 10px;
box-shadow: 0px 0px 10px 0px rgba(25, 69, 130, 0.1);
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
margin-bottom: 16px;
overflow: hidden;
cursor: pointer;
.header {
height: 91px;
width: 1200px;
margin: 0 auto;
border-bottom: 1px solid rgba(234, 236, 238, 1);
padding-top: 19px;
.title {
margin-top: 19px;
// margin-top: 19px;
// padding-top: 19px;
height: 26px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
......@@ -3229,13 +3285,13 @@ onUnmounted(() => {});
margin-top: 2px;
.item {
margin-top: 12px;
height: 24px;
// height: 24px;
display: flex;
.item-left {
width: 91px;
height: 24px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
width: 100px;
// height: 24px;
color: rgb(59, 65, 75);
font-family: "Microsoft YaHei";
font-size: 16px;
font-weight: 700;
line-height: 24px;
......@@ -3243,9 +3299,10 @@ onUnmounted(() => {});
text-align: left;
}
.item-right {
max-width: 1000px;
margin-left: 10px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-family: "Microsoft YaHei";
font-size: 16px;
font-weight: 400;
line-height: 24px;
......@@ -3263,7 +3320,7 @@ onUnmounted(() => {});
border-radius: 4px;
background: rgba(231, 243, 255, 1);
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-family: "Microsoft YaHei";
font-size: 14px;
font-weight: 400;
}
......@@ -3280,7 +3337,7 @@ onUnmounted(() => {});
padding-top: 12px;
.footer-left {
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-family: "Microsoft YaHei";
font-size: 16px;
font-weight: 400;
line-height: 32px;
......@@ -3297,7 +3354,7 @@ onUnmounted(() => {});
justify-content: space-between;
.footer-left {
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-family: "Microsoft YaHei";
font-size: 16px;
font-weight: 400;
line-height: 32px;
......
......@@ -16,11 +16,9 @@ const getDoublePieChart = (data1, data2) => {
},
label: {
position: 'inside',
textStyle: {
fontSize: '16px',
fontWeight: 700,
// color: '#333'
}
fontSize: '16px',
fontWeight: 700,
// color: '#333'
},
data: data1.map(item => {
return {
......
......@@ -212,6 +212,7 @@ onMounted(() => {
height: 1016px;
background: rgba(249, 250, 252, 1);
position: relative;
margin: 0 auto;
.layout-header {
width: 1920px;
height: 64px;
......
......@@ -37,10 +37,10 @@
<div class="right1-item" v-for="item in basicInfo.hylyList" :key="item">{{ item }}</div>
</div>
</div>
<div class="box1-right-item">
<!-- <div class="box1-right-item">
<div class="item-left">法案类别:</div>
<div class="item-right">{{ basicInfo.typeName }}</div>
</div>
</div> -->
<div class="box1-right-item">
<div class="item-left">委员会报告:</div>
<div class="item-right2" v-if="basicInfo.reportList">
......@@ -132,11 +132,11 @@
</div> -->
</div>
</div>
<div class="box2-footer">
<!-- <div class="box2-footer">
<div class="btn-more">
<img src="../assets/images/btn-more.png" alt="" />
</div>
</div>
</div> -->
</div>
</div>
<div class="introduction-wrap-right">
......@@ -154,7 +154,7 @@
</div>
<div class="introduction-wrap-right-main">
<div class="right-main-box1">
<div class="name-box">
<!-- <div class="name-box">
<el-select
v-model="selectValue"
placeholder="请选择"
......@@ -174,7 +174,7 @@
{{ item.name }}
</div>
</div>
</div>
</div> -->
<div class="info-box">
<div class="info-left">
<img src="./assets/images/usr1.png" alt="" />
......@@ -889,6 +889,7 @@ onMounted(() => {
background: #fff;
border-radius: 10px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
position: relative;
.box2-main {
margin-top: 10px;
height: calc(100% - 70px); // Subtract header height
......@@ -1001,6 +1002,11 @@ onMounted(() => {
margin-top: 7px;
display: flex;
justify-content: center;
position: absolute;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
z-index: 99;
.btn-more {
width: 108px;
height: 32px;
......@@ -1024,7 +1030,8 @@ onMounted(() => {
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
.introduction-wrap-right-main {
.right-main-box1 {
height: 218px;
// height: 218px; 将选择框去掉后高度变化
height: 171px;
// border-bottom: 1px solid rgb(243, 243, 244);
.name-box {
display: flex;
......
<template>
<el-row :gutter="20">
<el-col :span="24">
<custom-container title="政令时序及战略里程碑" height="510px">
<!-- 顶部右侧自定义内容 -->
<!-- <template #header-right>
<div style="display: flex; gap: 8px">
<el-input placeholder="搜索项目..." clearable style="width: 200px">
<template #prefix>
<el-icon><Search /></el-icon>
</template>
</el-input>
<el-button type="primary">涉华背景</el-button>
<el-button>全部背景</el-button>
</div>
</template> -->
<template #default>
<div class="content-box">
<el-image :src="TimeLine" alt="" style="width: 100%; height: 306px" />
<div class="content-box-footer">
<img class="footer-img-small" src="@/assets/images/icon-guanzhu.png" alt="" />
<span class="content-box-footer-text"> 促进美国人工智能栈技术出口总统政令的时序及战略里程碑分析结果。 </span>
<img class="footer-img-large" src="@/assets/images/icon-right-circle.png" alt="" />
</div>
</div>
</template>
</custom-container>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="24">
<custom-container title="相关政令关联分析" height="505px">
<template #default>
<div class="content-box">
<div class="content-tabs">
<div
:class="['content-tabs-item', activeTab === item.id ? 'contetn-tabs-item-active' : '']"
v-for="item in data"
:key="item.id"
@click="tabsClick(item.id)"
>
{{ item.name }}
<el-image :src="IconOpen" :style="{ width: '16px', height: '16px' }"></el-image>
</div>
</div>
<div class="content-tabs-pane">
<div class="content-tabs-pane-left">
<div class="content-tabs-pane-header">
<el-image :src="IconNews" :style="{ width: '20px', height: '20px' }"></el-image>
政令基本信息
</div>
<div class="content-tabs-pane-content">
<div class="content-tabs-pane-content-item">
<span class="content-tabs-pane-content-item-title">政令名称:</span>
<span>{{ currentContent.info.fullName }}</span>
</div>
<div class="content-tabs-pane-content-item">
<span class="content-tabs-pane-content-item-title">英文名称:</span>
<span>{{ currentContent.info.fullNameEn }}</span>
</div>
<div class="content-tabs-pane-content-item">
<span class="content-tabs-pane-content-item-title">相关领域:</span>
<!-- <span>{{ currentContent.info.fullName }}</span> -->
<el-tag v-for="item in currentContent.info.tags" :key="item" type="primary">{{ item }}</el-tag>
</div>
<div class="content-tabs-pane-content-item">
<span class="content-tabs-pane-content-item-title">签署时间:</span>
<span>{{ currentContent.info.time }}</span>
</div>
<div class="content-tabs-pane-content-item">
<span class="content-tabs-pane-content-item-title">签署总统:</span>
<span>{{ currentContent.info.president }}</span>
</div>
<div class="content-tabs-pane-content-item">
<span class="content-tabs-pane-content-item-title">政令编号:</span>
<span>{{ currentContent.info.orderNum }}</span>
</div>
<div class="content-tabs-pane-content-item">
<span class="content-tabs-pane-content-item-title">执行期限:</span>
<span>{{ currentContent.info.period }}</span>
</div>
</div>
</div>
<div class="content-tabs-pane-right">
<div class="content-tabs-pane-header">
<el-image :src="IconNews" :style="{ width: '20px', height: '20px' }"></el-image>
政令主要条款
</div>
<div class="content-tabs-pane-content">
<div class="content-tabs-pane-content-list">
<div class="content-tabs-pane-content-list-item" v-for="(item, index) in clause" :key="item.id">
<span class="content-tabs-pane-content-list-item-index">
{{ (currentPage - 1) * 5 + index + 1 }}
</span>
<span class="content-tabs-pane-content-list-item-content">
{{ item.content }}
</span>
</div>
</div>
</div>
<div class="content-tabs-pane-footer">
<el-pagination
v-model:current-page="currentPage"
:page-size="5"
size="small"
:total="currentContent.clause.length"
background
layout="total, prev, pager, next"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</div>
</div>
</div>
</template>
</custom-container>
</el-col>
</el-row>
</template>
<script setup>
import { onMounted, reactive, ref } from "vue";
import { Search } from "@element-plus/icons-vue";
import CustomContainer from "@/components/Container/index.vue";
import { TAGTYPE } from "@/common/constant.js";
import TimeLine from "@/assets/images/time-line.png";
import IconOpen from "@/assets/images/icon-open.png";
import IconNews from "@/assets/images/icon-news.png";
import { data } from "./mock";
const activeTab = ref(11);
const currentContent = ref({});
const clause = ref([]);
const tableData = ref([
{
date: "2024年5月14日",
entity: "37/24",
entityCN: "37/4",
proportion: "100%/1"
},
{
date: "2024年4月11日",
entity: "37/24",
entityCN: "37/4",
proportion: "100%/1"
},
{
date: "2024年2月27日",
entity: "37/24",
entityCN: "37/4",
proportion: "100%/1"
},
{
date: "2023年12月7日",
entity: "37/24",
entityCN: "37/4",
proportion: "100%/1"
},
{
date: "2023年11月15日",
entity: "37/24",
entityCN: "37/4",
proportion: "100%/1"
},
{
date: " 2024年3月5日",
entity: "37/24",
entityCN: "37/4",
proportion: "100%/1"
}
]);
// 重点实体列表
const entityList = ref([
{
entity: "中国科学技术大学",
tags: ["双一流", "985", "关税政策"]
},
{
entity: "合肥量子信息科学国家实验室",
tags: ["中国上市企业"]
},
{
entity: "中国科学院物理研究所",
tags: ["科研院所"]
}
]);
let option = null;
onMounted(() => {
currentContent.value = data.filter(item => item.id === activeTab.value)[0];
clause.value = currentContent.value.clause.slice((currentPage.value - 1) * 5, currentPage.value * 5);
console.log("数据查看 =>", currentContent.value);
// 更新频率
option = {
grid: {
left: 0,
right: 0,
top: 0,
bottom: 0
},
legend: {
show: true,
bottom: -5,
icon: "circle",
itemWidth: 6,
itemHeight: 6,
textStyle: {
color: "#4E5969"
}
},
tooltip: {
show: true,
formatter(params) {
return `总计:${params.value}<br>${params.data.size}`;
}
},
series: [
{
type: "pie",
radius: ["40%", "70%"],
avoidLabelOverlap: true,
label: {
show: false,
position: "center"
},
data: [
{
value: 37,
name: "中国上市企业"
},
{
value: 4,
name: "科研院所"
}
]
}
]
};
});
const tabsClick = id => {
console.log(id);
activeTab.value = id;
currentContent.value = data.filter(e => e.id === id)[0];
currentPage.value = 1;
clause.value = currentContent.value.clause.slice((currentPage.value - 1) * 5, currentPage.value * 5);
};
const currentPage = ref(1);
const handleCurrentChange = val => {
currentPage.value = val;
clause.value = currentContent.value.clause.slice((val - 1) * 5, val * 5);
console.log(`当前页: ${val}`);
console.log(`当前页-shuju`, clause.value);
};
const handleSizeChange = val => {
console.log(val);
};
</script>
<style scoped>
.content-box {
/* height: 90vh; */
display: flex;
flex-direction: row;
justify-content: flex-start;
border: 1px solid rgba(234, 236, 238, 1);
overflow: hidden;
}
.content-tabs {
height: 100%;
padding-top: 2%;
width: 300px;
border-right: 1px solid rgba(234, 236, 238, 1);
}
.content-tabs-item {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: 1px solid rgba(234, 236, 238, 1);
color: rgba(95, 101, 108, 1);
font-size: 16px;
font-weight: 400;
padding-left: 24px;
padding-right: 24px;
height: 36px;
cursor: pointer;
}
.contetn-tabs-item-active {
background-color: rgba(231, 243, 255, 1);
color: var(--color-main-active);
}
.content-tabs-pane {
display: flex;
justify-content: flex-start;
align-items: flex-start;
height: 100%;
flex: 1;
/* padding-top: 25px; */
padding-left: 20px;
background-color: rgba(246, 250, 255, 1);
}
.content-tabs-pane-left {
display: flex;
flex-direction: column;
align-items: flex-start;
height: 100%;
width: 550px;
padding-top: 15px;
gap: 15px;
flex-shrink: 0;
}
.content-tabs-pane-right {
height: 375px;
padding-top: 15px;
padding-left: 20px;
border-left: 1px solid rgba(234, 236, 238, 1);
display: flex;
flex-direction: column;
justify-content: space-between;
padding-right: 15px;
flex-grow: 1;
}
.content-tabs-pane-header {
display: flex;
justify-content: flex-start;
align-items: center;
gap: 8px;
font-size: 16px;
font-weight: 700;
color: var(--base-color);
}
.content-tabs-pane-content {
display: flex;
flex-direction: column;
gap: 15px;
margin-bottom: auto;
}
.content-tabs-pane-content-item {
display: flex;
justify-content: flex-start;
align-items: center;
gap: 8px;
font-size: 16px;
font-weight: 700;
color: var(--base-color);
}
.content-tabs-pane-content-item-title {
font-size: 16px;
font-weight: 700;
color: rgba(59, 65, 75, 1);
}
.content-tabs-pane-content-list {
display: flex;
flex-direction: column;
gap: 12px;
margin-top: 15px;
}
.content-tabs-pane-content-list-item {
display: flex;
justify-content: flex-start;
align-items: center;
padding: 5px 10px;
gap: 8px;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 5px;
}
.content-tabs-pane-content-list-item-index {
height: 24px;
width: 24px;
display: flex;
justify-content: center;
align-items: center;
font-size: 16px;
/* font-weight: 700; */
border-radius: 50%;
color: var(--base-color);
background-color: rgba(231, 243, 255, 1);
}
.content-tabs-pane-content-list-item-content {
font-size: 16px;
font-weight: 400;
color: rgba(10, 18, 30, 1);
}
.content-box-list {
width: 100%;
display: flex;
flex-direction: column;
gap: 12px;
}
.content-box-list-item {
display: flex;
justify-content: space-between;
align-items: center;
gap: 8px;
padding-bottom: 5px;
border-bottom: 1px solid rgba(234, 236, 238, 1);
}
.content-box-list-item-title {
font-size: 16px;
font-weight: 700;
color: rgba(10, 18, 30, 1);
}
.content-box-list-item-tag {
display: flex;
gap: 8px;
}
.content-box-footer {
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
background-color: rgba(246, 251, 255, 1);
padding: 5px 15px;
}
.content-box-footer-text {
font-size: 16px;
font-weight: 400;
color: var(--color-main-active);
}
.footer-img-small {
width: 20px;
height: 20px;
}
.footer-img-large {
width: 24px;
height: 24px;
}
</style>
export const data = [
{
id: 11,
name: "拜登AI芯片出口管制",
info: {
fullName: "推动美国人工智能技术栈出口",
fullNameEn: "Ending Crime and Disorder on America’s Streets",
tags: ["人工智能", "出口管制", "半导体产业", "税收", "光伏产业"],
time: "2025年7月23日",
president: "唐纳德·约翰·特朗普(Donald John Trump)",
orderNum: "第14320号行政命令 (EO 14320)",
period: "签署后90天内建立机制并开始实施"
},
clause: [
{
id: 1,
content: '要求商务部在90天内建立"全栈式"美国AI出口机制。'
},
{
id: 2,
content: '要求每个纳入出口计划的提案必须涵盖完整的"全栈AI技术包"。'
},
{
id: 3,
content: '指示联邦机构提供贷款、担保、股权投资和技术援助支持入选的"优先AI出口包"。'
},
{
id: 4,
content: "要求输出技术必须符合美国出口管制法规,并由多部门对最终用户进行合规与安全联合审查。"
},
{
id: 5,
content: '明确政策目标为"减少对对手国家开发的AI技术的国际依赖"。'
},
{
id: 6,
content: '要求每个纳入出口计划的提案必须涵盖完整的"全栈AI技术包"。'
}
]
},
{
id: 22,
name: "特朗普撤销拜登AI规则",
info: {
fullName: "推动美国人工智能技术栈出口",
fullNameEn: "推动美国人工智能技术栈出口",
tags: ["AI", "出口", "管制"],
time: "2025年7月23日",
president: "唐纳德·约翰·特朗普(Donald John Trump)",
orderNum: "第14320号行政命令 (EO 14320)",
period: "签署后90天内建立机制并开始实施"
},
clause: [
{
id: 1,
content: '要求商务部在90天内建立"全栈式"美国AI出口机制。'
},
{
id: 2,
content: '要求每个纳入出口计划的提案必须涵盖完整的"全栈AI技术包"。'
},
{
id: 3,
content: '指示联邦机构提供贷款、担保、股权投资和技术援助支持入选的"优先AI出口包"。'
},
{
id: 4,
content: "要求输出技术必须符合美国出口管制法规,并由多部门对最终用户进行合规与安全联合审查。"
},
{
id: 5,
content: '明确政策目标为"减少对对手国家开发的AI技术的国际依赖"。'
}
]
},
{
id: 33,
name: "美国AI行动计划",
info: {
fullName: "推动美国人工智能技术栈出口",
fullNameEn: "推动美国人工智能技术栈出口",
tags: ["AI", "出口", "管制"],
time: "2025年7月23日",
president: "唐纳德·约翰·特朗普(Donald John Trump)",
orderNum: "第14320号行政命令 (EO 14320)",
period: "签署后90天内建立机制并开始实施"
},
clause: [
{
id: 1,
content: '要求商务部在90天内建立"全栈式"美国AI出口机制。'
},
{
id: 2,
content: '要求每个纳入出口计划的提案必须涵盖完整的"全栈AI技术包"。'
},
{
id: 3,
content: '指示联邦机构提供贷款、担保、股权投资和技术援助支持入选的"优先AI出口包"。'
},
{
id: 4,
content: "要求输出技术必须符合美国出口管制法规,并由多部门对最终用户进行合规与安全联合审查。"
},
{
id: 5,
content: '明确政策目标为"减少对对手国家开发的AI技术的国际依赖"。'
}
]
},
{
id: 44,
name: "对中国AI芯片限制",
info: {
fullName: "推动美国人工智能技术栈出口",
fullNameEn: "推动美国人工智能技术栈出口",
tags: ["AI", "出口", "管制"],
time: "2025年7月23日",
president: "唐纳德·约翰·特朗普(Donald John Trump)",
orderNum: "第14320号行政命令 (EO 14320)",
period: "签署后90天内建立机制并开始实施"
},
clause: [
{
id: 1,
content: '要求商务部在90天内建立"全栈式"美国AI出口机制。'
},
{
id: 2,
content: '要求每个纳入出口计划的提案必须涵盖完整的"全栈AI技术包"。'
},
{
id: 3,
content: '指示联邦机构提供贷款、担保、股权投资和技术援助支持入选的"优先AI出口包"。'
},
{
id: 4,
content: "要求输出技术必须符合美国出口管制法规,并由多部门对最终用户进行合规与安全联合审查。"
},
{
id: 5,
content: '明确政策目标为"减少对对手国家开发的AI技术的国际依赖"。'
}
]
}
];
<template>
<el-row :gutter="20">
<el-col :span="16">
<custom-container title="实体清单发布机构" height="414px">
<!-- 顶部右侧自定义内容 -->
<!-- <template #header-right>
<div style="display: flex; gap: 8px">
<el-input placeholder="搜索项目..." clearable style="width: 200px">
<template #prefix>
<el-icon><Search /></el-icon>
</template>
</el-input>
<el-button type="primary">政令原文</el-button>
<el-button>全部背景分析报告</el-button>
</div>
</template> -->
<!-- 中间内容自定义 -->
<template #default>
<div class="content-card">
<el-image class="content-img" :src="DecreeInfoImg" fit="fill" />
<div class="content-desc" style="gap: 20px">
<div class="content-desc-item">
<div class="content-desc-title">政令全称:</div>
<div class="content-desc-content">
Further Modifying Reciprocal Tariff Rates to Reflect Ongoing Discussions with the People’s Republic of China
</div>
</div>
<div class="content-desc-item">
<div class="content-desc-title">英文全称:</div>
<div class="content-desc-content">出口管制条例(EAR)、实体清单、商业管制清单(CCL)、232调查等</div>
</div>
<div class="content-desc-item">
<div class="content-desc-title">相关领域:</div>
<!-- <div class="content-desc-content">公法(编号:Pub. L. No. 119-21)</div> -->
<el-tag type="primary">人工智能</el-tag>
<el-tag type="primary">出口管制</el-tag>
<el-tag type="primary">半导体</el-tag>
<el-tag type="primary">关税</el-tag>
<el-tag type="primary">光伏产业</el-tag>
</div>
<div class="content-desc-item">
<div class="content-desc-title">签署时间:</div>
<div class="content-desc-content">2025年7月23日</div>
</div>
<div class="content-desc-item">
<div class="content-desc-title">签署总统:</div>
<div class="content-desc-content">唐纳德·约翰·特朗普(Donald John Trump)</div>
</div>
<div class="content-desc-item">
<div class="content-desc-title">证明编号:</div>
<div class="content-desc-content content-desc-content-long">第14320号行政命令 (EO 14320)</div>
</div>
<div class="content-desc-item">
<div class="content-desc-title">执行期限:</div>
<div class="content-desc-content content-desc-content-long">签署后90天内建立机制并开始实施</div>
</div>
</div>
</div>
</template>
</custom-container>
<custom-container title="主要指令" height="415px">
<!-- 中间内容自定义 -->
<template #default>
<div class="content-vertical-card content-vertical-card-flex-start">
<div class="content-box">
<div class="content-box-content" v-for="(item, index) in mainInstructions" :key="index">
<span class="content-num">{{ index + 1 }}</span>
<span class="content-desc">{{ item }}</span>
</div>
</div>
<div class="content-box-footer">
<div>共5条指令</div>
<el-pagination size="small" background layout="prev, pager, next" :total="10" page-size="5" />
</div>
</div>
</template>
</custom-container>
</el-col>
<el-col :span="8">
<custom-container title="执行机构" height="845px">
<!-- 中间内容自定义 -->
<template #default>
<div class="content-vertical-card content-vertical-card-flex-start">
<el-space>
<el-button plain type="primary">商务部</el-button>
<el-button>国务院</el-button>
<el-button>科技政策办公室</el-button>
<el-button>国防部</el-button>
</el-space>
<div
style="
display: flex;
justify-content: space-between;
margin-top: 10px;
padding-bottom: 10px;
gap: 5px;
border-bottom: 1px solid rgba(234, 236, 238, 1);
"
>
<el-image class="content-img-small" :src="DecreeOrg" fit="fill" />
<div class="content-desc">
<div class="content-desc-item">
<div class="content-desc-content">美国商务部</div>
<!-- <div class="content-desc-content">
Further Modifying Reciprocal Tariff Rates to Reflect Ongoing Discussions with the People’s Republic of China
</div> -->
</div>
<div class="content-desc-item">
<div class="content-desc-content-long">英文名:</div>
<div class="content-desc-content-long">United States Department of Commerce</div>
</div>
<div class="content-desc-item">
<div class="content-desc-content-long">成立时间:</div>
<div class="content-desc-content-long">1903年2月14日</div>
</div>
<div class="content-desc-item">
<div class="content-desc-content-long">主要职责:</div>
<div class="content-desc-content-long">国际贸易、进出口管制(R-TX-19)</div>
</div>
<div class="content-desc-item">
<div class="content-desc-content-long">总部地址:</div>
<div class="content-desc-content-long">华盛顿宪法大道1401号胡佛大楼</div>
</div>
<div class="content-desc-item">
<div class="content-desc-content-long">部长:</div>
<div class="content-desc-content content-desc-content-long">霍华德·卢特尼克</div>
</div>
<div class="content-desc-item">
<div class="content-desc-content-long">执行期限:</div>
<div class="content-desc-content content-desc-content-long">签署后90天内建立机制并开始实施</div>
</div>
</div>
</div>
<div class="content-time-line-box">
<div class="content-time-line-title">
<img class="time-line-img" src="@/assets/images/decree-date.png" alt="" />
<span class="time-line-title-text">机构动态</span>
</div>
<el-timeline style="max-width: 600px">
<el-timeline-item
placement="top"
v-for="(activity, index) in activities"
:key="index"
:icon="activity.icon"
:type="activity.type"
:color="activity.color"
:size="activity.size"
:hollow="activity.hollow"
:timestamp="activity.timestamp"
>
{{ activity.content }}
</el-timeline-item>
</el-timeline>
</div>
<div class="content-card-footer">
<el-button type="primary" link>
查看更多 <img class="icon-mark" src="@/assets/images/icon-double-down.png" alt="" />
</el-button>
</div>
</div>
</template>
<!-- 底部自定义内容 -->
<!-- <template #footer>
<el-button>取消</el-button>
<el-button type="primary">保存更改</el-button>
</template> -->
</custom-container>
</el-col>
</el-row>
</template>
<script setup>
import CustomContainer from "@/components/Container/index.vue";
import DecreeInfoImg from "@/assets/images/decree-info.png";
import DecreeOrg from "@/assets/images/decree-org.png";
// 主要指令数据
const mainInstructions = [
"获取美国产物项,以支持中国量子技术;",
"支持2023年2月飞越美国上空的高空气球;",
"获取美国原产的无人机物项供中国军方使用。",
"限制中国对美国商品的进口。",
"限制中国对美国商品的出口。"
];
// 机构动态
const activities = [
{
content: `推动《州责任联邦部署成本法案》,要求拒执行联邦移民法的州政府
支付相关军事部署费用,强化财政约束。`,
timestamp: "20258-07-31",
size: "large",
type: "primary",
hollow: true
},
{
content: `借OBBBA通过势头,在得州巩固军工、能源集团支持,为2026年连任
铺路,同时协调党内资源争夺关键摇摆选区。`,
timestamp: "2025-07-30",
type: "primary",
hollow: true
},
{
content: `众议院预算委员会主席乔迪·阿灵顿(得克萨斯州共和党人)周四上午在辩论时将此法案形容为“美国历史上最大的减税措施”。`,
timestamp: "2025-07-30",
type: "primary",
hollow: true
},
{
content: "特朗普力挺阿灵顿,白宫声明强调法案“美丽且必要”,双方矛盾凸显共和党内 商业资本与传统能源势力裂痕。",
timestamp: "2025-07-27",
type: "primary",
hollow: true
}
];
</script>
<style scoped>
.content-card {
display: flex;
align-items: flex-start;
gap: 20px;
}
.content-vertical-card {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
}
.content-vertical-card-flex-start {
align-items: flex-start;
}
.content-box {
width: 100%;
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 10px;
margin-bottom: 10px;
}
.content-box-content {
width: 95%;
display: flex;
justify-content: flex-start;
align-items: center;
gap: 10px;
border: 1px solid rgba(234, 236, 238, 1);
padding: 5px 10px;
height: 48px;
box-sizing: border-box;
}
.content-box-footer {
width: 95%;
display: flex;
justify-content: space-between;
align-items: center;
}
.content-num {
width: 24px;
height: 24px;
display: flex;
justify-content: center;
align-items: center;
font-size: 12px;
font-weight: 400;
border-radius: 50%;
background-color: rgba(231, 243, 255, 1);
color: var(--color-main-active);
}
.content-box-footer {
display: flex;
justify-content: space-between;
}
.renwu-card {
display: flex;
align-items: center;
gap: 20px;
width: 379px;
height: 148px;
background-color: rgba(234, 236, 238, 1);
padding-left: 10px;
}
.content-img {
width: 235px;
height: 332px;
flex-shrink: 0;
}
.content-img-small {
width: 140px;
height: 140px;
flex-shrink: 0;
}
.content-img-2 {
width: 128px;
height: 128px;
flex-shrink: 0;
}
.content-distribution-img {
width: 627px;
height: 536px;
}
.content-desc {
display: flex;
flex-direction: column;
gap: 8px;
}
.content-desc-item {
display: flex;
gap: 4px;
}
.content-desc-title {
width: 100px;
flex-shrink: 0;
font-size: 16px;
font-weight: 700;
color: rgba(59, 65, 75, 1);
}
.content-desc-content {
color: var(--color-main-active);
font-size: 16px;
font-weight: 700;
}
.content-desc-content-long {
color: rgba(95, 101, 108, 1);
font-weight: 400;
}
.time-line {
display: flex;
gap: 20px;
align-items: flex-start;
padding-left: 10px;
margin-bottom: 20px;
}
.time-line-title {
display: flex;
align-items: center;
gap: 8px;
flex-shrink: 0;
}
.time-line-dot {
width: 10px;
height: 10px;
}
.time-line-title-text {
font-size: 14px;
font-weight: 700;
color: rgba(95, 101, 108, 1);
color: var(--base-color);
}
.time-line-desc-title {
font-size: 16px;
font-weight: 400;
color: var(--base-color);
margin-bottom: 5px;
}
.time-line-desc-text {
font-size: 14px;
font-weight: 400;
color: rgba(95, 101, 108, 1);
}
.time-line-dot {
width: 8px;
height: 8px;
background-color: var(--color-main-active);
border-radius: 50%;
}
.content-time-line-box {
margin-bottom: 10px;
}
.content-time-line-title {
display: flex;
align-items: center;
gap: 8px;
padding-left: 20px;
padding-bottom: 5px;
margin-bottom: 10px;
}
.time-line-img {
width: 16px;
height: 16px;
}
.time-line-title-text {
font-size: 14px;
font-weight: 700;
color: rgba(95, 101, 108, 1);
}
.icon-mark {
height: 12px;
width: 12px;
margin-right: 5px;
margin-left: 8px;
}
.content-card-footer {
display: flex;
width: 100%;
justify-content: center;
/* margin-top: 30px; */
}
</style>
......@@ -116,7 +116,7 @@
<div class="home-main-center">
<div class="center-top">
<div class="box1">
<div class="box1-left">
<!-- <div class="box1-left">
<div class="icon">
<img src="./assets/images/box1-left.png" alt="" />
</div>
......@@ -125,7 +125,7 @@
<div class="icon">
<img src="./assets/images/box1-right.png" alt="" />
</div>
</div>
</div> -->
<div class="box1-header">
<div class="box1-header-left">
<div class="icon">
......@@ -137,48 +137,49 @@
{{ "查看详情 >" }}
</div>
</div>
<div class="box1-main">
<div class="box1-main-left">
<img src="./assets/images/img1.png" alt="" />
</div>
<div class="box1-main-right">
<div class="box1-main-right-title">
{{ "关于进一步延长TikTok执法宽限期的行政令" }}
</div>
<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
}"
v-for="(tag, index) in tagList"
:key="index"
>
{{ tag.name }}
<el-carousel ref="carouselRef" trigger="click" height="376px" :autoplay="true">
<el-carousel-item v-for="(item, index) in box1DataList" :key="index">
<div class="box1-main">
<div class="box1-main-left">
<img :src="item.imageUrl" alt="" />
</div>
</div>
<div class="box1-main-right-center">
{{
`9月16日,美国白宫官方网站发布总统政令,再次推迟(第四次)对TikTok禁令的执法,新的宽限期截止日为2025年12月16日​。在宽限期内及对于宽限期前的行为,司法部不得强制执行​《保护美国人免受外国对手控制应用程序法》或因此处罚相关实体​(如TikTok及其分发平台)。司法部还需向提供商发出无违规和无责任的信函,并强调执行该法的权力专属联邦司法部长,意在阻止各州或私人提起诉讼。
`
}}
</div>
<div class="box1-main-right-footer">
<div class="footer-left">{{ "2025年9月16日" }}</div>
<div class="footer-right">
<div class="footer-right-item1">
{{ "美国白宫官方网站" }}
<div class="box1-main-right">
<div class="box1-main-right-title">
{{ item.name }}
</div>
<div class="box1-main-right-info" v-if="item.industryList">
<div
class="tag"
:class="{
tag1: tag.status == 1,
tag2: tag.status == 2,
tag3: tag.status == 3,
tag4: tag.status == 4
}"
v-for="(tag, index) in item.industryList"
:key="index"
>
{{ tag.name }}
</div>
</div>
<div class="footer-right-item2">
<img src="./assets/images/open-icon.png" alt="" />
<div class="box1-main-right-center">
{{ item.describe }}
</div>
<div class="box1-main-right-footer">
<div class="footer-left">{{ item.postDate }}</div>
<div class="footer-right">
<div class="footer-right-item1">
{{ item.officialUrl }}
</div>
<div class="footer-right-item2">
<img src="./assets/images/open-icon.png" alt="" />
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</el-carousel-item>
</el-carousel>
</div>
<div class="box2">
<div class="box2-header">
......@@ -200,17 +201,17 @@
<div
class="item-left"
:class="{
itemLeftStatus1: item.status === '一般风险',
itemLeftStatus2: item.status === '重大风险'
itemLeftStatus3: item.riskLevel === '特别重大',
itemLeftStatus2: item.riskLevel === '重大风险'
}"
>
{{ item.status }}
{{ item.riskLevel ? item.riskLevel : "暂无数据" }}
</div>
<div class="item-right">
<div class="text">
{{ item.title }}
{{ item.name }}
</div>
<div class="time">{{ item.time }}</div>
<div class="time">{{ item.postDate }}</div>
</div>
</div>
</div>
......@@ -235,7 +236,7 @@
</div>
</div>
<div class="box3-main">
<div class="box3-item" v-for="(news, index) in newsList" :key="index">
<div class="box3-item" v-for="(news, index) in newsList" :key="index" @click="handleToNewsAnalysis()">
<div class="left">
<img :src="news.img" alt="" />
</div>
......@@ -258,7 +259,7 @@
</div>
<div class="box4-main">
<div class="box4-main-item" v-for="(item, index) in messageList" :key="index">
<div class="left">
<div class="left" @click="handleClickPerson()">
<img :src="item.img" alt="" />
</div>
<div class="right">
......@@ -274,43 +275,37 @@
</div>
<DivideHeader id="position3" class="divide3" :titleText="'数据总览'"></DivideHeader>
<div class="center-footer">
<div class="box3">
<div class="box3-header">
<div class="box3-header-left">
<div class="box3-header-icon">
<div class="box5">
<div class="box5-header">
<div class="box5-header-left">
<div class="box5-header-icon">
<img src="./assets/images/box3-header-icon.png" alt="" />
</div>
<div class="box3-header-title">{{ "行政令发布频度" }}</div>
</div>
<div class="box3-header-right">
<img src="./assets/images/header-more.png" alt="" />
<div class="box5-header-title">{{ "行政令发布频度" }}</div>
</div>
</div>
<div class="box3-main" id="chart1"></div>
<div class="box5-main" id="chart1"></div>
</div>
<div class="box4">
<div class="box4-header">
<div class="box6">
<div class="box6-header">
<div class="header-icon">
<img src="./assets/images/box4-header-icon.png" alt="" />
</div>
<div class="header-title">{{ "政令涉及领域" }}</div>
<div class="header-right">
<img src="./assets/images/header-more.png" alt="" />
</div>
</div>
<div class="box4-main" id="chart2"></div>
<div class="box6-main" id="chart2"></div>
</div>
</div>
<div class="center-footer1">
<div class="box5">
<div class="box5-header">
<div class="box7">
<div class="box7-header">
<div class="header-icon">
<img src="./assets/images/box5-header-icon.png" alt="" />
</div>
<div class="header-title">{{ "关键行政令" }}</div>
</div>
<div class="box5-main">
<div class="box5-item" v-for="(item, index) in keyDecreeList" :key="index">
<div class="box7-main">
<div class="box7-item" v-for="(item, index) in keyDecreeList" :key="index">
<div class="icon">
<img src="./assets/images/warning.png" alt="" />
</div>
......@@ -319,20 +314,20 @@
<div class="title">{{ item.title }}</div>
<div class="time">{{ item.time }}</div>
</div>
<div class="info-content">{{ item.content }}</div>
<div class="info-content">{{ item.content ? item.content : "暂无数据" }}</div>
</div>
</div>
</div>
</div>
<div class="box6">
<div class="box6-header">
<div class="box8">
<div class="box8-header">
<div class="header-icon">
<img src="./assets/images/box5-header-icon.png" alt="" />
</div>
<div class="header-title">{{ "政令重点条款" }}</div>
</div>
<div class="box6-main">
<WordCloudMap :data="wordCloudData" :shape="circle" />
<div class="box8-main" id="wordCloudChart">
<!-- <WordCloudMap :data="wordCloudData" :shape="circle" /> -->
</div>
</div>
</div>
......@@ -341,37 +336,30 @@
<DivideHeader id="position4" class="divide4" :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)"
>
{{ cate }}
<div class="btn-wrapper">
<div
class="btn"
:class="{ btnActive: activeCate === cate.id }"
v-for="(cate, index) in categoryList"
:key="index"
@click="handleClickCate(cate)"
>
{{ cate.name }}
</div>
</div>
</div>
<div class="select-box">
<el-select v-model="releaseTime" placeholder="选择发布时间" style="width: 120px">
<el-option
v-for="item in releaseTimeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<!-- <el-select
v-model="releaseTime"
placeholder="选择发布时间"
style="width: 120px"
>
<el-option
v-for="item in releaseTimeList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select> -->
<div class="paixu-btn" @click="handleSwithSort">
<div class="icon1">
<img v-if="isSort" src="@/assets/icons/shengxu1.png" alt="" />
<img v-else src="@/assets/icons/jiangxu1.png" alt="" />
</div>
<div class="text">{{ "发布时间" }}</div>
<div class="icon2">
<img v-if="isSort" src="@/assets/icons/shengxu2.png" alt="" />
<img v-else src="@/assets/icons/jiangxu2.png" alt="" />
</div>
</div>
</div>
</div>
<div class="home-main-footer-main">
......@@ -407,7 +395,7 @@
:key="area.id"
v-model="activeAreaList"
:label="area.id"
class="filter-checkbox"
style="width: 100px"
>
{{ area.name }}
</el-checkbox>
......@@ -422,7 +410,7 @@
</div>
<div class="title">{{ "政令库" }}</div>
</div>
<div class="content-box">
<div class="content-box" v-show="curDecreeList">
<div
class="main-item"
v-for="(item, index) in curDecreeList"
......@@ -433,13 +421,13 @@
<div class="left-left">{{ item.time }}</div>
<div class="left-right">
<div class="icon"></div>
<div class="line"></div>
<div class="line" v-if="index !== 9 && index !== totalDecreesNum - 1"></div>
</div>
</div>
<div class="main-item-center">
<div class="center-header">
<div class="title">{{ item.title }}</div>
<div
<!-- <div
class="type-box"
:class="{
type1: item.status === 1,
......@@ -448,40 +436,20 @@
}"
>
{{ item.type }}
</div>
</div> -->
</div>
<div class="desc">{{ item.desc }}</div>
<div class="tag-box">
<div class="tag" v-for="(val, idx) in item.tagList" :key="idx">{{ val }}</div>
</div>
</div>
<!-- <div class="main-item-left">
<div
class="left-box"
:class="{
type1: decree.status === 1,
type2: decree.status === 2,
type3: decree.status === 3
}"
>
{{ decree.type }}
<div class="tag" v-for="(val, idx) in item.tagList" :key="idx">
{{ val.industryName }}
</div>
</div>
</div>
<div class="main-item-center">
<div class="main-item-center-box1">{{ decree.title }}</div>
<div class="main-item-center-box2">{{ decree.time }}</div>
</div>
<div class="main-item-right">
<div class="main-item-right-text">{{ "查看官网政令原文" }}</div>
<div class="main-item-right-icon">
<img src="./assets/images/open-icon.png" alt="" />
</div>
</div> -->
</div>
</div>
<div class="footer-box">
<div class="footer-left">
{{ `共${decreeList.length}项调查` }}
{{ `共${totalDecreesNum}项调查` }}
</div>
<div class="footer-right">
<el-pagination
......@@ -490,7 +458,7 @@
:current-page="currentPage"
background
layout="prev, pager, next"
:total="decreeList.length"
:total="totalDecreesNum"
/>
</div>
</div>
......@@ -502,15 +470,28 @@
</template>
<script setup>
import { onMounted, ref, computed } from "vue";
import { onMounted, ref, computed, watch } from "vue";
import * as echarts from "echarts";
import router from "@/router";
import {
getDepartmentList,
getLatestDecree,
getDecreeRiskSignal,
getDecreeYearOrder,
getDecreeArea,
getKeyDecree,
getDecreeKeyInstruction,
getDecreeOrderList,
getDecreehylyList
} from "@/api/decree/home";
import { getNews, getSocialMedia } from "@/api/general/index";
import WordCloudMap from "./WordCloudMap.vue";
import DivideHeader from "@/components/DivideHeader.vue";
import { useContainerScroll } from "@/hooks/useScrollShow";
import getMultiLineChart from "./utils/multiLineChart";
import getBarChart from "./utils/barChart";
import getPieChart from "./utils/piechart";
import getWordCloudChart from "./utils/wordCloudChart";
import getCalendarHeatChart from "./utils/cleandarHeat";
import setChart from "@/utils/setChart";
......@@ -614,24 +595,24 @@ const govInsList = ref([
name: "美国国立卫生研究院 (NIH)"
}
]);
// 最新科技政令
const tagList = ref([
{
name: "互联网",
status: 2
},
{
name: "人工智能",
status: 4
const handleGetDepartmentList = async () => {
try {
const res = await getDepartmentList();
console.log("机构列表", res);
if (res.code === 200 && res.data) {
govInsList.value = res.data.map(item => {
return {
id: item.orgId,
name: item.orgName,
img: item.orgImage
};
});
}
} catch (error) {
console.error("获取机构列表error", error);
}
]);
// 点击查看详情
const handleClickToDetail = () => {
// router.push("/decreeLayout");
const route = router.resolve("/decreeLayout");
window.open(route.href, "_blank");
};
handleGetDepartmentList();
// 查看更多风险信号
const handleToMoreRiskSignal = () => {
......@@ -645,34 +626,98 @@ const handleToMoreNews = () => {
window.open(route.href, "_blank");
};
// 最新科技政令
const box1DataList = ref([
{
id: 89,
name: "",
postDate: "",
describe: null,
imageUrl: null,
officialUrl: null,
industryList: null
}
]);
// const curBox1Data = ref({
// id: 89,
// name: "",
// postDate: "",
// describe: null,
// imageUrl: null,
// officialUrl: null,
// industryList: null
// });
const handleGetLatestDecree = async () => {
try {
const res = await getLatestDecree();
console.log("最新科技政令", res);
if (res.code === 200 && res.data) {
box1DataList.value = res.data;
}
} catch (error) {
console.error("最新科技政令error", error);
}
};
const handleBox1 = async () => {
await handleGetLatestDecree();
};
const carouselRef = ref(null);
// 点击查看详情
const handleClickToDetail = () => {
let activeIndex = 0;
if (carouselRef.value) {
activeIndex = carouselRef.value.activeIndex;
}
console.log("当前 Carousel 激活索引:", activeIndex);
const id = box1DataList.value[activeIndex].id
const route = router.resolve({
path: "/decreeLayout",
query: {
id: id
}
});
window.open(route.href, "_blank");
};
// 风险信号
const warningList = ref([
{
title: "关于对中华人民共和国合成阿片类药物供应链...",
time: "一天前",
status: "特别重大"
},
{
title: "关于调整汽车及汽车零部件进口的公告",
time: "一天前",
status: "特别重大"
},
{
title: "关于调整钢铁进口的公告",
time: "一天前",
status: "重大风险"
id: 1,
name: "关于对中华人民共和国合成阿片类药物供应链...",
postDate: "一天前",
riskLevel: "特别重大"
},
{
title: "关于使用互惠关税规范进口以纠正导致大规模...",
time: "一天前",
status: "重大风险"
id: 2,
name: "关于调整钢铁进口的公告",
postDate: "一天前",
riskLevel: "重大风险"
},
{
title: "关于修订对中华人民共和国低价值进口商品适...",
time: "一天前",
status: "一般风险"
id: 3,
name: "关于修订对中华人民共和国低价值进口商品适...",
postDate: "一天前",
riskLevel: "一般风险"
}
]);
const handlegetDecreeRiskSignal = async () => {
try {
const res = await getDecreeRiskSignal();
console.log("风险信号", res);
if (res.code === 200 && res.data) {
warningList.value = res.data;
}
} catch (error) {
console.error("风险信号error", error);
}
};
handlegetDecreeRiskSignal();
// 新闻资讯
const newsList = ref([
......@@ -707,6 +752,33 @@ const newsList = ref([
from: "11-2 · ​福克斯新闻网"
}
]);
const handleGetNews = async () => {
const params = {
moduleId: "0100"
};
try {
const res = await getNews(params);
console.log("新闻资讯", res);
if (res.code === 200 && res.data) {
newsList.value = res.data.map(item => {
return {
img: item.newsImage,
title: item.newsTitle,
content: item.newsContent,
from: item.newsDate + " · " + item.newsOrg
};
});
}
} catch (error) {
console.error("新闻资讯error", error);
}
};
handleGetNews();
// 点击新闻条目,跳转到新闻分析页
const handleToNewsAnalysis = () => {
const route = router.resolve("/newsAnalysis");
window.open(route.href, "_blank");
};
// 社交媒体
const messageList = ref([
......@@ -729,13 +801,68 @@ const messageList = ref([
content: `提出特朗普政府的AI政策强调技术开放与快速应用,但可能以牺牲安全防范为代价,开启了“潘多拉魔盒”。`
}
]);
const handleGetMessage = async () => {
const params = {
moduleId: "0100"
};
try {
const res = await getSocialMedia(params);
console.log("社交媒体", res);
messageList.value = res.data.map(item => {
return {
img: item.personImage,
name: item.personName,
time: item.time + " · 发布于" + item.orgName,
content: item.remarks
};
});
} catch (error) {}
};
handleGetMessage();
// 点击人物头像,跳转到人物主页
const handleClickPerson = () => {
const route = router.resolve({
path: "/characterPage",
query: {
type: 1 // 1 2 3
}
});
window.open(route.href, "_blank");
};
// 政令发布频度
// 政令发布频度
const chart1Data = ref({
dataX: ["2019", "2020", "2021", "2022", "2023", "2024", "2025"],
dataY: [219, 228, 129, 159, 152, 157, 78]
});
const handleGetDecreeYearOrder = async () => {
try {
const res = await getDecreeYearOrder();
console.log("行政令发布频度", res);
if (res.code === 200 && res.data) {
chart1Data.value.dataX = res.data
.map(item => {
return item.year;
})
.reverse();
chart1Data.value.dataY = res.data
.map(item => {
return item.count;
})
.reverse();
}
} catch (error) {
console.error("行政令发布频度error", error);
}
};
const handleBox5 = async () => {
await handleGetDecreeYearOrder();
let chart1 = getBarChart(chart1Data.value.dataX, chart1Data.value.dataY);
setChart(chart1, "chart1");
};
// 政令涉及领域
const chart2Data = ref([
{
......@@ -767,7 +894,29 @@ const chart2Data = ref([
value: 24
}
]);
const colorList = ["#69B1FF", "#FFC069", "#87E8DE", "#85A5FF", "#FF7875", "#B37FEB", "#4096FF"];
// const colorList = ["#69B1FF", "#FFC069", "#87E8DE", "#85A5FF", "#FF7875", "#B37FEB", "#4096FF"];
const handleGetDecreeArea = async () => {
try {
const res = await getDecreeArea();
console.log("政令涉及领域", res);
if (res.code === 200 && res.data) {
chart2Data.value = res.data.map(item => {
return {
name: item.industry,
value: item.count
};
});
}
} catch (error) {
console.error("政令涉及领域error", error);
}
};
const handleBox6 = async () => {
await handleGetDecreeArea();
let chart2 = getPieChart(chart2Data.value);
setChart(chart2, "chart2");
};
// 关键行政令
const keyDecreeList = ref([
......@@ -793,198 +942,87 @@ const keyDecreeList = ref([
}
]);
const handleGetKeyDecree = async () => {
try {
const res = await getKeyDecree();
console.log("关键行政令", res);
if (res.code === 200 && res.data) {
keyDecreeList.value = res.data.map(item => {
return {
title: item.name,
content: item.describe,
time: item.postDate
};
});
}
} catch (error) {}
};
handleGetKeyDecree();
// 政令重点条款
const wordCloudData = [
{ name: "与马斯克公开冲突", value: 100 },
{ name: "传统能源", value: 5 },
{ name: "共和党财政鹰派", value: 77 },
{ name: "未实现赤字控制目标", value: 35 },
{ name: "得克萨斯州", value: 88 },
{ 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 }
// { name: "与马斯克公开冲突", value: 100 },
// { name: "传统能源", value: 5 },
// { name: "共和党财政鹰派", value: 77 },
// { name: "未实现赤字控制目标", value: 35 },
// { name: "得克萨斯州", value: 88 },
// { 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 decreeList = ref([
{
type: "总统政令",
status: 1,
title: "关于进一步延长TikTok执法宽限期的行政令",
time: "2025年9月16日",
img: 1,
desc: "123",
tagList: ["生物科技"]
},
{
type: "总统政令",
status: 1,
title: "为国家安全部署先进核反应堆技术",
time: "2025年9月16日",
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: ["生物科技"]
const handleGetDecreeKeyInstruction = async () => {
try {
const res = await getDecreeKeyInstruction();
console.log("政令重点条款", res);
wordCloudData.value = res.data.map(item => {
return {
name: item.clause,
value: item.count
};
});
} catch (error) {
console.error("政令重点条款error", error);
}
]);
const curDecreeList = computed(() => {
const startIndex = (currentPage.value - 1) * pageSize.value;
const endIndex = startIndex + pageSize.value;
return decreeList.value.slice(startIndex, endIndex);
};
const handleBox8 = async () => {
await handleGetDecreeKeyInstruction();
let chart3 = getWordCloudChart(wordCloudData.value);
setChart(chart3, "wordCloudChart");
};
// 资源库
const isSort = ref(true); // true 升序 false 倒序
const handleSwithSort = () => {
isSort.value = !isSort.value;
};
const categoryList = computed(() => {
let obj = {
name: "全部分类",
id: "",
img: ""
};
return [obj, ...govInsList.value];
});
const releaseTime = ref("近一年发布");
const releaseTimeList = ref([
{
label: "近半年发布",
value: "近半年发布"
},
{
label: "近一年发布",
value: "近一年发布"
},
{
label: "近两年发布",
value: "近两年发布"
},
{
label: "近三年发布",
value: "近三年发布"
},
{
label: "近五年发布",
value: "近五年发布"
}
]);
const categoryList = ref(["全部分类", "白宫", "能源部", "商务部", "战争部", "FCC", "FDA", "NASA", "NSF", "NIH"]);
const activeCate = ref("全部分类");
const activeCate = ref("白宫");
const handleClickCate = cate => {
activeCate.value = cate;
activeCate.value = cate.id;
};
const calendarData = ref([
["2025-01-01", 20],
["2025-01-05", 120],
["2025-01-09", 220],
["2025-01-15", 320],
["2025-01-20", 120],
["2025-01-24", 420],
["2025-02-05", 80],
["2025-02-08", 280],
["2025-02-18", 480],
["2025-02-11", 420],
["2025-02-21", 320],
["2025-03-05", 160],
["2025-03-09", 260],
["2025-03-19", 460],
["2025-03-26", 430],
["2025-04-01", 70],
["2025-04-05", 170],
["2025-04-11", 270],
["2025-04-18", 370],
["2025-05-05", 210],
["2025-05-09", 210],
["2025-05-15", 410],
["2025-05-22", 480],
["2025-06-06", 45],
["2025-06-09", 415],
["2025-06-16", 245],
["2025-06-19", 332],
["2025-07-04", 127],
["2025-07-09", 327],
["2025-07-24", 427],
["2025-08-08", 150],
["2025-08-11", 250],
["2025-08-15", 350],
["2025-08-22", 460],
["2025-09-10", 480],
["2025-09-18", 312],
["2025-10-15", 60],
["2025-10-19", 80],
["2025-10-21", 190]
]);
const handleToPosi = id => {
// 0 618 1240 2350
switch (id) {
......@@ -1003,33 +1041,215 @@ const handleToPosi = id => {
}
};
const areaList = [
{ id: "人工智能", name: "人工智能" },
{ id: "集成电路", name: "集成电路" },
{ id: "通信网络", name: "通信网络" },
{ id: "量子科技", name: "量子科技" }
];
const activeAreaList = ["人工智能"];
const areaList = ref([
// { id: "人工智能", name: "人工智能" },
// { id: "集成电路", name: "集成电路" },
// { id: "通信网络", name: "通信网络" },
// { id: "量子科技", name: "量子科技" }
]);
const activeAreaList = ref(["1"]);
const handleGetAreaList = async () => {
try {
const res = await getDecreehylyList();
console.log("行业领域列表", res);
if (res.code === 200 && res.data) {
areaList.value = res.data.map(item => {
return {
name: item.name,
id: item.id
};
});
console.log("areaList", areaList.value);
}
} catch (error) {}
};
const pubTime = ref([
{ id: "2025", name: "2025年" },
{ id: "2024", name: "2024年" },
{ id: "2023", name: "2023年" },
{ id: "2022", name: "2022年" },
{ id: "2021", name: "2021年" },
{ id: "2025", name: "2025年" },
{ id: "2024", name: "2024年" },
{ id: "2023", name: "2023年" },
{ id: "2022", name: "2022年" },
{ id: "2021", name: "2021年" },
{ id: "更早时间", name: "更早时间" }
]);
const activePubTime = ref(["2025年"]);
const activePubTime = ref(["2025"]);
const totalDecreesNum = ref(0);
const decreeList = ref([
// {
// type: "总统政令",
// status: 1,
// title: "关于进一步延长TikTok执法宽限期的行政令",
// time: "2025年9月16日",
// img: 1,
// desc: "123",
// tagList: ["生物科技"]
// },
// {
// type: "总统政令",
// status: 1,
// title: "为国家安全部署先进核反应堆技术",
// time: "2025年9月16日",
// 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: ["生物科技"]
// }
]);
const handleGetDecreeOrderList = async () => {
const p1 = activeAreaList.value.join(",");
const p2 = activePubTime.value.join(",");
const params = {
currentPage: 0,
pageSize: 999999,
proposeName: activeCate.value,
researchTypeIds: p1,
sortFun: isSort.value,
years: p2
};
try {
const res = await getDecreeOrderList(params);
console.log("资源库列表", res.data.content);
if (res.code === 200 && res.data) {
totalDecreesNum.value = res.data.totalElements;
decreeList.value = res.data.content.map(item => {
return {
id: item.id,
time: item.postDate,
title: item.name,
desc: item.order,
img: item.orgImage,
tagList: item.industryList
};
});
console.log("decreeList", decreeList.value);
} else {
decreeList.value = [];
}
} catch (error) {
console.error('资源库列表error', error);
decreeList.value = [];
}
};
const curDecreeList = computed(() => {
const startIndex = (currentPage.value - 1) * pageSize.value;
const endIndex = startIndex + pageSize.value;
return decreeList.value.slice(startIndex, endIndex);
});
watch(
() => activePubTime.value,
val => {
handleGetDecreeOrderList();
}
);
watch(
() => activeAreaList.value,
val => {
handleGetDecreeOrderList();
}
);
watch(
() => activeCate.value,
val => {
handleGetDecreeOrderList();
}
);
watch(
() => isSort.value,
val => {
handleGetDecreeOrderList();
}
);
onMounted(async () => {
let chart1 = getBarChart(chart1Data.value.dataX, chart1Data.value.dataY);
setChart(chart1, "chart1");
handleGetAreaList();
handleGetDecreeOrderList();
handleBox1(); // 最新科技政令
let chart2 = getPieChart(chart2Data.value, colorList);
setChart(chart2, "chart2");
handleBox5();
let chartCalendar = getCalendarHeatChart(calendarData.value);
setChart(chartCalendar, "chartCalendar");
handleBox6();
handleBox8();
});
</script>
......@@ -1441,6 +1661,7 @@ onMounted(async () => {
}
.box1-main {
display: flex;
width: 1064px;
height: 354px;
margin-top: 22px;
padding-left: 31px;
......@@ -1602,9 +1823,9 @@ onMounted(async () => {
&:hover {
background: var(--color-bg-hover);
}
.itemLeftStatus1 {
color: rgba(82, 196, 26, 1) !important;
background: rgba(246, 255, 237, 1) !important;
.itemLeftStatus3 {
color: rgba(245, 34, 45, 1) !important;
background: rgba(255, 241, 240) !important;
}
.itemLeftStatus2 {
color: rgba(250, 140, 22, 1) !important;
......@@ -1616,8 +1837,8 @@ onMounted(async () => {
width: 40px;
height: 40px;
border-radius: 20px;
background: rgba(255, 241, 240);
color: rgba(245, 34, 45, 1);
color: rgba(82, 196, 26, 1);
background: rgba(246, 255, 237, 1);
font-family: Microsoft YaHei;
font-size: 12px;
font-weight: 400;
......@@ -1633,16 +1854,20 @@ onMounted(async () => {
border-bottom: 1px solid rgba(240, 242, 244, 1);
display: flex;
.text {
width: 348px;
width: 318px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 47px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.time {
margin-left: 10px;
width: 90px;
line-height: 47px;
text-align: center;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 14px;
......@@ -1756,6 +1981,10 @@ onMounted(async () => {
width: 749px;
margin-left: 21px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
cursor: pointer;
&:hover {
background: var(--color-bg-hover);
}
.left {
width: 72px;
height: 48px;
......@@ -1774,7 +2003,7 @@ onMounted(async () => {
justify-content: space-between;
.title {
margin-top: 13px;
width: 520px;
width: 500px;
height: 24px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
......@@ -1786,7 +2015,7 @@ onMounted(async () => {
white-space: nowrap;
}
.time {
flex: 1;
width: 157px;
text-align: right;
height: 22px;
margin-top: 19px;
......@@ -1795,6 +2024,9 @@ onMounted(async () => {
font-size: 14px;
font-weight: 400;
line-height: 22px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.right-footer {
......@@ -1861,6 +2093,9 @@ onMounted(async () => {
margin-top: 5px;
width: 36px;
height: 36px;
border-radius: 18px;
overflow: hidden;
cursor: pointer;
img {
width: 100%;
height: 100%;
......@@ -1869,6 +2104,7 @@ onMounted(async () => {
.right {
margin-left: 10px;
width: 690px;
border-radius: 4px;
box-sizing: border-box;
border: 1px solid rgba(231, 243, 255, 1);
background: rgba(246, 250, 255, 1);
......@@ -2341,21 +2577,21 @@ onMounted(async () => {
height: 452px;
display: flex;
justify-content: center;
.box3 {
.box5 {
width: 792px;
height: 452px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: rgba(255, 255, 255, 1);
border-radius: 10px;
.box3-header {
.box5-header {
height: 48px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
margin: 0 auto;
display: flex;
justify-content: space-between;
.box3-header-left {
.box5-header-left {
display: flex;
.box3-header-icon {
.box5-header-icon {
margin-top: 17px;
margin-left: 24px;
width: 17px;
......@@ -2365,7 +2601,7 @@ onMounted(async () => {
height: 100%;
}
}
.box3-header-title {
.box5-header-title {
margin-top: 11px;
margin-left: 19px;
height: 26px;
......@@ -2376,7 +2612,7 @@ onMounted(async () => {
line-height: 26px;
}
}
.box3-header-right {
.box5-header-right {
width: 49px;
height: 24px;
margin-top: 12px;
......@@ -2388,18 +2624,18 @@ onMounted(async () => {
}
}
}
.box3-main {
.box5-main {
height: 397px;
}
}
.box4 {
.box6 {
margin-left: 16px;
width: 792px;
height: 452px;
box-shadow: 0px 0px 15px 0px rgba(22, 119, 255, 0.1);
background: rgba(255, 255, 255, 1);
border-radius: 10px;
.box4-header {
.box6-header {
margin: 0 auto;
height: 53px;
border-bottom: 1px solid rgba(240, 242, 244, 1);
......@@ -2438,7 +2674,7 @@ onMounted(async () => {
}
}
}
.box4-main {
.box6-main {
margin-top: 8px;
height: 390px;
}
......@@ -2449,13 +2685,13 @@ onMounted(async () => {
height: 450px;
display: flex;
justify-content: center;
.box5 {
.box7 {
width: 792px;
height: 450px;
border-radius: 4px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
background: rgba(255, 255, 255, 1);
.box5-header {
.box7-header {
width: 792px;
height: 48px;
display: flex;
......@@ -2481,10 +2717,12 @@ onMounted(async () => {
line-height: 26px;
}
}
.box5-main {
.box7-main {
height: 400px;
box-sizing: border-box;
.box5-item {
overflow-y: auto;
overflow-x: hidden;
.box7-item {
width: 730px;
margin-top: 16px;
margin-left: 25px;
......@@ -2502,46 +2740,58 @@ onMounted(async () => {
margin-left: 13px;
width: 100%;
.info-header {
height: 24px;
display: flex;
margin-top: 4px;
justify-content: space-between;
.title {
width: 600px;
height: 24px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 18px;
font-weight: 700;
line-height: 24px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.time {
width: 91px;
height: 24px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.info-content {
min-height: 24px;
max-height: 48px;
margin-top: 6px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
overflow: hidden;
}
}
}
}
}
.box6 {
.box8 {
margin-left: 16px;
width: 792px;
height: 450px;
border-radius: 4px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
background: rgba(255, 255, 255, 1);
.box6-header {
.box8-header {
width: 792px;
height: 48px;
display: flex;
......@@ -2567,7 +2817,7 @@ onMounted(async () => {
line-height: 26px;
}
}
.box6-main {
.box8-main {
height: 401px;
}
}
......@@ -2585,46 +2835,98 @@ onMounted(async () => {
}
.home-main-footer-header {
width: 1600px;
height: 42px;
margin: 36px auto;
height: 70px;
margin: 36px auto 16px;
// background: orange;
display: flex;
justify-content: space-between;
.btn-box {
margin-top: 10px;
width: 1200px;
display: flex;
.btn {
height: 42px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 400;
line-height: 42px;
padding: 0 24px;
border-radius: 21px;
background: rgba(20, 89, 187, 0);
margin-right: 20px;
cursor: pointer;
&:hover {
background: rgba(20, 89, 187, 0.1);
width: 1450px;
overflow-x: auto;
overflow-y: hidden;
.btn-wrapper {
width: 1880px;
display: flex;
gap: 10px;
overflow-x: auto;
overflow-y: hidden;
.btn {
height: 42px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 400;
line-height: 42px;
padding: 0 24px;
border-radius: 21px;
background: rgba(20, 89, 187, 0);
cursor: pointer;
&:hover {
background: rgba(20, 89, 187, 0.1);
}
}
}
.btnActive {
font-weight: 700;
background: rgba(20, 89, 187, 1);
color: #fff;
&:hover {
color: #fff;
.btnActive {
font-weight: 700;
background: rgba(20, 89, 187, 1);
color: #fff;
&:hover {
color: #fff;
background: rgba(20, 89, 187, 1);
}
}
}
}
.select-box {
margin-top: 10px;
margin-top: 5px;
height: 42px;
box-sizing: border-box;
padding: 5px 0;
.paixu-btn {
display: flex;
width: 120px;
height: 32px;
box-sizing: border-box;
border: 1px solid rgba(230, 231, 232, 1);
border-radius: 4px;
background: rgba(255, 255, 255, 1);
&:hover {
background: var(--color-bg-hover);
}
cursor: pointer;
.icon1 {
width: 11px;
height: 14px;
margin-top: 10px;
margin-left: 9px;
img {
width: 100%;
height: 100%;
}
}
.text {
height: 19px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 18px;
letter-spacing: 0px;
text-align: left;
margin-top: 7px;
margin-left: 9px;
}
.icon2 {
width: 10px;
height: 5px;
margin-top: 5px;
margin-left: 13px;
img {
width: 100%;
height: 100%;
}
}
}
}
}
.home-main-footer-main {
......@@ -2634,7 +2936,7 @@ onMounted(async () => {
gap: 16px;
.left {
width: 300px;
height: 443px;
height: 666px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
background: rgba(255, 255, 255, 1);
box-sizing: border-box;
......@@ -2666,7 +2968,7 @@ onMounted(async () => {
margin-left: 25px;
}
.select-main1 {
width: 100px;
width: 260px;
}
}
}
......@@ -2800,6 +3102,7 @@ onMounted(async () => {
.tag-box {
margin-top: 9px;
display: flex;
gap: 8px;
.tag {
height: 28px;
line-height: 28px;
......
const getPieChart = (data,colorList) => {
const getPieChart = (data) => {
let option = {
color: colorList,
series: [
{
type: 'pie',
......
const getWordCloudChart = (data) => {
const option = {
grid: {
left: 5,
top: 5,
right: 5,
bottom: 5,
},
series: [
{
type: "wordCloud",
shape: 'circle',
width: '100%',
height: '100%',
// 其他形状你可以使用形状路径
// shape: 'circle', // 示例
// 或者自定义路径
gridSize: 30, // 网格大小,影响词间距。
sizeRange: [15, 40], // 定义词云中文字大小的范围
rotationRange: [0, 0],
rotationStep: 0,
drawOutOfBound: false, // 是否超出画布
shrinkToFit: true, // 是否自动缩小以适应容器
// 字体
textStyle: {
// normal: {
// color: function () {
// return 'rgb(' + [
// Math.round(Math.random() * 160),
// Math.round(Math.random() * 160),
// Math.round(Math.random() * 160)
// ].join(',') + ')';
// }
// },
color: function () {
let colors = [
"rgba(189, 33, 33, 1)",
"rgba(232, 151, 21, 1)",
"rgba(220, 190, 68, 1)",
"rgba(96, 58, 186, 1)",
"rgba(32, 121, 69, 1)",
"rgba(22, 119, 255, 1)",
];
return colors[parseInt(Math.random() * colors.length)];
},
emphasis: {
shadowBlur: 5,
shadowColor: "#333",
},
},
// 设置词云数据
data: data,
},
],
};
return option
}
export default getWordCloudChart
\ No newline at end of file
......@@ -39,7 +39,7 @@
<div class="item-right-text">
{{ decreeInfo.totalTitle }}
</div>
<div class="item-right-icon">
<div class="item-right-icon" v-if="decreeInfo.totalTitle">
<img src="./assets/icons/open-icon.png" alt="" />
</div>
</div>
......@@ -57,9 +57,9 @@
</div>
</div>
<div class="info-item">
<div class="item-left">{{ "签署总统:" }}</div>
<div class="item-left">{{ "发布机构:" }}</div>
<div class="item-right">
{{ decreeInfo.signPerson }}
{{ decreeInfo.signOrg }}
</div>
</div>
</div>
......@@ -72,9 +72,9 @@
<div class="title">{{ "政令主要内容" }}</div>
</div>
<div class="list-main">
<div class="list-item" v-for="(val, idx) in decreeInfo.list" :key="idx">
<div class="list-item" v-for="(val, idx) in showList" :key="idx">
<div class="id">{{ idx + 1 }}</div>
<div class="title">{{ val.title }}</div>
<div class="title">{{ val.content }}</div>
<div class="open">
<img src="./assets/icons/open-icon.png" alt="" />
</div>
......@@ -103,12 +103,30 @@
</template>
<script setup>
import { ref, onMounted } from "vue";
import { ref, computed, onMounted } from "vue";
import { useRoute } from "vue-router";
import { getDecreeMainContent } from "@/api/decree/introduction";
import { getDecreeRelateOrder } from "@/api/decree/deepdig";
import box2InfoImg from "./assets/icons/box1-info.png";
const allData = ref([]);
const relateId = ref(0);
const route = useRoute();
const pageSize = ref(10);
const currentPage = ref(1);
// 处理页码改变事件
const handleCurrentChange = page => {
currentPage.value = page;
};
const showList = computed(() => {
const startIndex = (currentPage.value - 1) * pageSize.value;
const endIndex = startIndex + pageSize.value;
return decreeInfo.value.list.slice(startIndex, endIndex);
});
const siderList = ref([
{
......@@ -133,51 +151,112 @@ const siderList = ref([
}
]);
const siderActiveIndex = ref(0);
const handleClickSider = index => {
siderActiveIndex.value = index
}
const handleClickSider = async index => {
siderActiveIndex.value = index;
decreeInfo.value.img = allData.value[index].imageUrl;
decreeInfo.value.totalTitle = allData.value[index].name;
decreeInfo.value.eTotalTitle = allData.value[index].ename;
decreeInfo.value.signTime = allData.value[index].postDate;
decreeInfo.value.signOrg = allData.value[index].proposeOrgName;
relateId.value = allData.value[index].id;
const params1 = {
currentPage: 0,
pageSize: 999999,
id: relateId.value
};
try {
const res = await getDecreeMainContent(params1);
console.log("政令主要内容", res);
if (res.code === 200 && res.data) {
decreeInfo.value.list = res.data.content;
} else {
decreeInfo.value.list = [];
}
} catch (error) {}
};
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日",
signPerson: "乔·拜登(Joe Biden)",
signOrg: "乔·拜登(Joe Biden)",
list: [
{
title: "要求强大AI系统开发者与政府分享安全测试结果(“红队测试”);制定生物合成筛查标准防范风险;建立AI生成内容鉴别标准"
},
{
title: "优先支持隐私保护技术(PET)研发;评估各机构如何收集和使用商业信息;制定评估隐私保护技术有效性的指南。"
},
{
title: "为解决算法歧视提供明确指导;确保刑事司法系统中AI使用的公平性;协调调查和起诉AI相关的民权侵犯行为。"
},
{
title: "推动医疗保健领域负责任地使用AI;创造资源支持教育工作者部署AI教育工具。"
},
{
title: "制定减轻AI对工人潜在危害的原则和最佳实践;编写AI对劳动力市场潜在影响的报告。"
},
{
title: "通过“国家AI研究资源”(NAIRR)试点促进研究;为小型开发者和企业家提供技术援助和资源;简化相关领域高技能人才的签证流程。"
},
{
title: "扩大在AI领域的国际合作;与国际伙伴和标准组织加速制定AI标准。"
},
{
title: "发布政府机构使用AI的指南;加快招聘AI专业人才并为相关领域员工提供培训。"
content:
"要求强大AI系统开发者与政府分享安全测试结果(“红队测试”);制定生物合成筛查标准防范风险;建立AI生成内容鉴别标准"
},
{
title: "发布政府机构使用AI的指南;加快招聘AI专业人才并为相关领域员工提供培训。"
content: "优先支持隐私保护技术(PET)研发;评估各机构如何收集和使用商业信息;制定评估隐私保护技术有效性的指南。"
},
{
title: "发布政府机构使用AI的指南;加快招聘AI专业人才并为相关领域员工提供培训。"
content: "为解决算法歧视提供明确指导;确保刑事司法系统中AI使用的公平性;协调调查和起诉AI相关的民权侵犯行为。"
}
]
});
const handleGetRelateOrder = async () => {
const params = {
id: route.query.id
};
try {
const res = await getDecreeRelateOrder(params);
console.log("相关政令关联分析", res);
if (res.code === 200 && res.data) {
allData.value = res.data;
siderList.value = res.data.map(item => {
return {
time: item.year,
title: item.name
};
});
decreeInfo.value.img = allData.value[0].imageUrl;
decreeInfo.value.totalTitle = allData.value[0].name;
decreeInfo.value.eTotalTitle = allData.value[0].ename;
decreeInfo.value.signTime = allData.value[0].postDate;
decreeInfo.value.signOrg = allData.value[0].proposeOrgName;
relateId.value = allData.value[0].id;
const params1 = {
currentPage: 0,
pageSize: 999999,
id: relateId.value
};
try {
const res = await getDecreeMainContent(params1);
console.log("政令主要内容", res);
if (res.code === 200 && res.data) {
decreeInfo.value.list = res.data.content;
} else {
decreeInfo.value.list = [];
}
} catch (error) {}
} else {
allData.value = [];
siderList.value = [];
decreeInfo.value.img = "";
decreeInfo.value.totalTitle = "";
decreeInfo.value.eTotalTitle = "";
decreeInfo.value.signTime = "";
decreeInfo.value.signOrg = "";
decreeInfo.value.list = [];
}
} catch (error) {
allData.value = [];
siderList.value = [];
decreeInfo.value.img = "";
decreeInfo.value.totalTitle = "";
decreeInfo.value.eTotalTitle = "";
decreeInfo.value.signTime = "";
decreeInfo.value.signOrg = "";
decreeInfo.value.list = [];
}
};
onMounted(() => {
handleGetRelateOrder();
});
</script>
<style lang="scss" scoped>
......@@ -265,14 +344,19 @@ const decreeInfo = ref({
margin-top: 20px;
}
.title {
width: 200px;
margin-left: 17px;
margin-top: 17px;
height: 30px;
// color: var(--color-main-active);
// font-family: Microsoft YaHei;
// font-size: 16px;
// font-weight: 700;
line-height: 30px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
letter-spacing: 0px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.leftItemActive {
......@@ -285,7 +369,7 @@ const decreeInfo = ref({
width: 5px;
height: 48px;
background: var(--color-main-active);
right: -70px;
right: -15px;
top: 8px;
}
}
......
......@@ -122,7 +122,7 @@
<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import router from "@/router";
import { useRoute } from "vue-router";
import search from "./assets/images/search.png";
import icon1 from "./assets/icons/icon1.png";
......@@ -132,6 +132,10 @@ import icon2Active from "./assets/icons/icon2_active.png";
import icon3 from "./assets/icons/icon3.png";
import icon3Active from "./assets/icons/icon3_active.png";
const route = useRoute();
const decreeId = ref(route.query.id);
const activeName = ref("分析报告");
const handleSwitchActiveName = name => {
......@@ -177,7 +181,12 @@ const activeTitle = ref("政令概况");
const handleClickMainHeaderBtn = item => {
activeTitle.value = item.name;
window.sessionStorage.setItem("activeTitle", item.name);
router.push(item.path);
router.push({
path: item.path,
query: {
id: decreeId.value
}
});
};
onMounted(() => {
......
<template>
<div class="wrapper">
<div class="left">
<div class="box1">
<div class="box-header">
<div class="icon"></div>
<div class="title">{{ "企业影响分析" }}</div>
<div class="header-right1">
<el-checkbox
v-model="isChecked"
label="只看中国企业"
size="large"
/>
</div>
<div class="wrapper">
<div class="left">
<div class="box1">
<div class="box-header">
<div class="icon"></div>
<div class="title">{{ "企业影响分析" }}</div>
<div class="header-right1">
<el-checkbox v-model="isCRelated" label="只看中国企业" size="large" />
</div>
<div class="header-right">
<div class="header-right-icon">
<img src="@/assets/icons/box-header-icon2.png" alt="" />
......@@ -20,56 +16,51 @@
<img src="@/assets/icons/box-header-icon3.png" alt="" />
</div>
</div>
</div>
<div class="box1-top" id="chart1"></div>
<div class="box1-tab-box">
<div
class="tab"
:class="{ tabActive: box1BtnActiveName === item }"
v-for="(item, index) in box1BtnList"
:key="index"
@click="handleClickBox1Btn(item)"
>
{{ item }}
</div>
</div>
<div class="box1-list-box">
<div
class="box1-item"
v-for="(item, index) in companyList"
:key="index"
>
<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-else src="./assets/images/down.png" alt="" />
</div>
</div>
</div>
<div class="box1-footer">
<div class="box1-footer-left">{{ `共${companyTotalNum}家企业` }}</div>
<div class="box1-footer-right">
<el-pagination
background
layout="prev, pager, next"
size="small"
:total="105"
/>
</div>
</div>
</div>
</div>
<div class="right">
<div class="box2">
<div class="box-header">
<div class="icon"></div>
<div class="title">{{ "政令举措落实分析" }}</div>
<div class="header-right1"></div>
</div>
<div class="box1-top" id="chart1"></div>
<div class="box1-tab-box">
<div
class="tab"
:class="{ tabActive: box1BtnActiveName === item.name }"
v-for="(item, index) in box1BtnList"
:key="index"
@click="handleClickBox1Btn(item)"
>
{{ item.name }}
</div>
</div>
<div class="box1-list-box">
<div class="box1-item" v-for="(item, index) in showCompanyList" :key="index">
<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-else src="./assets/images/down.png" alt="" />
</div>
</div>
</div>
<div class="box1-footer">
<div class="box1-footer-left">{{ `共${companyTotalNum}家企业` }}</div>
<div class="box1-footer-right">
<el-pagination
@current-change="handleCurrentChange"
:pageSize="pageSize"
:current-page="currentPage"
background
layout="prev, pager, next"
size="small"
:total="companyTotalNum"
/>
</div>
</div>
</div>
</div>
<div class="right">
<div class="box2">
<div class="box-header">
<div class="icon"></div>
<div class="title">{{ "政令举措落实分析" }}</div>
<div class="header-right1"></div>
<div class="header-right">
<div class="header-right-icon">
<img src="@/assets/icons/box-header-icon2.png" alt="" />
......@@ -78,46 +69,46 @@
<img src="@/assets/icons/box-header-icon3.png" alt="" />
</div>
</div>
</div>
</div>
<div class="box2-main">
<div class="box2-line-box"></div>
<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="./assets/images/point.png" alt="" />
</div>
<div class="box2-item-header">
<div class="title">{{ item.time }}</div>
</div>
<div class="box2-item-content">
{{ item.content }}
</div>
</div>
</div>
<div class="box2-footer">
<div class="footer-left">
<img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div>
<div class="footer-center">
{{
`政令目前仍处于关键的执行框架搭建期。该政令旨在通过推动“全栈式”美国AI技术出口,巩固其技术霸权并减少国际社会对美国对手国家技术的依赖`
}}
</div>
<div class="footer-right">
<img src="@/assets/icons/box-footer-right-icon.png" alt="" />
</div>
</div>
</div>
<div class="box3">
<div class="box-header">
<div class="icon"></div>
<div class="title">{{ "历史相似举措及落实情况" }}</div>
<div class="header-right1"></div>
<div class="box2-main">
<div class="box2-line-box"></div>
<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="./assets/images/point.png" alt="" />
</div>
<div class="box2-item-header">
<div class="title">{{ item.time }}</div>
</div>
<div class="box2-item-content">
{{ item.content }}
</div>
</div>
</div>
<div class="box2-footer">
<div class="footer-left">
<img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div>
<div class="footer-center">
{{
`政令目前仍处于关键的执行框架搭建期。该政令旨在通过推动“全栈式”美国AI技术出口,巩固其技术霸权并减少国际社会对美国对手国家技术的依赖`
}}
</div>
<div class="footer-right">
<img src="@/assets/icons/box-footer-right-icon.png" alt="" />
</div>
</div>
</div>
<div class="box3">
<div class="box-header">
<div class="icon"></div>
<div class="title">{{ "历史相似举措及落实情况" }}</div>
<div class="header-right1"></div>
<div class="header-right">
<div class="header-right-icon">
<img src="@/assets/icons/box-header-icon2.png" alt="" />
......@@ -126,636 +117,763 @@
<img src="@/assets/icons/box-header-icon3.png" alt="" />
</div>
</div>
</div>
<div class="box3-main">
<div class="box3-item" v-for="(item, index) in box3List" :key="index">
<div class="box3-item-left">
<div class="text">
{{ item.type }}
</div>
</div>
<div class="box3-item-right">
<div class="right-top">
<div class="title">{{ item.title }}</div>
<div class="tag">{{ item.tag }}</div>
</div>
<div class="right-footer">
<div class="content">{{ item.content }}</div>
<div class="time">{{ item.time }}</div>
</div>
</div>
</div>
</div>
<div class="box3-footer">
<div class="footer-left">
<img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div>
<div class="footer-center">
{{
`中美经济深度交织,全面脱钩成本高昂且不现实。其核心揭示了三大纽带:生产网络相互依存使强行分离代价巨大;人才双向流动推动创新却成政策博弈焦点;能源领域合作与竞争并存,关乎全球气候治理与经济博弈。报告主张理性竞合,在竞争中找到合作路径。`
}}
</div>
<div class="footer-right">
<img src="@/assets/icons/box-footer-right-icon.png" alt="" />
</div>
</div>
</div>
</div>
</div>
</div>
<div class="box3-main">
<div class="box3-item" v-for="(item, index) in box3List" :key="index">
<div class="box3-item-left">
<div class="text">
{{ item.type }}
</div>
</div>
<div class="box3-item-right">
<div class="right-top">
<div class="title">{{ item.title }}</div>
<div class="tag">{{ item.tag }}</div>
</div>
<div class="right-footer">
<div class="content">{{ item.content }}</div>
<div class="time">{{ item.time }}</div>
</div>
</div>
</div>
</div>
<div class="box3-footer">
<div class="footer-left">
<img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div>
<div class="footer-center">
{{
`中美经济深度交织,全面脱钩成本高昂且不现实。其核心揭示了三大纽带:生产网络相互依存使强行分离代价巨大;人才双向流动推动创新却成政策博弈焦点;能源领域合作与竞争并存,关乎全球气候治理与经济博弈。报告主张理性竞合,在竞争中找到合作路径。`
}}
</div>
<div class="footer-right">
<img src="@/assets/icons/box-footer-right-icon.png" alt="" />
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { ref, computed,watch, onMounted } from "vue";
import { useRoute } from "vue-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 companyTotalNum = ref(0); // 企业数量
const isCRelated = ref(false); // 只看中国企业
const chart1Data = ref({
title: ["集成电路", "新能源", "人工智能", "先进制造", "量子科技"],
value: [109, 95, 79, 25, 11],
// title: ["集成电路", "新能源", "人工智能", "先进制造", "量子科技"],
// value: [109, 95, 79, 25, 11]
});
const box1BtnActiveName = ref('集成电路');
const handleGetChart1Data = async () => {
const params = {
cRelated: isCRelated.value,
id: 147
};
try {
const res = await getDecreeIndustry(params);
console.log("企业影响分析", res);
if (res.code === 200 && res.data) {
chart1Data.value.title = res.data.map(item => {
return item.hylyName;
});
chart1Data.value.value = res.data.map(item => {
return item.companyNum;
});
} else {
chart1Data.value.title = [];
chart1Data.value.value = [];
}
} catch (error) {
chart1Data.value.title = [];
chart1Data.value.value = [];
}
};
const handelBox1 = async () => {
await handleGetChart1Data();
let chart1 = getBarChart(chart1Data.value.title, chart1Data.value.value);
setChart(chart1, "chart1");
};
const box1BtnActiveName = ref("");
const curAreaId = ref(0);
const box1BtnList = ref(["集成电路", "新能源", "人工智能", "先进制造", "量子科技"]);
const handleClickBox1Btn = btn => {
box1BtnActiveName.value = btn
}
box1BtnActiveName.value = btn.name;
curAreaId.value = btn.id;
handleGetCompanyListByArea();
};
// 获取行业领域列表
const handleGetHylyList = async () => {
try {
const res = await getDecreehylyList();
console.log("行业领域列表", res);
if (res.code === 200 && res.data) {
box1BtnList.value = res.data;
box1BtnActiveName.value = box1BtnList.value[0].name;
curAreaId.value = box1BtnList.value[0].id;
}
} 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"
},
{
name: "国轩高科股份有限公司",
status: "up"
},
{
name: "远景科技集团",
status: "down"
},
{
name: "惠州亿纬锂能股份有限公司",
status: "down"
},
{
name: "天合光能股份有限公司",
status: "down"
},
{
name: "晶澳太阳能科技股份有限公司",
status: "up"
}
]);
const companyTotalNum = ref(105); // 企业数量
const isChecked = ref(true); // 只看中国企业
const currentPage = ref(1);
const pageSize = ref(10);
// 处理页码改变事件
const handleCurrentChange = page => {
currentPage.value = page;
};
const showCompanyList = computed(() => {
const startIndex = (currentPage.value - 1) * pageSize.value;
const endIndex = startIndex + pageSize.value;
return companyList.value.slice(startIndex, endIndex);
});
const handleGetCompanyListByArea = async () => {
const params = {
cRelated: isCRelated.value,
id: curAreaId.value
};
try {
const res = await getDecreeCompany(params);
console.log("行业领域公司列表", res);
if (res.code === 200 && res.data) {
companyList.value = res.data.map(item => {
return {
name: item.name,
id: item.id,
status: "up"
};
});
companyTotalNum.value = companyList.value.length;
} else {
companyList.value = [];
companyTotalNum.value = 0;
}
} catch (error) {
companyList.value = [];
companyTotalNum.value = 0;
}
};
// 政令举措落实情况
// 政令举措落实分析
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: "英伟达、微软、谷歌等企业已提交初步技术栈提案。"
},
{
time: "2025年8月5日",
content: "国务院开始与盟友国家进行初步磋商。"
},
{
time: "2025年8月9日",
content: "国防部、能源部安全审查流程尚未最终确定。"
},
{
time: "2025年8月12日",
content: "商务部已成立AI出口计划办公室,并开始招募专业人员。"
}
]);
const handleGetAction = async () => {
const params = {
id: route.query.id
};
try {
const res = await getDecreeAction(params);
console.log("政令举措落实分析", res);
if (res.code === 200 && res.data) {
timeLineList.value = res.data.map(item => {
return {
time: item.time,
content: item.describe
};
});
} else {
timeLineList.value = [];
}
} catch (error) {
timeLineList.value = [];
}
};
// 历史相似举措及落实情况
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(
() => isCRelated.value,
val => {
handleGetCompanyListByArea();
handelBox1();
}
);
onMounted(() => {
let chart1 = getBarChart(chart1Data.value.title, chart1Data.value.value);
setChart(chart1, "chart1");
handleGetCompanyListByArea();
handleGetChart1Data();
handleGetHylyList();
handleGetAction();
handelBox1();
});
</script>
<style lang="scss" scoped>
.wrapper {
width: 100%;
height: 879px;
display: flex;
.box-header {
display: flex;
height: 48px;
position: relative;
.icon {
margin-top: 18px;
width: 8px;
height: 20px;
border-radius: 0 4px 4px 0;
background: var(--color-main-active);
}
.title {
height: 26px;
margin-left: 14px;
margin-top: 14px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
}
width: 100%;
height: 879px;
display: flex;
.box-header {
display: flex;
height: 48px;
position: relative;
.icon {
margin-top: 18px;
width: 8px;
height: 20px;
border-radius: 0 4px 4px 0;
background: var(--color-main-active);
}
.title {
height: 26px;
margin-left: 14px;
margin-top: 14px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
}
.header-right {
position: absolute;
top: 14px;
right: 12px;
display: flex;
justify-content: flex-end;
display: flex;
justify-content: flex-end;
gap: 4px;
.header-right-icon{
width: 28px;
height: 28px;
img{
width: 100%;
height: 100%;
}
}
.header-right-icon {
width: 28px;
height: 28px;
img {
width: 100%;
height: 100%;
}
}
}
.header-right1 {
position: absolute;
top: 8px;
right: 84px;
}
}
.left {
margin-left: 160px;
margin-top: 16px;
.box1 {
width: 480px;
height: 845px;
border-radius: 4px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
background: rgba(255, 255, 255, 1);
.box1-top {
width: 446px;
height: 188px;
margin: 7px auto 0;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 4px;
background: rgba(247, 248, 249, 1);
}
.box1-tab-box {
height: 60px;
width: 446px;
margin: 0 auto;
overflow-x: auto;
display: flex;
white-space: nowrap;
gap: 8px;
.tab {
min-width: min-content;
margin-top: 18px;
padding: 0 8px;
height: 28px;
box-sizing: border-box;
border: 1px solid rgba(230, 231, 232, 1);
border-radius: 4px;
background: rgba(255, 255, 255, 1);
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
cursor: pointer;
&:hover {
background: var(--btn-active-bg-color);
border: 1px solid var(--btn-active-border-color);
}
}
.tabActive {
color: var(--btn-active-text-color);
background: var(--btn-active-bg-color);
border: 1px solid var(--btn-active-border-color);
}
}
.box1-list-box {
height: 480px;
width: 446px;
margin: 0 auto;
.box1-item {
width: 446px;
height: 48px;
box-sizing: border-box;
border-bottom: 1px solid rgba(234, 236, 238, 1);
border-radius: 4px;
display: flex;
.id {
width: 24px;
height: 24px;
margin-top: 12px;
margin-left: 12px;
border-radius: 12px;
background: #e7f3ff;
font-size: 14px;
font-family: Microsoft YaHei;
text-align: center;
line-height: 24px;
color: var(--color-main-active);
}
.title {
margin-left: 10px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 48px;
}
.icon {
width: 8px;
height: 6px;
margin-top: 14px;
margin-left: 6px;
img {
width: 100%;
height: 100%;
}
}
}
}
.box1-footer {
height: 65px;
width: 446px;
margin: 0 auto;
display: flex;
justify-content: space-between;
box-sizing: border-box;
.box1-footer-left {
margin-top: 25px;
height: 18px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 18px;
}
.box1-footer-right {
margin-top: 23px;
}
}
}
}
.right {
margin-left: 17px;
margin-top: 16px;
.box2 {
width: 1103px;
height: 415px;
border-radius: 4px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
background: rgba(255, 255, 255, 1);
.box2-main {
margin: 0 auto;
margin-top: 10px;
height: 260px;
width: 1054px;
overflow-x: auto;
overflow-y: hidden;
display: flex;
position: relative;
padding-left: 120px;
.box2-line-box {
position: absolute;
left: 0;
top: 114px;
height: 8px;
width: 1054px;
background: url("./assets/images/line-bg.png") repeat;
}
.box2-item {
width: 300px;
height: 120px;
position: relative;
box-sizing: border-box;
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;
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
}
}
.box2-item-content {
width: 210px;
min-height: 48px;
max-height: 96px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
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);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 24px;
position: absolute;
bottom: -36px;
left: 0;
}
}
.box2ItemFooter {
margin-top: 118px;
margin-left: -120px;
box-sizing: border-box;
padding-top: 20px;
// display: flex;
// flex-direction: column;
// justify-content: flex-end;
}
}
.box2-footer {
margin-top: 6px;
width: 1057px;
height: 64px;
box-sizing: border-box;
border: 1px rgba(231, 243, 255, 1);
border-radius: 4px;
background: rgba(246, 251, 255, 1);
margin: 14px auto 0;
padding: 6px 12px 6px 12px;
display: flex;
.footer-left {
width: 19px;
height: 20px;
margin-top: 16px;
img {
width: 100%;
height: 100%;
}
}
.footer-center {
margin-left: 13px;
width: 964px;
height: 48px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
display: flex;
align-items: center;
}
.footer-right {
margin-left: 13px;
width: 24px;
height: 24px;
border-radius: 12px;
margin-top: 14px;
img {
width: 100%;
height: 100%;
}
}
}
}
.box3 {
margin-top: 15px;
width: 1103px;
height: 415px;
border-radius: 4px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
background: rgba(255, 255, 255, 1);
.box3-main {
height: 264px;
overflow-y: auto;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin-left: 21px;
margin-right: 26px;
.box3-item {
margin-top: 12px;
width: 520px;
height: 76px;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 4px;
display: flex;
.box3-item-left {
width: 54px;
height: 54px;
border-radius: 27px;
background: #e7f3ff;
text-align: center;
margin-top: 11px;
margin-left: 14px;
.text {
width: 33px;
height: 30px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 700;
line-height: 18px;
margin: 11px auto;
}
}
.box3-item-right {
margin-left: 8px;
width: 433px;
.right-top {
display: flex;
justify-content: space-between;
.title {
margin-top: 13px;
height: 24px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 18px;
font-weight: 700;
line-height: 24px;
}
.tag {
margin-top: 11px;
width: 72px;
height: 24px;
box-sizing: border-box;
border: 1px solid rgba(255, 163, 158, 1);
border-radius: 4px;
background: rgba(255, 241, 240, 1);
color: rgba(245, 34, 45, 1);
}
}
.right-footer {
margin-top: 2px;
display: flex;
justify-content: space-between;
.content {
height: 24px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
width: 353px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.time {
height: 24px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
width: 78px;
line-height: 24px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
}
}
.box3-footer {
width: 1057px;
height: 64px;
box-sizing: border-box;
border: 1px rgba(231, 243, 255, 1);
border-radius: 4px;
background: rgba(246, 251, 255, 1);
margin: 14px auto 0;
padding: 6px 12px 6px 12px;
display: flex;
.footer-left {
width: 19px;
height: 20px;
margin-top: 16px;
img {
width: 100%;
height: 100%;
}
}
.footer-center {
margin-left: 13px;
width: 964px;
height: 48px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
display: flex;
align-items: center;
}
.footer-right {
margin-left: 13px;
width: 24px;
height: 24px;
border-radius: 12px;
margin-top: 14px;
img {
width: 100%;
height: 100%;
}
}
}
}
.header-right1 {
position: absolute;
top: 8px;
right: 84px;
}
}
.left {
margin-left: 160px;
margin-top: 16px;
.box1 {
width: 480px;
height: 845px;
border-radius: 4px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
background: rgba(255, 255, 255, 1);
.box1-top {
width: 446px;
height: 188px;
margin: 7px auto 0;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 4px;
background: rgba(247, 248, 249, 1);
}
.box1-tab-box {
height: 57px;
width: 446px;
margin: 0 auto;
display: flex;
.tab {
margin-top: 18px;
margin-right: 8px;
padding: 0 8px;
height: 28px;
box-sizing: border-box;
border: 1px solid rgba(230, 231, 232, 1);
border-radius: 4px;
background: rgba(255, 255, 255, 1);
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
cursor: pointer;
&:hover {
background: var(--btn-active-bg-color);
border: 1px solid var(--btn-active-border-color);
}
}
.tabActive {
color: var(--btn-active-text-color);
background: var(--btn-active-bg-color);
border: 1px solid var(--btn-active-border-color);
}
}
.box1-list-box {
height: 480px;
width: 446px;
margin: 0 auto;
.box1-item {
width: 446px;
height: 48px;
box-sizing: border-box;
border-bottom: 1px solid rgba(234, 236, 238, 1);
border-radius: 4px;
display: flex;
.id {
width: 24px;
height: 24px;
margin-top: 12px;
margin-left: 12px;
border-radius: 12px;
background: #e7f3ff;
font-size: 14px;
font-family: Microsoft YaHei;
text-align: center;
line-height: 24px;
color: var(--color-main-active);
}
.title {
margin-left: 10px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 48px;
}
.icon {
width: 8px;
height: 6px;
margin-top: 14px;
margin-left: 6px;
img {
width: 100%;
height: 100%;
}
}
}
}
.box1-footer {
height: 65px;
width: 446px;
margin: 0 auto;
display: flex;
justify-content: space-between;
box-sizing: border-box;
.box1-footer-left {
margin-top: 25px;
height: 18px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 18px;
}
.box1-footer-right {
margin-top: 23px;
}
}
}
}
.right {
margin-left: 17px;
margin-top: 16px;
.box2 {
width: 1103px;
height: 415px;
border-radius: 4px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
background: rgba(255, 255, 255, 1);
.box2-main {
margin: 0 auto;
margin-top: 10px;
height: 260px;
width: 1054px;
overflow-x: auto;
overflow-y: hidden;
display: flex;
position: relative;
padding-left: 120px;
.box2-line-box {
position: absolute;
left: 0;
top: 114px;
height: 8px;
width: 1054px;
background: url("./assets/images/line-bg.png") repeat;
}
.box2-item {
width: 300px;
height: 120px;
position: relative;
box-sizing: border-box;
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;
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
}
}
.box2-item-content {
width: 210px;
min-height: 48px;
max-height: 96px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
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);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
line-height: 24px;
position: absolute;
bottom: -36px;
left: 0;
}
}
.box2ItemFooter {
margin-top: 118px;
margin-left: -120px;
box-sizing: border-box;
padding-top: 20px;
// display: flex;
// flex-direction: column;
// justify-content: flex-end;
}
}
.box2-footer {
margin-top: 6px;
width: 1057px;
height: 64px;
box-sizing: border-box;
border: 1px rgba(231, 243, 255, 1);
border-radius: 4px;
background: rgba(246, 251, 255, 1);
margin: 14px auto 0;
padding: 6px 12px 6px 12px;
display: flex;
.footer-left {
width: 19px;
height: 20px;
margin-top: 16px;
img {
width: 100%;
height: 100%;
}
}
.footer-center {
margin-left: 13px;
width: 964px;
height: 48px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
display: flex;
align-items: center;
}
.footer-right {
margin-left: 13px;
width: 24px;
height: 24px;
border-radius: 12px;
margin-top: 14px;
img {
width: 100%;
height: 100%;
}
}
}
}
.box3 {
margin-top: 15px;
width: 1103px;
height: 415px;
border-radius: 4px;
box-shadow: 0px 0px 15px 0px rgba(60, 87, 126, 0.2);
background: rgba(255, 255, 255, 1);
.box3-main {
height: 264px;
overflow-y: auto;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
margin-left: 21px;
margin-right: 26px;
.box3-item {
margin-top: 12px;
width: 520px;
height: 76px;
box-sizing: border-box;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 4px;
display: flex;
.box3-item-left {
width: 54px;
height: 54px;
border-radius: 27px;
background: #e7f3ff;
text-align: center;
margin-top: 11px;
margin-left: 14px;
.text {
width: 33px;
height: 30px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 700;
line-height: 18px;
margin: 11px auto;
}
}
.box3-item-right {
margin-left: 8px;
width: 433px;
.right-top {
display: flex;
justify-content: space-between;
.title {
margin-top: 13px;
height: 24px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-size: 18px;
font-weight: 700;
line-height: 24px;
}
.tag {
margin-top: 11px;
width: 72px;
height: 24px;
box-sizing: border-box;
border: 1px solid rgba(255, 163, 158, 1);
border-radius: 4px;
background: rgba(255, 241, 240, 1);
color: rgba(245, 34, 45, 1);
}
}
.right-footer {
margin-top: 2px;
display: flex;
justify-content: space-between;
.content {
height: 24px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
width: 353px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.time {
height: 24px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
width: 78px;
line-height: 24px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
}
}
}
.box3-footer {
width: 1057px;
height: 64px;
box-sizing: border-box;
border: 1px rgba(231, 243, 255, 1);
border-radius: 4px;
background: rgba(246, 251, 255, 1);
margin: 14px auto 0;
padding: 6px 12px 6px 12px;
display: flex;
.footer-left {
width: 19px;
height: 20px;
margin-top: 16px;
img {
width: 100%;
height: 100%;
}
}
.footer-center {
margin-left: 13px;
width: 964px;
height: 48px;
color: var(--color-main-active);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
display: flex;
align-items: center;
}
.footer-right {
margin-left: 13px;
width: 24px;
height: 24px;
border-radius: 12px;
margin-top: 14px;
img {
width: 100%;
height: 100%;
}
}
}
}
}
}
}
</style>
\ No newline at end of file
......@@ -28,16 +28,16 @@
<div class="box1-main">
<div class="box1-item" v-for="(item, index) in backgroundList" :key="index">
<div class="id">{{ index + 1 }}</div>
<div class="title">{{ item.title }}</div>
<div class="title">{{ item.content }}</div>
<div class="open">
<img src="./assets/images/open-icon.png" alt="" />
</div>
</div>
</div>
<div class="box1-footer">
<div class="box1-footer-left">{{ "共计10条指令" }}</div>
<div class="box1-footer-left">{{ `共计${backgroundListNum}条指令` }}</div>
<div class="box1-footer-right">
<el-pagination :page-size="5" background layout="prev, pager, next" :total="10" />
<el-pagination :page-size="5" background layout="prev, pager, next" :total="backgroundListNum" />
</div>
</div>
</div>
......@@ -103,36 +103,55 @@
<script setup>
import { ref, onMounted } from "vue";
import { useRoute } from "vue-router";
import { getDecreeBackground, getDecreeRelatedEvent, getDecreeDepend } from "@/api/decree/background";
import Img1 from "./assets/images/box2-img1.png";
import Img2 from "./assets/images/box2-img2.png";
import Img3 from "./assets/images/box2-img3.png";
import Img4 from "./assets/images/box2-img4.png";
import Img5 from "./assets/images/box2-img5.png";
import { reduce } from "lodash";
const route = useRoute();
const decreeId = ref(route.query.id);
// 提出背景
const box1BtnList = ref(["涉华背景", "全部背景"]);
const box1ActiveBtn = ref("涉华背景");
const handleClickBox1Btn = btn => {
box1ActiveBtn.value = btn;
handleGetBackground();
};
const backgroundListNum = ref(0);
const backgroundList = ref([
{
title: "认为人工智能(AI)是一项将决定未来几十年经济增长、国家安全和全球竞争力的基础性技术"
},
{
title: "要求美国不仅必须在开发通用和前沿AI能力方面领先,还必须确保美国的人工智能技术、标准和治理模式在全球范围内被采用"
},
{
title: "要求加强与盟友的关系并确保我们持续的技术主导地位"
content: "认为人工智能(AI)是一项将决定未来几十年经济增长、国家安全和全球竞争力的基础性技术"
},
{
title: "计划通过支持美国原产人工智能技术的全球部署,以维护和扩大美国在人工智能领域的领导地位"
content: "要求美国不仅必须在开发通用和前沿AI能力方面领先,还必须确保美国的人工智能技术、标准和治理模式在全球范围内被采用"
},
{
title: "目的为减少国际社会对由中国开发的人工智能技术的依赖"
}
]);
const handleGetBackground = async () => {
const params = {
cRelated: box1ActiveBtn.value === "涉华背景" ? true : false,
currentPage: 0,
pageSize: 999999,
id: decreeId.value
};
try {
const res = await getDecreeBackground(params);
console.log("提出背景", res);
if (res.code === 200 && res.data) {
backgroundListNum.value = res.data.numberOfElements
backgroundList.value = res.data.content
} else {
backgroundListNum.value = 0;
backgroundList.value = [];
}
} catch (error) {}
};
// 相关事件
const relatedEvents = ref([
......@@ -170,7 +189,29 @@ const relatedEvents = ref([
time: "2025-05-20"
}
]);
const handleGetRelateEvents = async () => {
const params = {
id: decreeId.value
}
try {
const res = await getDecreeRelatedEvent(params)
console.log('相关事件', res);
if(res.code === 200 && res.data) {
relatedEvents.value = res.data.map( item => {
return {
image: '',
title: item.sjbt,
content: item.sjnr,
time: item.sjsj
}
})
} else {
relatedEvents.value = []
}
} catch (error) {
}
}
// 法律依据
const laws = ref([
......@@ -203,6 +244,28 @@ const laws = ref([
content: "要求强大AI系统的开发者与政府共享安全测试结果,并为AI安全、隐私保护、公平权利及创新竞争等方面制定标准。"
}
]);
const handleGetLaws = async () => {
const params = {
id: decreeId.value
}
try {
const res = await getDecreeDepend(params)
console.log('法律依据', res);
if(res.code === 200 && res.data) {
} else {
laws.value = []
}
} catch (error) {
}
}
onMounted(() => {
handleGetBackground();
handleGetRelateEvents()
handleGetLaws()
});
</script>
<style lang="scss" scoped>
......
......@@ -22,6 +22,10 @@
<script setup>
import { ref, onMounted, onUnmounted } from "vue";
import router from "@/router";
import { useRoute } from "vue-router";
const route = useRoute();
const decreeId = ref(route.query.id);
const siderList = ref([
{
......@@ -39,7 +43,12 @@ const siderBtnActive = ref("政令简介");
const handleClickLeftSiderBtn = item => {
window.sessionStorage.setItem("siderBarActiveName", item.name);
siderBtnActive.value = item.name;
router.push(item.path);
router.push({
path: item.path,
query: {
id: decreeId.value
}
});
};
onMounted(() => {
......
......@@ -17,7 +17,7 @@
</div>
<div class="box1-main">
<div class="box1-main-left">
<img src="./assets/images/box1-img.png" alt="" />
<img :src="basicInfo.img" alt="" />
</div>
<div class="box1-main-right">
<div class="item">
......@@ -34,7 +34,7 @@
<div class="item-left">{{ "相关领域:" }}</div>
<div class="item-right tag-box">
<div class="tag" v-for="(area, index) in basicInfo.areaList" :key="index">
{{ area }}
{{ area.industryName }}
</div>
</div>
</div>
......@@ -77,18 +77,24 @@
</div>
</div>
<div class="box2-main">
<div class="box2-item" v-for="(item, index) in majorList" :key="index">
<div class="box2-item" v-for="(item, index) in curmajorList" :key="index">
<div class="id">{{ index + 1 }}</div>
<div class="title">{{ item.title }}</div>
<div class="title">{{ item.content }}</div>
<div class="open">
<img src="./assets/images/open-icon.png" alt="" />
</div>
</div>
</div>
<div class="box2-footer">
<div class="box2-footer-left">{{ "共计10条指令" }}</div>
<div class="box2-footer-left">{{ `共计${majorListNum}条指令` }}</div>
<div class="box2-footer-right">
<el-pagination :page-size="5" background layout="prev, pager, next" :total="10" />
<el-pagination
@current-change="handleCurrentChange"
:page-size="5"
background
layout="prev, pager, next"
:total="majorListNum"
/>
</div>
</div>
</div>
......@@ -104,7 +110,7 @@
:class="{ btnActive: box3ActiveBtn === item }"
v-for="(item, index) in box3BtnList"
:key="index"
@click="handleClickBox3Btn(item)"
@click="handleClickBox3Btn(item, index)"
>
{{ item }}
</div>
......@@ -179,7 +185,7 @@
:key="index"
>
<div class="timeline-content">
{{ item.content }}
{{ item.title }}
</div>
</el-timeline-item>
</el-timeline>
......@@ -194,12 +200,19 @@
</template>
<script setup>
import { ref, onMounted } from "vue";
import { ref, computed, onMounted } from "vue";
import { useRoute } from "vue-router";
import box1Img from "./assets/images/box1-img.png";
import Box3Logo from "./assets/images/box3-img.png";
import { getDecreeBasicInfo, getDecreeMainContent, getDecreeOrganization } from "@/api/decree/introduction";
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: ["人工智能", "出口管制", "半导体产业", "关税", "光伏产业"],
......@@ -209,38 +222,98 @@ const basicInfo = ref({
deadline: "签署后90天内建立机制并开始实施"
});
const handleGetBasicInfo = async () => {
const params = {
id: decreeId.value
};
try {
const res = await getDecreeBasicInfo(params);
console.log("基本信息", res);
if (res.code === 200 && res.data) {
basicInfo.value.img = res.data.picture;
basicInfo.value.name = res.data.name;
basicInfo.value.eName = res.data.ename;
basicInfo.value.areaList = res.data.industryList;
basicInfo.value.signTime = res.data.postDate;
basicInfo.value.bh = res.data.order;
basicInfo.value.deadline = res.data.deadline;
}
} catch (error) {
console.error("基本信息error", error);
}
};
handleGetBasicInfo();
// 主要指令
const majorList = ref([
{
title: '要求商务部在90天内建立"全栈式"美国AI出口机制。'
},
{
title: '要求每个纳入出口计划的提案必须涵盖完整的"全栈AI技术包"。'
},
{
title: '指示联邦机构提供贷款、担保、股权投资和技术援助支持入选的"优先AI出口包"。'
},
{
title: "要求输出技术必须符合美国出口管制法规,并由多部门对最终用户进行合规与安全联合审查。"
},
{
title: '明确政策目标为"减少对对手国家开发的AI技术的国际依赖"。'
id: 1,
content: '要求商务部在90天内建立"全栈式"美国AI出口机制。'
}
]);
const currentPage = ref(1);
const pageSize = ref(5);
// 处理页码改变事件
const handleCurrentChange = page => {
currentPage.value = page;
};
const curmajorList = computed(() => {
const startIndex = (currentPage.value - 1) * pageSize.value;
const endIndex = startIndex + pageSize.value;
return majorList.value.slice(startIndex, endIndex);
});
const majorListNum = ref(0);
const handleMajorList = async () => {
const params = {
currentPage: 0,
pageSize: 999999,
id: decreeId.value
};
try {
const res = await getDecreeMainContent(params);
console.log("主要指令", res);
if (res.code === 200 && res.data) {
majorList.value = res.data.content;
majorListNum.value = res.data.numberOfElements;
} else {
majorList.value = [];
majorListNum.value = 0;
}
} catch (error) {}
};
handleMajorList();
// 执行机构
const box3BtnList = ref(["商务部", "经济外交行动组"]);
const box3ActiveBtn = ref("商务部");
const handleClickBox3Btn = btn => {
const box3BtnActiveIndex = ref(0);
const handleClickBox3Btn = (btn, index) => {
box3ActiveBtn.value = btn;
box3BtnActiveIndex.value = index;
box3TopData.value.logo = box3Data.value[index].url;
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 => {
return {
time: val.newsDate,
title: newsTitle
};
});
};
const box3Data = ref([]);
const box3TopData = ref({
logo: Box3Logo,
name: "美国商务部",
eName: "United States Department of Commerce",
clsj: "1903年2月14日",
zyzz: "国际贸易、进出口管制(R-TX-19)",
zbdz: "华盛顿宪法大道1401号胡佛大楼",
bz: "霍华德·卢特尼克"
});
......@@ -249,24 +322,74 @@ const box3TopData = ref({
const eventList = ref([
{
time: "2025-07-31",
content:
"美商务部发布指南,警告全球企业使用华为昇腾芯片可能违反美国出口管制。意在限制中国AI产业发展,阻碍其获得先进算力。"
title: "美商务部发布指南,警告全球企业使用华为昇腾芯片可能违反美国出口管制。意在限制中国AI产业发展,阻碍其获得先进算力。"
},
{
time: "2025-07-25",
content:
"美商务部持续对多种中国产品发起“双反”(反倾销、反补贴)调查并作出裁决,涉及产品从工业原料到日常用品,且裁定的税率普遍较高。"
title: "美商务部持续对多种中国产品发起“双反”(反倾销、反补贴)调查并作出裁决,涉及产品从工业原料到日常用品,且裁定的税率普遍较高。"
},
{
time: "2025-07-21",
content:
"美商务部进一步收紧对华先进半导体出口管制,将更多中国实体列入“实体清单”。限制14纳米及以下先进芯片、DRAM等对华出口"
title: "美商务部进一步收紧对华先进半导体出口管制,将更多中国实体列入“实体清单”。限制14纳米及以下先进芯片、DRAM等对华出口"
},
{
time: "2025-07-12",
content: "美商务部发起第三次反倾销和反补贴日落复审调查。"
title: "美商务部发起第三次反倾销和反补贴日落复审调查。"
}
]);
const handleGetOrgnization = async () => {
const params = {
id: decreeId.value
};
try {
const res = await getDecreeOrganization(params);
console.log("执行机构", res);
if (res.code === 200 && res.data) {
box3BtnList.value = res.data.map(item => {
return item.name;
});
box3Data.value = res.data;
box3TopData.value.logo = res.data[0].url;
box3TopData.value.name = res.data[0].name;
box3TopData.value.eName = res.data[0].ename;
box3TopData.value.clsj = res.data[0].foundingDate;
box3TopData.value.zbdz = res.data[0].address;
box3TopData.value.bz = res.data[0].leaderName;
eventList.value = res.data[0].newsList.map(val => {
return {
time: val.newsDate,
title: newsTitle
};
});
} else {
box3BtnList.value = [];
box3TopData.value = {
logo: "",
name: "",
eName: "",
clsj: "",
zyzz: "",
zbdz: "",
bz: ""
};
eventList.value = [];
}
} catch (error) {
console.error("执行机构error", error);
box3BtnList.value = [];
box3TopData.value = {
logo: "",
name: "",
eName: "",
clsj: "",
zbdz: "",
bz: ""
};
eventList.value = [];
}
};
handleGetOrgnization();
</script>
<style lang="scss" scoped>
......
......@@ -726,7 +726,7 @@ export const getHorizontalBarChart2 = (nameList, valueList, isPer) => {
tooltip: {},
grid: {
top: "3%",
right: "10%",
right: "6%",
bottom: "0",
left: "1%",
containLabel: true
......@@ -769,7 +769,7 @@ export const getHorizontalBarChart2 = (nameList, valueList, isPer) => {
}),
label: {
show: true,
position: [340, -2],
position: [310, -2],
formatter: function (params) {
return isPer ? params.value + "%" : params.value;
}
......
......@@ -41,7 +41,7 @@
<el-table :data="InnovationRanking" stripe style="width: 100%;padding: 5px 25px;"
:header-cell-style="headerCellStyle">
<el-table-column prop="name" label="创新主体" width="100" />
<el-table-column prop="markValue" align="right">
<el-table-column prop="markValue" align="center">
<template #header>
<div class="custom-header">
<div class="label">市值</div>
......
......@@ -322,7 +322,16 @@ const totalDistribution = ref([
change: "较上月+8",
path: "/innovationSubject",
color: ["#C9AAF0", "#DFCAF6", "#FAF1FF", "#531DAC"]
}
},
{
titlle: "科技人物观点",
value: 58,
text: "51",
unit: "次",
change: "较上月+3",
path: "/technologyFigures",
color: ["#96DFDD", "#BCEFEC", "#E7FFFB", "#006E75"]
},
]);
const startIndex = ref(0);
......
......@@ -21,7 +21,7 @@
</div>
</template>
<div class="panel1Body">
<Echarts :option="mapOption" height="100%" @chart-ready="echarsReady"></Echarts>
<Echarts :option="mapOption" height="90%" @chart-ready="echarsReady"></Echarts>
<div class="countryWrap">
<div class="item" v-for="(item, index) in mapData" :key="index">
<img :src="item.flag" alt="" class="itemIcon" />
......@@ -54,7 +54,7 @@
</el-row>
<el-card class="gap">
<el-row>
<PieProgress v-for="item in List" :data="item" />
<PieProgress v-for="item,index in List" :key="index" :data="item" />
</el-row>
</el-card>
<el-row class="gap">
......@@ -159,7 +159,7 @@
<div class="itemCard2BigTextWrap" :style="{ color: item.bgColor }">
{{ item.title }}
</div>
<div class="itemCard2TextWrap" v-for="(itemText, inde) in item.list" :key="index">
<div class="itemCard2TextWrap" v-for="(itemText, index) in item.list" :key="index">
<div class="temCard2Title">{{ itemText.title }}</div>
<div class="temCard2Text">{{ itemText.text }}</div>
</div>
......@@ -1073,15 +1073,11 @@ function moreClick(n) {
position: relative;
height: 100%;
.countryWrap {
position: absolute;
bottom: 8px;
left: 0;
right: 0;
width: 782px;
width: 840px;
margin: 0 auto;
display: flex;
gap: 10px;
overflow-x: auto;
justify-content: space-between;
.item {
display: flex;
align-items: center;
......
......@@ -74,7 +74,7 @@ export function setChart(option, chartDom) {
chart.setOption(option);
return chart;
};
export function getMapOption(data,levelMap) {
export function getMapOption(data, levelMap) {
echarts.registerMap('world', worldJson);
function convertData(data) {
let res = [];
......@@ -144,7 +144,8 @@ export function getMapOption(data,levelMap) {
map: 'world',
roam: true,
// 地图尺寸为容器宽高较小值的80%
zoom: 1.5,
zoom: 1.15,
top: 0,
center: [31.614149450443932, 20.978078159827206],
// scaleLimit:{
// max:'1.2',
......
<!-- SourceLibrary.vue -->
<template>
<div class="source-library-container">
<div class="source-library-grid">
<div v-for="(item, index) in sourceLibraryData" :key="index" class="source-library-card">
<div class="source-library-avatar-wrapper">
<img :src="item.avatar" alt="" class="source-library-avatar" />
<div class="person-tags">
<div class="person-tag-bg" v-for="(tag, tIdx) in item.icon" :key="tIdx">
<img :src="'/public/icon/header-icon' + tag + '.png'" class="tag-icon" alt="tag" />
</div>
</div>
</div>
<div class="source-library-text-content">
<div style=" width: 240px;">
<h3 class="source-library-name">{{ item.name }}</h3>
<p class="source-library-title">{{ item.title }}</p>
<p class="source-library-tag" :style="{
background: item.colorArray[2],
color: item.colorArray[0],
borderColor: item.colorArray[1],
}">{{ item.tag }}</p>
</div>
</div>
</div>
</div>
<div class="page">
<div class="count">共1205项调查</div>
<el-pagination v-model:current-page="currentPage" :page-size="pageSize" :total="total" layout="prev, pager, next"
background @current-change="handlePageChange" />
</div>
</div>
<div class="source-library-container">
<div class="source-library-grid">
<div v-for="(item, index) in sourceLibraryData" :key="index" class="source-library-card">
<div class="source-library-avatar-wrapper">
<img :src="item.avatar" alt="" class="source-library-avatar" />
</div>
<div class="source-library-text-content">
<div style="width: 240px">
<h3 class="source-library-name">{{ item.name }}</h3>
<p class="source-library-title">{{ item.title }}</p>
<p
class="source-library-tag"
:style="{
background: item.colorArray[2],
color: item.colorArray[0],
borderColor: item.colorArray[1]
}"
>
{{ item.tag }}
</p>
</div>
</div>
</div>
</div>
<div class="page">
<div class="count">共1205项调查</div>
<el-pagination
v-model:current-page="currentPage"
:page-size="pageSize"
:total="total"
layout="prev, pager, next"
background
@current-change="handlePageChange"
/>
</div>
</div>
</template>
<script setup>
// 导入数据(建议使用更具语义的变量名)
import sourceLibraryData from '../json/source.json';
import { ref } from 'vue'
import sourceLibraryData from "../json/source.json";
import { ref } from "vue";
const total = ref(1205);
const pageSize = ref(121);
const currentPage = ref(5);
const handlePageChange = p => {
currentPage.value = p;
currentPage.value = p;
};
</script>
<style scoped>
<style lang="scss" scoped>
.source-library-container {
width: 1530px;
margin: 0;
width: 1530px;
margin: 0;
}
.source-library-grid {
width: 1600px;
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px 16px;
width: 1600px;
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 16px 16px;
}
.source-library-card {
width: 388px;
height: 160px;
box-sizing: border-box;
display: flex;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: var(---10, 10px);
padding: 20px 18px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
width: 388px;
height: 160px;
box-sizing: border-box;
display: flex;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: var(---10, 10px);
padding: 20px 18px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
background: rgba(255, 255, 255, 1);
}
.source-library-card:hover {
transform: translateY(-2px);
transform: translateY(-2px);
}
.source-library-avatar-wrapper {
flex-shrink: 0;
margin-right: 18px;
flex-shrink: 0;
margin-right: 18px;
}
.person-tags {
......@@ -106,144 +107,135 @@ const handlePageChange = p => {
}
.source-library-avatar {
/* 椭圆 142 */
width: 88px;
height: 88px;
border-radius: 50%;
/* 椭圆 142 */
width: 88px;
height: 88px;
border-radius: 50%;
}
.source-library-text-content {
width: 656px;
flex: 1;
width: 656px;
flex: 1;
}
.source-library-name {
color: rgba(59, 65, 75, 1);
margin: 0;
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
letter-spacing: 0px;
text-align: left;
color: rgba(59, 65, 75, 1);
margin: 0;
font-family: Microsoft YaHei;
font-size: 20px;
font-weight: 700;
line-height: 26px;
letter-spacing: 0px;
text-align: left;
}
.source-library-title {
width: 240px;
height: 48px;
color: rgba(59, 65, 75, 1);
margin: 11px 0 14px 0;
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
width: 240px;
height: 48px;
color: rgba(59, 65, 75, 1);
margin: 11px 0 14px 0;
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 400;
line-height: 24px;
letter-spacing: 0px;
text-align: left;
}
.source-library-tag {
/* width: 72px; */
height: 22px;
/* 自动布局 */
display: inline-block;
/* 关键:把块级盒子变成行内块 */
align-items: center;
padding: 1px 8px 1px 8px;
box-sizing: border-box;
border: 1px solid rgba(255, 229, 143, 1);
border-radius: 4px;
background: rgba(255, 251, 230, 1);
color: rgba(22, 119, 255, 1);
margin: 0;
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 20px;
letter-spacing: 0px;
text-align: left;
/* width: 72px; */
height: 22px;
/* 自动布局 */
display: inline-block;
/* 关键:把块级盒子变成行内块 */
align-items: center;
padding: 1px 8px 1px 8px;
box-sizing: border-box;
border: 1px solid rgba(255, 229, 143, 1);
border-radius: 4px;
background: rgba(255, 251, 230, 1);
color: rgba(22, 119, 255, 1);
margin: 0;
font-family: Microsoft YaHei;
font-size: 14px;
font-weight: 400;
line-height: 20px;
letter-spacing: 0px;
text-align: left;
}
.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;
}
/* width: 1221px; */
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;
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";
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);
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;
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;
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;
color: rgba(95, 101, 108, 0.45);
border-color: rgb(235, 238, 242);
background-color: #fff;
}
</style>
\ No newline at end of file
......@@ -18,7 +18,7 @@
<div class="search-text">搜索</div>
</div>
</div>
<div class="home-main-header-footer">
<!-- <div class="home-main-header-footer">
<div class="home-main-header-footer-item">
<div class="item-top">843</div>
<div class="item-footer">政府官员</div>
......@@ -35,7 +35,7 @@
<div class="item-top">312</div>
<div class="item-footer">国会议员</div>
</div>
</div>
</div> -->
<div class="home-main-header-btn-box">
<div class="btn" @click="scrollToTop('position1')">
<div class="btn-text">{{ "最新动态" }}</div>
......@@ -1202,7 +1202,7 @@ onMounted(() => {
}
.home-main-footer {
height: 1149px;
height: 1000px;
overflow: hidden;
.home-main-footer-header {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论