提交 6db3f5e1 authored 作者: 闫鹏's avatar 闫鹏

合并分支 'yp-dev' 到 'master'

Yp dev 查看合并请求 !46
......@@ -88,7 +88,7 @@ export function getIndustryCountByYear(sanTypeId) {
* domains: string[]
* }>}
*/
export function getCountDomainByYear(isRule, startYear = "2020", endYear = new Date().getFullYear()) {
export function getCountDomainByYear(isRule, startYear = "2020", endYear = String(new Date().getFullYear())) {
return request200(
request({
method: "POST",
......@@ -162,6 +162,30 @@ export function getOrganizationInfo(sanTypeId = 1) {
);
}
/**
* 风险信号
*/
export function getRiskSignal(moduleId = "0103") {
return request200(
request({
method: "GET",
url: `/api/commonFeature/riskSignal/${moduleId}`
})
);
}
/**
* 社交媒体
*/
export function getSocialMediaInfo(moduleId = "0103") {
return request200(
request({
method: "GET",
url: `/api/commonFeature/remarks/${moduleId}`
})
);
}
/**
* 查询重点人物
* @returns {Promise<{
......@@ -527,9 +551,10 @@ export function getCountSanTypeByTime(startTime) {
return request200(
request({
method: "GET",
url: "/api/entitiesDataCount/countSanTypeByTime",
// url: "/api/entitiesDataCount/countSanTypeByTime",
url: "/api/entitiesDataInfo/getTypeDistribution",
params: {
startTime
sanctionDate: startTime || "2025-11-11"
}
})
);
......
......@@ -62,5 +62,6 @@ function setActiveIndex(item) {
display: flex;
gap: 8px;
overflow-x: auto;
flex-wrap: wrap;
}
</style>
[
{
"yearDomainCount": [
{
"sanTypeName": null,
"year": 2020,
"domainCountInfo": [
{
"year": 2020,
"id": "1",
"name": "人工智能",
"count": 11
},
{
"year": 2020,
"id": "2",
"name": "生物科技",
"count": 2
},
{
"year": 2020,
"id": "3",
"name": "新一代信息技术",
"count": 13
},
{
"year": 2020,
"id": "4",
"name": "量子科技",
"count": 0
},
{
"year": 2020,
"id": "5",
"name": "新能源",
"count": 0
},
{
"year": 2020,
"id": "6",
"name": "集成电路",
"count": 1
},
{
"year": 2020,
"id": "7",
"name": "海洋",
"count": 47
},
{
"year": 2020,
"id": "8",
"name": "先进制造",
"count": 22
},
{
"year": 2020,
"id": "9",
"name": "新材料",
"count": 0
},
{
"year": 2020,
"id": "10",
"name": "航空航天",
"count": 18
},
{
"year": 2020,
"id": "99",
"name": "其他",
"count": 0
},
{
"year": 2020,
"id": "13",
"name": "太空",
"count": 0
},
{
"year": 2020,
"id": "11",
"name": "深海",
"count": 0
},
{
"year": 2020,
"id": "12",
"name": "极地",
"count": 0
},
{
"year": 2020,
"id": "14",
"name": "核",
"count": 10
}
]
},
{
"sanTypeName": null,
"year": 2021,
"domainCountInfo": [
{
"year": 2021,
"id": "1",
"name": "人工智能",
"count": 15
},
{
"year": 2021,
"id": "2",
"name": "生物科技",
"count": 12
},
{
"year": 2021,
"id": "3",
"name": "新一代信息技术",
"count": 5
},
{
"year": 2021,
"id": "4",
"name": "量子科技",
"count": 7
},
{
"year": 2021,
"id": "5",
"name": "新能源",
"count": 3
},
{
"year": 2021,
"id": "6",
"name": "集成电路",
"count": 22
},
{
"year": 2021,
"id": "7",
"name": "海洋",
"count": 5
},
{
"year": 2021,
"id": "8",
"name": "先进制造",
"count": 27
},
{
"year": 2021,
"id": "9",
"name": "新材料",
"count": 7
},
{
"year": 2021,
"id": "10",
"name": "航空航天",
"count": 4
},
{
"year": 2021,
"id": "99",
"name": "其他",
"count": 0
},
{
"year": 2021,
"id": "13",
"name": "太空",
"count": 0
},
{
"year": 2021,
"id": "11",
"name": "深海",
"count": 3
},
{
"year": 2021,
"id": "12",
"name": "极地",
"count": 0
},
{
"year": 2021,
"id": "14",
"name": "核",
"count": 3
}
]
},
{
"sanTypeName": null,
"year": 2022,
"domainCountInfo": [
{
"year": 2022,
"id": "1",
"name": "人工智能",
"count": 22
},
{
"year": 2022,
"id": "2",
"name": "生物科技",
"count": 0
},
{
"year": 2022,
"id": "3",
"name": "新一代信息技术",
"count": 2
},
{
"year": 2022,
"id": "4",
"name": "量子科技",
"count": 0
},
{
"year": 2022,
"id": "5",
"name": "新能源",
"count": 0
},
{
"year": 2022,
"id": "6",
"name": "集成电路",
"count": 33
},
{
"year": 2022,
"id": "7",
"name": "海洋",
"count": 7
},
{
"year": 2022,
"id": "8",
"name": "先进制造",
"count": 27
},
{
"year": 2022,
"id": "9",
"name": "新材料",
"count": 1
},
{
"year": 2022,
"id": "10",
"name": "航空航天",
"count": 12
},
{
"year": 2022,
"id": "99",
"name": "其他",
"count": 0
},
{
"year": 2022,
"id": "13",
"name": "太空",
"count": 0
},
{
"year": 2022,
"id": "11",
"name": "深海",
"count": 2
},
{
"year": 2022,
"id": "12",
"name": "极地",
"count": 0
},
{
"year": 2022,
"id": "14",
"name": "核",
"count": 0
}
]
},
{
"sanTypeName": null,
"year": 2023,
"domainCountInfo": [
{
"year": 2023,
"id": "1",
"name": "人工智能",
"count": 31
},
{
"year": 2023,
"id": "2",
"name": "生物科技",
"count": 5
},
{
"year": 2023,
"id": "3",
"name": "新一代信息技术",
"count": 3
},
{
"year": 2023,
"id": "4",
"name": "量子科技",
"count": 1
},
{
"year": 2023,
"id": "5",
"name": "新能源",
"count": 0
},
{
"year": 2023,
"id": "6",
"name": "集成电路",
"count": 82
},
{
"year": 2023,
"id": "7",
"name": "海洋",
"count": 7
},
{
"year": 2023,
"id": "8",
"name": "先进制造",
"count": 36
},
{
"year": 2023,
"id": "9",
"name": "新材料",
"count": 1
},
{
"year": 2023,
"id": "10",
"name": "航空航天",
"count": 55
},
{
"year": 2023,
"id": "99",
"name": "其他",
"count": 0
},
{
"year": 2023,
"id": "13",
"name": "太空",
"count": 1
},
{
"year": 2023,
"id": "11",
"name": "深海",
"count": 0
},
{
"year": 2023,
"id": "12",
"name": "极地",
"count": 0
},
{
"year": 2023,
"id": "14",
"name": "核",
"count": 7
}
]
},
{
"sanTypeName": null,
"year": 2024,
"domainCountInfo": [
{
"year": 2024,
"id": "1",
"name": "人工智能",
"count": 33
},
{
"year": 2024,
"id": "2",
"name": "生物科技",
"count": 0
},
{
"year": 2024,
"id": "3",
"name": "新一代信息技术",
"count": 10
},
{
"year": 2024,
"id": "4",
"name": "量子科技",
"count": 22
},
{
"year": 2024,
"id": "5",
"name": "新能源",
"count": 0
},
{
"year": 2024,
"id": "6",
"name": "集成电路",
"count": 190
},
{
"year": 2024,
"id": "7",
"name": "海洋",
"count": 0
},
{
"year": 2024,
"id": "8",
"name": "先进制造",
"count": 27
},
{
"year": 2024,
"id": "9",
"name": "新材料",
"count": 13
},
{
"year": 2024,
"id": "10",
"name": "航空航天",
"count": 29
},
{
"year": 2024,
"id": "99",
"name": "其他",
"count": 0
},
{
"year": 2024,
"id": "13",
"name": "太空",
"count": 0
},
{
"year": 2024,
"id": "11",
"name": "深海",
"count": 0
},
{
"year": 2024,
"id": "12",
"name": "极地",
"count": 0
},
{
"year": 2024,
"id": "14",
"name": "核",
"count": 2
}
]
},
{
"sanTypeName": null,
"year": 2025,
"domainCountInfo": [
{
"year": 2025,
"id": "1",
"name": "人工智能",
"count": 12
},
{
"year": 2025,
"id": "2",
"name": "生物科技",
"count": 0
},
{
"year": 2025,
"id": "3",
"name": "新一代信息技术",
"count": 11
},
{
"year": 2025,
"id": "4",
"name": "量子科技",
"count": 9
},
{
"year": 2025,
"id": "5",
"name": "新能源",
"count": 0
},
{
"year": 2025,
"id": "6",
"name": "集成电路",
"count": 35
},
{
"year": 2025,
"id": "7",
"name": "海洋",
"count": 0
},
{
"year": 2025,
"id": "8",
"name": "先进制造",
"count": 42
},
{
"year": 2025,
"id": "9",
"name": "新材料",
"count": 11
},
{
"year": 2025,
"id": "10",
"name": "航空航天",
"count": 26
},
{
"year": 2025,
"id": "99",
"name": "其他",
"count": 0
},
{
"year": 2025,
"id": "13",
"name": "太空",
"count": 1
},
{
"year": 2025,
"id": "11",
"name": "深海",
"count": 0
},
{
"year": 2025,
"id": "12",
"name": "极地",
"count": 0
},
{
"year": 2025,
"id": "14",
"name": "核",
"count": 1
}
]
}
],
"domians": [
{
"year": null,
"id": "1",
"name": "人工智能",
"count": null
},
{
"year": null,
"id": "2",
"name": "生物科技",
"count": null
},
{
"year": null,
"id": "3",
"name": "新一代信息技术",
"count": null
},
{
"year": null,
"id": "4",
"name": "量子科技",
"count": null
},
{
"year": null,
"id": "5",
"name": "新能源",
"count": null
},
{
"year": null,
"id": "6",
"name": "集成电路",
"count": null
},
{
"year": null,
"id": "7",
"name": "海洋",
"count": null
},
{
"year": null,
"id": "8",
"name": "先进制造",
"count": null
},
{
"year": null,
"id": "9",
"name": "新材料",
"count": null
},
{
"year": null,
"id": "10",
"name": "航空航天",
"count": null
},
{
"year": null,
"id": "99",
"name": "其他",
"count": null
},
{
"year": null,
"id": "13",
"name": "太空",
"count": null
},
{
"year": null,
"id": "11",
"name": "深海",
"count": null
},
{
"year": null,
"id": "12",
"name": "极地",
"count": null
},
{
"year": null,
"id": "14",
"name": "核",
"count": null
}
]
"personImage": "https://www.congress.gov/img/member/y000064_200.jpg",
"personName": "扬(Young, Todd)",
"remarks": "拜登打心底里厌恶美国的石油和天然气产业,他的一系列政策,正在摧毁这个能为美国创造大量就业岗位的重要领域。",
"time": "2025-04-12T03:27:07",
"orgName": "推特"
},
{
"personImage": "https://www.congress.gov/img/member/k000306_200.jpg",
"personName": "科尔贝 (Kolbe), 吉姆 (Jim)",
"remarks": "美国将控制加沙地带,我们会把这片被战火摧毁的区域改造成 “中东的里维埃拉”,这一计划会为当地带来全新未来。",
"time": "2025-01-12T00:55:53",
"orgName": "推特"
}
]
\ No newline at end of file
<template>
<div class="influencePanel2">
<CardCustom title="涉及行业" :style="{ width: '480px', height: '860px' }">
<CardCustom title="涉及行业" :style="{ width: '500px', height: '860px' }">
<div class="subPanel1">
<div class="chartsWrap">
<Echarts :option="horizontalBarOptions" height="100%"></Echarts>
......@@ -9,7 +9,7 @@
<ButtonList :list="buttonList" :active-id="activeButtonId" @click="setActiveButtonId"></ButtonList>
</div>
<div class="listWrap">
<div class="item" v-for="(item, index) in listData" :key="index">
<div class="item" v-for="(item, index) in listData" :key="index" @click="handleEttClick(item)">
<div class="index" :class="{ isTopTen: index < 10 }">{{ index + 1 }}</div>
<div class="name">{{ item.name }}</div>
<div class="icon" :class="{ iconUp: item.isUp, iconDown: !item.isUp }"></div>
......@@ -78,8 +78,9 @@ import ButtonList from "@/components/buttonList/buttonList.vue";
import Fishbone from "./fishbone.vue";
import { getHorizontalBarChart2 } from "../../utils/charts";
import { getDomainDistribution, getChainEntities } from "@/api/exportControl";
import { useRoute } from "vue-router";
import { useRoute, useRouter } from "vue-router";
const route = useRoute();
const router = useRouter();
const buttonList = ref([]);
const activeButtonId = ref(buttonList.value[0]?.id || 1);
const setActiveButtonId = id => {
......@@ -141,6 +142,15 @@ const listData = ref([
]);
const horizontalBarOptions = shallowRef({});
const handleEttClick = item => {
const route = router.resolve({
path: "/companyPages",
query: {
id: item.id
}
});
window.open(route.href, "_blank");
};
// 获取领域分布数据并更新图表
const fetchDomainDistribution = async () => {
try {
......@@ -181,6 +191,7 @@ const fetchChainEntities = async () => {
console.log("data data", data);
// 更新 listData
listData.value = data.map(item => ({
...item,
name: item.orgNameZh,
isUp: item.isUp
}));
......@@ -367,6 +378,8 @@ watch(() => activeButtonId.value, fetchChainEntities);
flex-direction: column;
.chartsWrap {
height: 200px;
display: flex;
// flex: 1;
border: 1px solid rgba(234, 236, 238, 1);
border-radius: 4px;
background: rgba(247, 248, 249, 1);
......
......@@ -63,7 +63,7 @@
<div class="subPanel4">
<div class="listWrap">
<div class="item" v-for="(item, index) in subPanel4" :key="index">
<div class="name">{{ item.name }}</div>
<div class="name" @click="handleOrgClick(item)">{{ item.name }}</div>
<div class="tags">
<div
class="tagItem"
......@@ -94,8 +94,9 @@ import { getBarChart, getLineChart } from "../../utils/charts";
import Hint from "./hint.vue";
import { getEntitiesChangeCount, getEntitiesGrowthTrend, getEntitiesUpdateCount, getKeyEntityList } from "@/api/exportControl";
import _ from "lodash";
import { useRoute } from "vue-router";
import { useRoute, useRouter } from "vue-router";
const route = useRoute();
const router = useRouter();
const line1Option = shallowRef({});
const bar2Option = shallowRef({});
......@@ -111,6 +112,7 @@ const fetchKeyEntityList = async (date = "2025-11-11", keyword = "") => {
const name = item.orgNameZh || item.orgName || "未知实体";
return {
...item,
name,
tags: item.domainList || []
};
......@@ -261,7 +263,7 @@ const typeOptions = [
}
];
const domainValue = ref(domainOptions[0].value);
const typeValue = ref(typeOptions[0].value);
const typeValue = ref(typeOptions[1].value);
const bar1Option = shallowRef({});
const bar1DataIsEmpty = ref(false);
watch(
......@@ -338,6 +340,17 @@ watch(
const handleDomainChange = async domain => {
await fetchKeyEntityList(route.query.startTime, value3.value, domain);
};
const handleOrgClick = item => {
console.log(item);
const route = router.resolve({
path: "/companyPages",
query: {
id: item.id
}
});
window.open(route.href, "_blank");
};
</script>
<style lang="scss" scoped>
......@@ -389,6 +402,7 @@ const handleDomainChange = async domain => {
overflow: hidden;
margin-right: 11px;
text-overflow: ellipsis;
cursor: pointer;
}
.tags {
display: flex;
......
......@@ -45,13 +45,13 @@
<div class="subPanel4">
<div class="listWrap">
<div class="item" v-for="(item, index) in subPanel4" :key="index">
<div class="name">{{ item.name }}</div>
<div class="name" @click="handleOrgClick(item)">{{ item.name }}</div>
<div class="infoWrap">
<div class="shizhi">{{ item.shizhi }}</div>
<div class="address">{{ item.address }}</div>
<div class="hangye">{{ item.hangye }}</div>
<div class="type">{{ item.type }}</div>
<div class="detail">查看详情</div>
<div class="detail" @click="handleOrgClick(item)">查看详情</div>
</div>
</div>
</div>
......@@ -73,8 +73,9 @@ import { getBarChart, getLineChart } from "../../utils/charts";
import _ from "lodash";
import Hint from "./hint.vue";
import { getEntityFinancing, getEntityMarketValue, getKeyListedEntityList, getSanStrength } from "@/api/exportControl";
import { useRoute } from "vue-router";
import { useRoute, useRouter } from "vue-router";
const route = useRoute();
const router = useRouter();
const options = [
{
value: "1",
......@@ -147,6 +148,7 @@ const fetchKeyListedEntityList = async (keyword = "") => {
const type = item.orgType || "企业";
return {
...item,
name,
shizhi: `市值:${marketValue}`,
address: `地址:${address}`,
......@@ -229,12 +231,12 @@ const fetchEntityMarketValue = async () => {
// 按日期排序
const sortedData = data
.sort((a, b) => {
return new Date(a.name) - new Date(b.name);
return new Date(a.year) - new Date(b.year);
})
.filter((item, idx) => idx % 3 === 0);
// 提取 x 轴数据(日期)
const xAxisData = sortedData.map(item => item.name);
const xAxisData = sortedData.map(item => item.year);
// 提取 y 轴数据(市值数据)
const seriesData = sortedData.map(item => item.count);
......@@ -258,12 +260,12 @@ const fetchSanStrength = async () => {
// 按日期排序
const sortedData = data
.sort((a, b) => {
return new Date(a.name) - new Date(b.name);
return new Date(a.year) - new Date(b.year);
})
.filter((item, idx) => idx % 3 === 0);
// 提取 x 轴数据(日期)
const xAxisData = sortedData.map(item => item.name);
const xAxisData = sortedData.map(item => item.year);
// 提取 y 轴数据(市值数据)
const seriesData = sortedData.map(item => item.count);
......@@ -310,6 +312,17 @@ watch(
await fetchKeyListedEntityList(newVal);
}, 300)
);
const handleOrgClick = item => {
console.log(item);
const route = router.resolve({
path: "/companyPages",
query: {
id: item.id
}
});
window.open(route.href, "_blank");
};
</script>
<style lang="scss" scoped>
......@@ -359,6 +372,7 @@ watch(
font-size: 16px;
font-weight: 400;
line-height: 24px;
cursor: pointer;
}
.infoWrap {
display: flex;
......
......@@ -19,7 +19,7 @@
</CardCustom>
</div>
<div class="row">
<CardCustom title="历制裁涉及领域数" :style="{ width: '798px', height: '422px' }">
<CardCustom title="历制裁涉及领域数" :style="{ width: '798px', height: '422px' }">
<div class="subPanel3">
<div class="chartsWrap" :style="{ paddingBottom: '10px' }">
<Echarts :option="bar2Option" height="100%"></Echarts>
......
<template>
<div class="panel4Wrap">
<div class="row">
<CardCustom title="新增实体领域分布情况" :style="{ width: '798px', height: '422px' }">
<CardCustom title="新增实体类别分布情况" :style="{ width: '798px', height: '422px' }">
<div class="subPanel1">
<div class="chartsWrap" :style="{ paddingBottom: '10px' }">
<Echarts :option="pie1Option" height="100%"></Echarts>
......@@ -66,7 +66,7 @@ onMounted(async () => {
pie1Option.value = getPieOption1(
_.map(countSanTypeByTimeData ?? [], item => {
return {
name: item?.type,
name: item?.name,
value: item?.count
};
})
......
......@@ -22,7 +22,7 @@
</CardCustom>
<CardCustom title="重点人物" :style="{ width: '600px', height: '284px' }">
<div class="panel2">
<div class="item" v-for="(item, index) in personLis" :key="index">
<div class="item" v-for="(item, index) in personLis" :key="index" @click="handlePerClick(item)">
<img :src="item.img" alt="" class="img" />
<div class="infoWrap">
<div class="name">{{ item.name }}</div>
......@@ -76,13 +76,13 @@
<CardCustom title="实体清单列表" :style="{ width: '984px', height: '678px' }">
<template #right>
<el-checkbox v-model="panel5IsChecked" label="只看中国实体" size="large" :style="{ marginRight: '15px' }" />
<ButtonList
<!-- <ButtonList
:list="panel5ButtonList"
:gap="8"
:active-id="panel5ButtonAcitveID"
@click="panel5SetButtonAcitveID"
:style="{ marginRight: '15px' }"
></ButtonList>
></ButtonList> -->
</template>
<div class="panel5">
<div class="hintWrap">
......@@ -105,7 +105,7 @@
>
<el-table-column prop="name" label="实体清单" min-width="180">
<template #default="{ row }">
<div style="font-weight: 500" class="name">
<div style="font-weight: 500" class="name" @click="handleOrgClick(row)">
<img v-if="row.img" :src="row.img" alt="" class="img" />
<div v-else class="imgUndefined">
{{ row.name?.match(/[\u4e00-\u9fa5a-zA-Z0-9]/)?.[0] }}
......@@ -131,7 +131,7 @@
</template>
</el-table-column> -->
<el-table-column prop="time" label="制裁时间" width="120" align="center">
<el-table-column prop="time" label="制裁时间" width="150" align="center">
<template #default="{ row }">
{{ row.time }}
</template>
......@@ -143,7 +143,7 @@
</template>
</el-table-column> -->
<el-table-column prop="subCompany" label="50%规则子企业" min-width="140" align="left">
<el-table-column prop="subCompany" label="50%规则子企业" min-width="140" align="center">
<template #default="{ row }">
<span class="subCompany">
{{ row.subCompany }}
......@@ -206,9 +206,10 @@ import {
} from "@/api/exportControl";
import _ from "lodash";
import { useRoute } from "vue-router";
import { useRoute, useRouter } from "vue-router";
import { formatAnyDateToChinese } from "../../utils";
const route = useRoute();
const router = useRouter();
const organizationInfo = shallowRef({});
const personLis = shallowRef([
// {
......@@ -254,6 +255,17 @@ const sanReasonSelect = shallowRef([
}
]);
const handlePerClick = item => {
console.log(item);
const route = router.resolve({
path: "/characterPage",
query: {
type: item.type || [1, 2, 3][Math.floor(Math.random() * 3)]
}
});
window.open(route.href, "_blank");
};
const panel5IsChecked = ref(true);
const selectEntitiesList = shallowRef([]);
......@@ -285,7 +297,7 @@ onMounted(async () => {
enName: item.enName,
position: item.position,
party: item.party,
img: item.avatarUrl
img: item.imageUrl
};
});
sanReasonSelect.value = _.map(sanReasonSelectData, item => {
......@@ -509,6 +521,16 @@ const panel6 = ref([
desc: '美国将对华关税从34%提升至84%(总税率104%),中方同步对美商品加征同等税率,并暂停进口美国影片、限制留学合作。特朗普政府通过"基准关税+对等关税+额外加征"策略施压,引发全球供应链震荡。'
}
]);
const handleOrgClick = item => {
console.log(item);
const route = router.resolve({
path: "/companyPages",
query: {
id: item.id
}
});
window.open(route.href, "_blank");
};
</script>
<style lang="scss" scoped>
......@@ -585,6 +607,7 @@ const panel6 = ref([
background: rgba(231, 243, 255, 0.5);
display: flex;
align-items: center;
cursor: pointer;
.img {
width: 70px;
height: 70px;
......@@ -769,6 +792,7 @@ const panel6 = ref([
.name {
display: flex;
align-items: center;
cursor: pointer;
.img {
width: 40px;
height: 40px;
......
<template>
<div class="message-bubble">
<div class="avatar-container">
<div class="avatar-container" @click="handleClick">
<img :src="avatar" :alt="name" class="avatar" />
</div>
<div class="bubble-container">
......@@ -9,7 +9,7 @@
<span class="name">{{ name }}</span>
<span class="meta">{{ time }} · {{ source }}</span>
</div>
<div class="bubble-content">
<div class="bubble-content" @click="handleInfoClick">
{{ content }}
</div>
<div class="triangle"></div>
......@@ -19,6 +19,7 @@
</template>
<script setup>
const emit = defineEmits(["click"]);
defineProps({
avatar: {
type: String,
......@@ -42,6 +43,13 @@ defineProps({
"埃隆·马斯克在强力支持我竞选总统之前,早就知道我强烈反对‘电动汽车强制令’。这太荒谬了,这一直是我竞选活动的主要部分。电动汽车没问题,但不应该强迫每个人都拥有一辆。埃隆获得的补贴可能远远超过历史上任何一个人。如果没有补贴,埃隆可能不得不关门大吉,回到南非老家。"
}
});
const handleClick = () => {
emit("click");
};
const handleInfoClick = () => {
emit("info-click");
};
</script>
<style scoped>
......@@ -54,6 +62,8 @@ defineProps({
.avatar-container {
flex-shrink: 0;
flex-grow: 0;
flex: 0;
margin-right: 12px;
}
......
......@@ -135,6 +135,7 @@
class="box1-bottom-content-item"
v-for="(ett, index) in item.sanEntities"
:key="index"
@click="handleEntityClick(ett)"
>
<el-image
v-if="ett.img"
......@@ -228,6 +229,17 @@
<custom-container title="社交媒体" :titleIcon="dialogIcon" height="450px">
<template #default>
<div class="dialog-list">
<MessageBubble
v-for="(item, index) in socialMediaList"
@click="handlePerClick(item)"
@info-click="handleInfoClick(item)"
:key="index"
:avatar="item.avatar"
:name="item.name"
:time="item.time"
:source="item.source"
:content="item.content"
/>
<!-- <MessageBubble
:avatar="customMessage.avatar"
:name="customMessage.name"
......@@ -235,7 +247,8 @@
:source="customMessage.source"
:content="customMessage.content"
/> -->
<MessageBubble
<!-- <MessageBubble
@click="handlePerClick(item)"
:avatar="trumpAvatar"
name="唐纳德·特朗普"
time="16:02"
......@@ -257,7 +270,7 @@
time="16:02"
source="发布于真实社交"
content="提出特朗普政府的AI政策强调技术开放与快速应用,但可能以牺牲安全防范为代价,开启了“潘多拉魔盒”。"
/>
/> -->
</div>
</template>
</custom-container>
......@@ -273,8 +286,8 @@
<div class="box3-content">
<div class="box3-content-title">实体清单发布频度</div>
<el-table :data="tableData1" stripe style="width: 100%">
<el-table-column prop="year" label="年份" width="100" />
<el-table-column label="发布次数" width="180">
<el-table-column prop="year" label="年份" width="150" />
<el-table-column label="发布次数" width="200">
<template #default="scope">
<div style="display: flex; align-items: center">
<span style="margin-right: 10px; width: 40px">{{ scope.row.num }}</span>
......@@ -286,7 +299,7 @@
</div>
</template>
</el-table-column>
<el-table-column label="重点领域" width="180" align="center">
<el-table-column label="重点领域" width="280" align="center">
<template #default="scope">
<div
style="display: flex; justify-content: center; align-items: center; gap: 5px"
......@@ -309,8 +322,8 @@
<div class="box3-content">
<div class="box3-content-title">商业管制清单(CCL)更新频度</div>
<el-table :data="tableData1" stripe style="width: 100%">
<el-table-column prop="year" label="年份" width="100" />
<el-table-column label="发布次数" width="180">
<el-table-column prop="year" label="年份" width="150" />
<el-table-column label="发布次数" width="200">
<template #default="scope">
<div style="display: flex; align-items: center">
<span style="margin-right: 10px; width: 40px">{{ scope.row.num }}</span>
......@@ -322,7 +335,7 @@
</div>
</template>
</el-table-column>
<el-table-column label="重点领域" width="180" align="center">
<el-table-column label="重点领域" width="280" align="center">
<template #default="scope">
<div
style="display: flex; justify-content: center; align-items: center; gap: 5px"
......@@ -419,7 +432,9 @@
</div>
<div class="box4-item-right">
<div class="box4-item-right-header" @click="handleSanc(item)">
<span class="box4-item-right-header-title">{{ item.title }}</span>
<span class="box4-item-right-header-title"
>{{ item.postDate }}{{ item.title }}</span
>
<span class="box4-item-right-header-desc">{{ item.desc }}</span>
</div>
<div class="box4-item-right-content">
......@@ -523,7 +538,7 @@
<el-table-column prop="revenue" label="50%规则子企业" width="280" align="right">
<template #default="scope">
<div class="num-item">
<div class="num-item" v-if="scope.row.ruleOrgCount > 0">
<div
class="name-item"
:class="[
......@@ -531,9 +546,14 @@
scope.row.revenue === '无营收数据' ? 'no-revenue' : ''
]"
>
{{ scope.row.name }}...等
{{ scope.row.ruleOrgList[0].orgName }}...等
</div>
<div
style="width: 50px; color: #409eff; cursor: pointer"
@click="handleOrgClick(scope.row)"
>
{{ scope.row.ruleOrgCount }}家>
</div>
<div style="width: 50px; color: #409eff">{{ scope.row.ruleOrgCount }}家></div>
</div>
</template>
</el-table-column>
......@@ -559,6 +579,33 @@
</el-col>
</el-row>
</div>
<el-dialog v-model="dialogVisible" width="800" :before-close="handleClose">
<template #title>
<div class="dialog-title">50%规则子企业</div>
</template>
<div class="dialog-ett-wrpper">
<div
class="box1-bottom-content-item"
v-for="(ett, index) in currentOrgList"
:key="index"
@click="handleEntityClick(ett)"
>
<el-image v-if="ett.img" class="box1-bottom-content-item-img" :src="ett.img" alt=""></el-image>
<div v-else class="box1-bottom-content-item-imgUndefined">
{{ (ett.orgName || ett.enName)?.match(/[\u4e00-\u9fa5a-zA-Z0-9]/)?.[0] }}
</div>
<div class="box1-bottom-content-item-txt">
{{ ett.orgName || ett.orgNameZh }}
</div>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="dialogVisible = false"> 确定 </el-button>
</div>
</template>
</el-dialog>
</div>
</template>
......@@ -567,6 +614,8 @@ import { onMounted, ref, computed, reactive, shallowRef, watch } from "vue";
import scrollToTop from "@/utils/scrollToTop";
import * as echarts from "echarts";
import setChart from "@/utils/setChart";
import { ElMessage, ElMessageBox } from "element-plus";
import { DArrowRight, Warning, Search } from "@element-plus/icons-vue";
// import router from "@/router/index";
import EChart from "@/components/Chart/index.vue";
......@@ -631,7 +680,9 @@ import {
getSanctionsInfoCount,
getEntitiesList,
getSanctionProcess,
getSanDomainCount
getSanDomainCount,
getRiskSignal,
getSocialMediaInfo
} from "@/api/exportControl";
import { getMultipleBarChart_m } from "./utils/charts";
import { formatAnyDateToChinese } from "./utils";
......@@ -662,6 +713,10 @@ const sanctionProcessList = ref([]);
const sanctionPage = ref(1);
// 制裁实体清单
const entitiesList = ref([]);
// 风险信号
const riskSignalList = ref([]);
// 社交媒体信息
const socialMediaList = ref([]);
onMounted(async () => {
try {
......@@ -671,7 +726,10 @@ onMounted(async () => {
getIndustryCountByYear(1),
getCountDomainByYear(trendChecked.value)
]);
// 交换第二个和第三个元素
[dataCount[1], dataCount[2]] = [dataCount[2], dataCount[1]];
infoList.value = dataCount;
const entityList = _.map(entitiesDataInfo?.sanEntities ?? [], ({ entityNameZh, entityName }) => {
return { name: entityNameZh, enName: entityName };
});
......@@ -701,6 +759,9 @@ onMounted(async () => {
// "2025年3月25日,美国商务部工业与安全局以从事有悖于美国国家安全和外交政策利益的活动为由,宣布将来自中国的54家实体新增至“实体清单”。"
// };
// });
await fetchRiskSignals("0103");
// 获取社交媒体信息
await fetchSocialMediaInfo();
await fetchEntitiesList(currentPage.value, pageSize.value);
await fetchSanctionProcess(sanctionPage.value, 10);
// 获取雷达图数据
......@@ -773,6 +834,18 @@ watch(
}
);
const handleEntityClick = item => {
console.log("item", item);
const route = router.resolve({
path: "/companyPages",
query: {
startTime: item.startTime,
id: item.id
}
});
window.open(route.href, "_blank");
};
// 返回首页
const handleBackHome = () => {
router.push({
......@@ -808,41 +881,6 @@ const searchKey = ref("");
const infoListColor = ref(["rgba(206, 79, 81, 1)", "rgba(132, 136, 142, 1)", "rgba(132, 136, 142, 1)", "rgba(132, 136, 142, 1)"]);
const infoList = ref([]);
const entityList = ref([
{
name: "北京复旦微电子技术有限公司",
img: fudanIcon
},
{
name: "北京福康微电子技术有限公司",
img: fukongIcon
},
{
name: "北京华岭微电子技术有限公司",
img: hualingIcon
},
{
name: "北京吉姆微芯科技有限公司",
img: jimuxiIcon
},
{
name: "北京盛工微电子技术有限公司",
img: shenggongIcon
},
{
name: "北京首时微电子技术有限公司",
img: shoushiIcon
},
{
name: "北京天易微电子技术有限公司",
img: tianyiIcon
},
{
name: "北京航空航天大学微电子技术研究院",
img: aircasIcon
}
]);
const customNewsData = ref([
{
image: newsImg,
......@@ -1104,142 +1142,75 @@ const strengthLabels = {
weak: "弱",
none: "无"
};
// 模拟数据
// const mockData = [
// {
// name: "科大讯飞股份有限公司",
// domains: ["人工智能"],
// sanctionDate: "2025年9月",
// strength: "strong",
// revenue: "325"
// },
// {
// name: "华为技术有限公司",
// domains: ["通信网络", "集成电路"],
// sanctionDate: "2025年9月",
// strength: "medium",
// revenue: "290"
// },
// {
// name: "中国航空工业集团",
// domains: ["航空航天"],
// sanctionDate: "2025年9月",
// strength: "medium",
// revenue: "288"
// },
// {
// name: "杭州海康威视数字技术股份有限公司",
// domains: ["人工智能"],
// sanctionDate: "2025年9月",
// strength: "weak",
// revenue: "203"
// },
// {
// name: "浪潮集团有限公司",
// domains: ["人工智能"],
// sanctionDate: "2025年9月",
// strength: "medium",
// revenue: "195"
// },
// {
// name: "中芯国际集成电路制造有限公司",
// domains: ["集成电路"],
// sanctionDate: "2025年9月",
// strength: "medium",
// revenue: "190"
// },
// {
// name: "北京复旦微电子技术有限公司",
// domains: ["集成电路"],
// sanctionDate: "2025年9月",
// strength: "medium",
// revenue: "184"
// },
// {
// name: "哈尔滨工业大学",
// domains: ["人工智能", "集成电路"],
// sanctionDate: "2025年9月",
// strength: "medium",
// revenue: "无营收数据"
// },
// {
// name: "ZTE中兴",
// domains: ["通信网络", "集成电路"],
// sanctionDate: "2025年9月",
// strength: "medium",
// revenue: "154"
// },
// {
// name: "中兴通讯股份有限公司",
// domains: ["通信网络", "集成电路"],
// sanctionDate: "2025年9月",
// strength: "medium",
// revenue: "117"
// },
// {
// name: "大疆创新科技有限公司",
// domains: ["航空航天"],
// sanctionDate: "2025年9月",
// strength: "medium",
// revenue: "1"
// }
// ];
// 生成更多数据以模拟1329家实体
// const generateMoreData = () => {
// const moreData = [];
// const companySuffixes = ["有限公司", "集团", "股份有限公司", "技术有限公司", "研究所"];
// const domainsList = [
// ["人工智能"],
// ["通信网络"],
// ["航空航天"],
// ["集成电路"],
// ["人工智能", "集成电路"],
// ["通信网络", "集成电路"],
// ["航空航天", "人工智能"]
// ];
// const strengths = ["strong", "medium", "weak"];
// for (let i = 0; i < 1318; i++) {
// const nameSuffix = companySuffixes[Math.floor(Math.random() * companySuffixes.length)];
// const companyName = `实体${i + 12}${nameSuffix}`;
// const domains = domainsList[Math.floor(Math.random() * domainsList.length)];
// const strength = strengths[Math.floor(Math.random() * strengths.length)];
// const revenue = Math.floor(Math.random() * 400) + 1;
// moreData.push({
// name: companyName,
// domains: domains,
// sanctionDate: "2025年9月",
// strength: strength,
// revenue: revenue.toString()
// });
// }
// return moreData;
// };
// const allData = [...mockData, ...generateMoreData()];
// 计算属性
// const total = computed(() => allData.length);
// const totalPages = computed(() => Math.ceil(total.value / pageSize.value));
// const filteredData = computed(() => {
// if (!searchKeyword.value) return allData;
// const keyword = searchKeyword.value.toLowerCase();
// return allData.filter(
// item => item.name.toLowerCase().includes(keyword) || item.domains.some(domain => domain.toLowerCase().includes(keyword))
// );
// });
// const paginatedData = computed(() => {
// const start = (currentPage.value - 1) * pageSize.value;
// const end = start + pageSize.value;
// return filteredData.value.slice(start, end);
// });
// 获取风险信号数据
const fetchRiskSignals = async () => {
try {
const data = await getRiskSignal();
if (data && Array.isArray(data)) {
warningList.value = data.map(item => ({
...item,
title: item.signalTitle,
time: item.signalTime,
status: item.signalLevel,
id: item.signalId
}));
}
} catch (err) {
console.error("获取风险信号数据失败:", err);
}
};
// 添加获取社交媒体信息的方法
const fetchSocialMediaInfo = async () => {
try {
const data = await getSocialMediaInfo();
if (data && Array.isArray(data)) {
socialMediaList.value = data.map(item => ({
avatar: item.personImage,
name: item.personName,
time: formatTime(item.time),
source: item.orgName,
content: item.remarks
}));
}
} catch (err) {
console.error("获取社交媒体信息失败:", err);
}
};
const handlePerClick = item => {
console.log("点击了社交媒体消息:", item);
const route = router.resolve({
path: "/characterPage",
query: {
type: item.type || [1, 2, 3][Math.floor(Math.random() * 3)]
}
});
window.open(route.href, "_blank");
};
// 处理点击社交媒体消息的方法
const handleInfoClick = item => {
console.log("点击了社交媒体消息的更多信息:", item);
// 这里可以添加打开详情页的逻辑
ElMessageBox.alert(`${item.content}`, "信息详情", {
confirmButtonText: "确定",
callback: action => {
ElMessage({
type: "info",
message: `action: ${action}`
});
}
});
};
// 添加格式化时间的方法
const formatTime = dateString => {
const date = new Date(dateString);
const hours = date.getHours().toString().padStart(2, "0");
const minutes = date.getMinutes().toString().padStart(2, "0");
return `${hours}:${minutes}`;
};
const warningList = ref([
{
......@@ -1269,57 +1240,6 @@ const warningList = ref([
}
]);
const timelineList = ref([
{
title: "成为公法 No: 119-21。",
time: "2025-07-04",
status: 1
},
{
title: "总统签署",
time: "2025-07-04",
status: 0
},
{
title: "提交总统",
time: "2025-07-03",
status: 0
},
{
title: "重新审议动议搁置案无异议通过。",
time: "2025-07-03 14:31",
status: 0
},
{
title: "关于‘众议院同意参议院修正案’...",
time: "2025-07-02 14:31",
status: 0
}
]);
const areaList = ref([
{
name: "跨境电商",
status: 2
},
{
name: "新能源产业",
status: 4
},
{
name: "半导体产业",
status: 1
},
{
name: "关税",
status: 3
},
{
name: "光伏产业",
status: 2
}
]);
const curBillList = ref([
{
billName: "大而美法案",
......@@ -1385,42 +1305,7 @@ const curBillList = ref([
const releaseTime = ref("近一年发布");
const releaseTimeList = ref([
{
label: "近半年发布",
value: "近半年发布"
},
{
label: "近一年发布",
value: "近一年发布"
},
{
label: "近两年发布",
value: "近两年发布"
},
{
label: "近三年发布",
value: "近三年发布"
},
{
label: "近五年发布",
value: "近五年发布"
}
]);
const categoryList = ref([
// "全部分类",
// "生物科技",
// "集成电路",
// "通信网络",
// "量子科技",
// "新能源",
// "新一代信息技术",
// "海洋",
// "先进制造",
// "新材料",
// "航空航天",
]);
const categoryList = ref([]);
const activeCate = ref("全部分类");
const activeHylyId = ref("");
......@@ -1526,6 +1411,17 @@ onMounted(async () => {
let chart1 = getMultiLineChart(chart1Data.value.title, chart1Data.value.data[0].value, chart1Data.value.data[1].value);
setChart(chart1, "chart1");
});
const dialogVisible = ref(false);
const currentOrgList = ref([]);
const handleClose = () => {
dialogVisible.value = false;
};
const handleOrgClick = item => {
console.log(item, item.name);
currentOrgList.value = item.ruleOrgList;
dialogVisible.value = true;
};
</script>
<style lang="scss" scoped>
......@@ -1642,6 +1538,7 @@ onMounted(async () => {
// margin-bottom: 6px;
box-sizing: border-box;
gap: 10px;
cursor: pointer;
&-img {
width: 24px;
height: 24px;
......@@ -1751,7 +1648,7 @@ onMounted(async () => {
.text {
font-family: Microsoft YaHei;
line-height: 47px;
width: 80%;
width: 260px;
font-size: 16px;
font-weight: 400;
color: rgba(59, 65, 75, 1);
......@@ -1805,14 +1702,14 @@ onMounted(async () => {
.box3 {
display: flex;
// justify-content: space-between;
align-items: flex-start;
gap: 60px;
justify-content: center;
// align-items: flex-start;
gap: 100px;
.box3-content-title {
font-size: 18px;
font-weight: 700;
font-family: Microsoft YaHei;
width: 470px;
width: 640px;
height: 36px;
display: flex;
align-items: center;
......@@ -1822,6 +1719,7 @@ onMounted(async () => {
margin-bottom: 15px;
}
.box3-content {
// flex: 1;
.el-progress--line {
width: 82px;
}
......@@ -2620,6 +2518,7 @@ onMounted(async () => {
align-items: center;
gap: 10px;
cursor: pointer;
.box1-bottom-content-item-imgUndefined {
width: 24px;
height: 24px;
......@@ -2644,6 +2543,61 @@ onMounted(async () => {
white-space: nowrap;
}
}
.dialog-title {
text-align: center;
font-size: 24px;
font-weight: 700;
font-family: $base-font-family;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}
.dialog-ett-wrpper {
display: flex;
flex-wrap: wrap;
gap: 10px;
height: 500px;
.box1-bottom-content {
display: flex;
gap: 15px;
flex-wrap: wrap;
justify-content: space-between;
padding-left: 10px;
height: 156px;
overflow: auto;
&-item {
display: flex;
// align-items: center;
justify-content: flex-start;
width: 48%; /* 留出2%的间距 */
// margin-bottom: 6px;
box-sizing: border-box;
gap: 10px;
cursor: pointer;
&-img {
width: 24px;
height: 24px;
flex-shrink: 0;
}
&-imgUndefined {
width: 24px;
height: 24px;
font-size: 14px;
font-weight: 700;
flex-shrink: 0;
color: rgba(5, 95, 194, 1);
background-color: rgb(236, 245, 255);
line-height: 24px;
text-align: center;
border-radius: 12px;
}
&-txt {
font-size: 16px;
font-weight: 400;
color: rgba(95, 101, 108, 1);
}
}
}
}
:deep(.el-input__wrapper) {
box-shadow: none;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论