提交 5fc86ad6 authored 作者: yanpeng's avatar yanpeng

exportControl api

上级 a3bb0583
......@@ -4,6 +4,7 @@ import { ElMessage } from "element-plus";
const request200 = requestP => {
return requestP.then(data => {
if (data.code === 200) {
console.log('返回的数据结构 =>', data.data)
return data.data;
}
ElMessage({
......@@ -122,13 +123,14 @@ export function getSanctionsInfoCount() {
* sanReason: string
* }[]>}
*/
export function getSanctionProcess(typeName = "实体清单", pageNum = 1, pageSize = 10, isCn = false) {
export function getSanctionProcess(sanTypeIds = "1", pageNum = 1, pageSize = 10, isCn = false) {
return request200(
request({
method: "POST",
url: "/api/entitiesDataCount/getSanctionProcess",
data: {
typeName,
sanTypeIds,
// typeName: tabMap[sanTypeId],
pageNum,
pageSize,
isCn
......
import request from "@/api/request.js";
// 实体清单-制裁概况-获取实体清单基本信息
export function getEntityInfo(sanType) {
export function getEntityInfo(id) {
return request({
method: "GET",
url: `/api/sanctionList/baseInfo/${sanType}`
url: `/api/sanctionList/baseInfoById/${id}`
});
}
......@@ -98,10 +98,10 @@ export function get50PercentEntityCount(data) {
}
// 实体清单-数据统计-总量统计
export function getTotalCount() {
export function getTotalCount(id) {
return request({
method: "GET",
url: `/api/sanctionList/statistics/el/total`
url: `/api/sanctionList/statistics/total?sanTypeId=${id}`
});
}
......@@ -113,7 +113,7 @@ export function getTotalCount() {
export function getSanctionCountChange(params) {
return request({
method: "GET",
url: `/api/sanctionList/statistics/el/num`,
url: `/api/sanctionList/statistics/num`,
params
});
}
......@@ -128,7 +128,7 @@ export function getSanctionCountChange(params) {
export function getRegionCount(params) {
return request({
method: "GET",
url: `/api/sanctionList/statistics/el/region`,
url: `/api/sanctionList/statistics/region`,
params
});
}
......@@ -143,7 +143,7 @@ export function getRegionCount(params) {
export function getTechDomainCount(params) {
return request({
method: "GET",
url: `/api/sanctionList/statistics/el/domain`,
url: `/api/sanctionList/statistics/domain`,
params
});
}
......@@ -158,7 +158,7 @@ export function getTechDomainCount(params) {
export function getEntityTypeCount(params) {
return request({
method: "GET",
url: `/api/sanctionList/statistics/el/entityType`,
url: `/api/sanctionList/statistics/entityType`,
params
});
}
......@@ -247,7 +247,7 @@ export function getSingleSanctionOverview(params) {
export function getSingleSanctionEntityCountry(params) {
return request({
method: "GET",
url: `/api/sanctionList/statistics/el/countryRegion`,
url: `/api/sanctionList/statistics/countryRegion`,
params
});
}
......@@ -292,11 +292,10 @@ export function getSingleSanctionOverviewList(data) {
* @param {string} params.sanRecordId - 制裁记录ID
* @header token
*/
export function getSingleSanctionTotalCount(params) {
export function getSingleSanctionTotalCount(id) {
return request({
method: "GET",
url: `/api/sanctionList/statistics/el/total`,
params
url: `/api/sanctionList/statistics/total?sanTypeId=${id}`,
});
}
......@@ -311,7 +310,7 @@ export function getSingleSanctionTotalCount(params) {
export function getSingleSanctionDomainCount(params) {
return request({
method: "GET",
url: `/api/sanctionList/statistics/el/domain`,
url: `/api/sanctionList/statistics/domain`,
params
});
}
......@@ -327,7 +326,7 @@ export function getSingleSanctionDomainCount(params) {
export function getSingleSanctionEntityTypeCount(params) {
return request({
method: "GET",
url: `/api/sanctionList/statistics/el/entityType`,
url: `/api/sanctionList/statistics/entityType`,
params
});
}
......@@ -341,7 +340,7 @@ export function getSingleSanctionEntityTypeCount(params) {
export function getSingleSanctionEntityCountryCount(params) {
return request({
method: "GET",
url: `/api/sanctionList/statistics/el/countryRegion`,
url: `/api/sanctionList/statistics/countryRegion`,
params
});
}
......@@ -357,7 +356,7 @@ export function getSingleSanctionEntityCountryCount(params) {
export function getSingleSanctionEntityRegionCount(params) {
return request({
method: "GET",
url: `/api/sanctionList/statistics/el/region`,
url: `/api/sanctionList/statistics/region`,
params
});
}
......
......@@ -135,8 +135,8 @@ const headerTitleClasses = computed(() => [
.header-icon {
width: 22px;
height: 18px;
margin-left: 5px;
margin-right: 14px;
margin-left: 0px;
margin-right: 10px;
}
.blue-title-block {
......@@ -155,6 +155,7 @@ const headerTitleClasses = computed(() => [
/* color: var(--base-color); */
color: $base-color;
line-height: 48px;
padding: 0 5px;
// padding: 0 12px;
}
......
......@@ -403,7 +403,7 @@
v-for="tab in resourceTabs"
:key="tab.value"
class="resource-tab-item"
:class="{ active: activeResourceTab === tab.value, disabled: tab.disabled }"
:class="{ active: activeResourceTab == tab.value, disabled: tab.disabled }"
@click="handleResourceTabClick(tab)"
>
{{ tab.label }}
......@@ -856,7 +856,8 @@ const handleTitleClick = item => {
const route = router.resolve({
path: "/exportControl/singleSanction",
query: {
id: item.id
id: item.id,
sanTypeId: item.sanTypeId
}
});
window.open(route.href, "_blank");
......@@ -869,7 +870,8 @@ const handleCompClick = item => {
const route = router.resolve({
name: "companyPages",
params: {
id: item.id
id: item.id,
sanTypeId: item.sanTypeId
}
});
window.open(route.href, "_blank");
......@@ -938,7 +940,15 @@ onMounted(async () => {
// 交换第二个和第三个元素
[dataCount[1], dataCount[2]] = [dataCount[2], dataCount[1]];
infoList.value = dataCount.slice(0, 2);
allSanTypeIds.value = infoList.value.map(item => item.id);
resourceTabs.value = infoList.value.map(item => ({
label: item.nameZh,
value: tabMap[item.id],
id: [item.id],
disabled: item.id == "13" // 商业管制清单不展示
}));
resourceTabs.value.unshift({ label: "全部制裁", value: "all", id: "", disabled: false });
console.log("返回的数据结构 infoList =》", infoList.value);
const entityList = _.map(entitiesDataInfo?.sanEntities ?? [], ({ entityNameZh, entityName }) => {
return { name: entityNameZh, enName: entityName };
});
......@@ -1123,15 +1133,22 @@ const handleToEntityList = item => {
// 跳转到V2.0实体清单无ID
const handleToEntityListNoId = item => {
console.log("这是什么数据 =>", item);
if (item.nameZh == "实体清单") {
const routeData = router.resolve({
path: "/exportControl/entityList"
path: "/exportControl/entityList",
query: {
sanTypeId: item.id
}
});
// 打开一个新页面
window.open(routeData.href, "_blank");
} else if (item.nameZh == "商业管制清单") {
const routeData = router.resolve({
path: "/exportControl/commercialControlList"
path: "/exportControl/commercialControlList",
query: {
sanTypeId: item.id
}
});
// 打开一个新页面
window.open(routeData.href, "_blank");
......@@ -1146,6 +1163,7 @@ const curBillListIndex = ref(0);
const searchExportControlText = ref("");
const infoListColor = ref(["rgba(206, 79, 81, 1)", "rgba(114, 46, 209, 1)", "rgba(132, 136, 142, 1)", "rgba(132, 136, 142, 1)"]);
const infoList = ref([]);
const allSanTypeIds = ref(["1", "13"]);
// 雷达图
const domainChecked = ref(false);
......@@ -1324,7 +1342,8 @@ const fetchSanctionList = async () => {
techDomainIds: techDomains,
years: years,
isCn: false,
typeName: "实体清单"
// typeName: "实体清单"
sanTypeIds: allSanTypeIds.value
};
const res = await getExportControlList(params);
......@@ -1454,7 +1473,8 @@ const fetchEntitiesList = async (page = 1, size = 10) => {
const handleGetMore = async () => {
sanctionPage.value++;
try {
const res = await getSanctionProcess("实体清单", sanctionPage.value, 10);
const sanTypeid = activeResourceTabItem.value.id ? activeResourceTabItem.value.id : allSanTypeIds.value;
const res = await getSanctionProcess(sanTypeid, sanctionPage.value, 10);
if (res && res.content) {
// 将新数据合并到现有列表中
const newData = res.content.map(item => ({
......@@ -1479,7 +1499,7 @@ const handleGetMore = async () => {
// 获取历次制裁过程数据
const fetchSanctionProcess = async (page = 1, size = 10) => {
try {
const res = await getSanctionProcess("实体清单", page, size);
const res = await getSanctionProcess(allSanTypeIds.value, page, size);
if (res) {
sanctionProcessList.value = res.content.map(item => ({
...item,
......@@ -1504,18 +1524,25 @@ const handlePageChange = page => {
const searchKeyword = ref("");
// 资源库 Tab 数据
const resourceTabs = [
{ label: "全部制裁", value: "all", disabled: false },
{ label: "实体清单", value: "entity", disabled: false },
{ label: "商业管制清单", value: "commerce", disabled: true }
const resourceTabs = ref([
// { label: "全部制裁", value: "all", disabled: false },
// { label: "实体清单", value: "entity", disabled: false },
// { label: "商业管制清单", value: "commerce", disabled: true }
// { label: "关键与新兴技术清单", value: "tech", disabled: true },
// { label: "军事最终用户清单", value: "military", disabled: true }
];
]);
const activeResourceTab = ref("all");
const activeResourceTabItem = ref({});
// 数据对应,便宜行事
const tabMap = {
1: "entity",
13: "commerce"
};
const handleResourceTabClick = tab => {
if (tab.disabled) return;
activeResourceTab.value = tab.value;
activeResourceTabItem.value = tab;
};
const strengthLabels = {
......
......@@ -10,9 +10,7 @@
</div>
<div class="department">{{ headerTitle.department }}</div>
</div>
<div class="btn">
<img :src="icon01" alt />切换
</div>
<div class="btn"><img :src="icon01" alt />切换</div>
</div>
<div class="header-nav">
<div
......@@ -38,15 +36,16 @@
</template>
<script setup>
import { ref } from 'vue'
import { ref, onMounted } from "vue";
import { useRoute } from "vue-router";
import sanctionsOverview from "./components/sanctionsOverview/index.vue"
import sanctionsOverview from "./components/sanctionsOverview/index.vue";
// import dataStatistics from "./components/dataStatistics/index.vue"
// import deepMining from "./components/deepMining/index.vue"
// import impactAnalysis from "./components/impactAnalysis/index.vue"
import title from "./assets/title.png"
import icon01 from "./assets/icon01.png"
import title from "./assets/title.png";
import icon01 from "./assets/icon01.png";
import icon1 from "../assets/icons/icon1.png";
import icon1Active from "../assets/icons/icon1_active.png";
import icon5 from "../assets/icons/icon5.png";
......@@ -56,41 +55,45 @@ 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 sanTypeId = ref("");
onMounted(() => {
// 获取路由参数sanTypeId
sanTypeId.value = route.query.sanTypeId;
console.log("CommercialControlList 页面接收到的 sanTypeId:", sanTypeId.value);
});
const headerTitle = ref({
img: title,
title: "商业管制清单(CCL)",
titleEn: "Commercial Control List",
department: "美国商务部工业与安全局"
})
img: title,
title: "商业管制清单(CCL)",
titleEn: "Commercial Control List",
department: "美国商务部工业与安全局"
});
const activeIndex = ref(0)
const activeIndex = ref(0);
const headerNavList = ref([
{
img: icon1,
imgActive: icon1Active,
title: "制裁概况"
},
{
img: icon5,
imgActive: icon5Active,
title: "数据统计"
},
{
img: icon2,
imgActive: icon2Active,
title: "深度挖掘"
},
{
img: icon3,
imgActive: icon3Active,
title: "影响分析"
}
])
{
img: icon1,
imgActive: icon1Active,
title: "制裁概况"
},
{
img: icon5,
imgActive: icon5Active,
title: "数据统计"
},
{
img: icon2,
imgActive: icon2Active,
title: "深度挖掘"
},
{
img: icon3,
imgActive: icon3Active,
title: "影响分析"
}
]);
</script>
<style scoped lang="scss">
......
......@@ -178,8 +178,13 @@
<div class="rank-index" :class="'rank-' + (index + 1)">{{ index + 1 }}</div>
<div class="rank-name">{{ item.name }}</div>
<div class="rank-bar-bg">
<div class="rank-bar-fill"
:style="{ width: (item.value / maxRankValue) * 100 + '%', background: getBarColor(index) }"></div>
<div
class="rank-bar-fill"
:style="{
width: (item.value / maxRankValue) * 100 + '%',
background: getBarColor(index)
}"
></div>
</div>
<div class="rank-value">{{ item.value }}家</div>
</div>
......@@ -302,13 +307,22 @@ import * as echarts from "echarts";
import chinaJson from "../../../utils/China.json";
import ai from "./assets/ai.png";
import right from "./assets/right.png";
import { getTotalCount, getSanctionCountChange, getRegionCount, getTechDomainCount, getEntityTypeCount } from "@/api/exportControlV2.0";
import {
getTotalCount,
getSanctionCountChange,
getRegionCount,
getTechDomainCount,
getEntityTypeCount
} from "@/api/exportControlV2.0";
import { useRoute } from "vue-router";
const route = useRoute();
// 实体清单-数据统计-制裁实体类型分布情况
const typeData = ref([]);
const getTypeCountData = async () => {
// 参数
const param = {};
param.sanTypeId = sanTypeId.value;
if (typeTime.value !== "all") {
param.startDate = `${typeTime.value}-01-01`;
......@@ -330,14 +344,12 @@ const getTypeCountData = async () => {
}
};
// 实体清单-数据统计-制裁实体领域分布情况
const domainData = ref([]);
const getDomainCountData = async () => {
// 参数
const param = {};
param.sanTypeId = sanTypeId.value;
if (domainTime.value !== "all") {
param.startDate = `${domainTime.value}-01-01`;
......@@ -371,7 +383,7 @@ const maxRankValue = computed(() => {
const getRegionCountData = async () => {
// 参数
const param = {};
param.sanTypeId = sanTypeId.value;
if (regionTime.value !== "all") {
param.startDate = `${regionTime.value}-01-01`;
param.endDate = `${regionTime.value}-12-31`;
......@@ -396,14 +408,14 @@ const getRegionCountData = async () => {
}
};
// 实体清单-数据统计-制裁实体数量变化情况
const sanctionCountChange = ref([]);
// 获取实体清单-数据统计-制裁实体数量变化情况
const getSanctionCountChangeData = async () => {
// 参数
const param = {
countType: activeTab.value === "year" ? "year" : "record"
countType: activeTab.value === "year" ? "year" : "record",
sanTypeId: sanTypeId.value
};
try {
const res = await getSanctionCountChange(param);
......@@ -419,7 +431,7 @@ const totalCount = ref(0);
// 获取实体清单-数据统计-总量统计
const getTotalCountData = async () => {
try {
const res = await getTotalCount();
const res = await getTotalCount(sanTypeId.value);
totalCount.value = res.data || 0;
} catch (error) {
console.error("获取实体清单-数据统计-总量统计失败:", error);
......@@ -438,9 +450,7 @@ const typeTime = ref("all");
const currentYear = new Date().getFullYear();
const timeOptions = [
{ label: "全部时间", value: "all" },
];
const timeOptions = [{ label: "全部时间", value: "all" }];
for (let i = 0; i <= 10; i++) {
const year = currentYear - i;
......@@ -749,11 +759,13 @@ const updateTypeChart = () => {
chart = echarts.init(typeChartRef.value);
}
let data = typeData.value.length ? [...typeData.value] : [
{ value: 50, name: "企业" },
{ value: 32, name: "高校" },
{ value: 32, name: "科研院所" }
];
let data = typeData.value.length
? [...typeData.value]
: [
{ value: 50, name: "企业" },
{ value: 32, name: "高校" },
{ value: 32, name: "科研院所" }
];
// 2. 聚合逻辑:保留前5项,其余合并为“其他”
data.sort((a, b) => b.value - a.value);
......@@ -873,7 +885,10 @@ const initTypeChart = () => {
updateTypeChart();
};
const sanTypeId = ref("");
onMounted(() => {
sanTypeId.value = route.query.sanTypeId || "";
console.log("数据统计页面接收到的 sanTypeId:", sanTypeId.value);
// initSanctionCountChart();
initMapChart();
initDomainChart();
......
......@@ -75,9 +75,17 @@
<AnalysisBox title="实体清单更新历史" :showAllBtn="false">
<template #header-btn>
<div class="filters">
<el-select v-model="selectedDomain" placeholder="Select"
style="width: 150px; height: 32px; margin-right: 16px">
<el-option v-for="item in domainOptions" :key="item.value" :label="item.label" :value="item.value" />
<el-select
v-model="selectedDomain"
placeholder="Select"
style="width: 150px; height: 32px; margin-right: 16px"
>
<el-option
v-for="item in domainOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-checkbox v-model="onlyChina">只看涉华动态</el-checkbox>
</div>
......@@ -91,8 +99,13 @@
<img :src="item.icon || title" alt="" />
<div class="main">
<div class="main-title" @click="handleClick(item)">{{ item.name }}</div>
<el-tooltip effect="dark" :content="item.summary" popper-class="common-prompt-popper" placement="top"
:show-after="500">
<el-tooltip
effect="dark"
:content="item.summary"
popper-class="common-prompt-popper"
placement="top"
:show-after="500"
>
<div class="main-desc">{{ item.summary }}</div>
</el-tooltip>
<div class="tag-box">
......@@ -107,8 +120,14 @@
</div>
<div class="left-footer">
<div class="total-count"> {{ totalAll }} </div>
<el-pagination v-model:current-page="currentPageAll" :page-size="pageSizeAll" :total="totalAll"
layout="prev, pager, next" background @current-change="handlePageChangeAll" />
<el-pagination
v-model:current-page="currentPageAll"
:page-size="pageSizeAll"
:total="totalAll"
layout="prev, pager, next"
background
@current-change="handlePageChangeAll"
/>
</div>
</AnalysisBox>
</div>
......@@ -130,8 +149,12 @@
<span>关键人物</span>
</div>
<div class="key-person-list">
<div class="person-item" v-for="(item, index) in publishInfo.personList" :key="index"
@click="handlePerClick(item)">
<div
class="person-item"
v-for="(item, index) in publishInfo.personList"
:key="index"
@click="handlePerClick(item)"
>
<img :src="item.imageUrl" alt="" />
<div class="person-info">
<CommonPrompt :content="item.name">
......@@ -183,7 +206,9 @@ import icon02 from "../../assets/icon02.png";
import { ArrowDown } from "@element-plus/icons-vue";
import CommonPrompt from "../../../../../commonPrompt/index.vue";
import { getEntityInfo, getPublishInfo, getPublishOrgInfo, getEntityUpdateInfo } from "@/api/exportControlV2.0.js";
import { useRoute } from "vue-router";
const route = useRoute();
// 处理点击发布机构的方法
const handleClickOrg = item => {
// console.log("点击了发布机构:", item);
......@@ -275,9 +300,10 @@ const getSanctionUpdate = async () => {
const data = {
isCn: onlyChina.value,
techDomainIds: selectedDomain.value ? [selectedDomain.value] : [],
typeName: "实体清单",
// typeName: "实体清单",
pageNum: currentPageAll.value,
pageSize: pageSizeAll.value
pageSize: pageSizeAll.value,
sanTypeIds: [sanTypeId.value] || ["1"] // 实体清单固定1
};
try {
const res = await getEntityUpdateInfo(data);
......@@ -324,7 +350,7 @@ const handlePageChangeAll = val => {
const publishInfo = ref({});
const getPublishInfoFn = async () => {
const params = {
sanTypeId: 1 // 实体清单固定1
sanTypeId: sanTypeId.value || 1 // 实体清单固定1
};
try {
const res = await getPublishInfo(params);
......@@ -379,22 +405,25 @@ const handleLoadMoreDynamic = () => {
// 获取实体清单基本信息
const entityInfo = ref({});
const emit = defineEmits(['update-entity-info']);
const getEntityInfoFn = async () => {
const emit = defineEmits(["update-entity-info"]);
const getEntityInfoFn = async id => {
try {
const res = await getEntityInfo("el");
const res = await getEntityInfo(id);
if (res && res.code === 200) {
entityInfo.value = res.data;
emit('update-entity-info', res.data);
console.log("获取实体清单基本信息成功:", res.data);
emit("update-entity-info", res.data);
}
} catch (error) {
console.error("获取实体清单基本信息失败:", error);
}
};
const sanTypeId = ref("");
onMounted(() => {
sanTypeId.value = route.query.sanTypeId;
// 获取实体清单基本信息
getEntityInfoFn();
getEntityInfoFn(sanTypeId.value);
// 获取实体清单发布机构
getPublishInfoFn();
// 获取实体清单更新历史
......
<template>
<div class="sanctions-overview">
<div class="side-nav">
<div v-for="(item, index) in activeTab" :key="index" class="tab-item" :class="{'active': index === activeIndex}" @click="activeIndex = index">
{{item}}
<span v-if="index === activeIndex" class="arrow"></span>
</div>
</div>
<div class="content-box">
<introductionPage v-if="activeIndex === 0" @update-entity-info="(data) => $emit('update-entity-info', data)"></introductionPage>
<listPage v-if="activeIndex === 1"></listPage>
</div>
</div>
<div class="sanctions-overview">
<div class="side-nav">
<div
v-for="(item, index) in activeTab"
:key="index"
class="tab-item"
:class="{ active: index === activeIndex }"
@click="activeIndex = index"
>
{{ item }}
<span v-if="index === activeIndex" class="arrow"></span>
</div>
</div>
<div class="content-box">
<introductionPage
v-show="activeIndex === 1"
@update-entity-info="data => $emit('update-entity-info', data)"
></introductionPage>
<listPage v-show="activeIndex === 0"></listPage>
</div>
</div>
</template>
<script setup>
import { ref, defineEmits } from 'vue'
import introductionPage from "./components/introductionPage/index.vue"
import listPage from "./components/listPage/index.vue"
const emit = defineEmits(['update-entity-info'])
const activeTab = ref(["实体清单简介", "实体清单列表"])
const activeIndex = ref(0)
import { ref, defineEmits } from "vue";
import introductionPage from "./components/introductionPage/index.vue";
import listPage from "./components/listPage/index.vue";
const emit = defineEmits(["update-entity-info"]);
const activeTab = ref(["实体清单列表", "实体清单简介"]);
const activeIndex = ref(0);
</script>
<style scoped lang="scss">
*{
margin: 0;
padding: 0;
* {
margin: 0;
padding: 0;
}
.sanctions-overview{
width: 1601px;
margin: 0 auto;
position: relative;
// min-height: 800px;
.side-nav {
position: absolute;
top: 27px;
right: 100%;
margin-right: 12px;
display: flex;
flex-direction: column;
gap: 16px;
.tab-item {
cursor: pointer;
padding: 4px 20px;
border-radius: 22px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
white-space: nowrap;
display: flex;
align-items: center;
&.active {
background-color: rgb(5, 95, 194);
color: #fff;
.arrow {
display: inline-block;
width: 0;
height: 0;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-left: 6px solid #fff;
margin-left: 8px;
}
}
}
}
.content-box {
width: 100%;
}
.sanctions-overview {
width: 1601px;
margin: 0 auto;
position: relative;
// min-height: 800px;
.side-nav {
position: absolute;
top: 27px;
right: 100%;
margin-right: 12px;
display: flex;
flex-direction: column;
gap: 16px;
.tab-item {
cursor: pointer;
padding: 4px 20px;
border-radius: 22px;
font-size: 16px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
white-space: nowrap;
display: flex;
align-items: center;
&.active {
background-color: rgb(5, 95, 194);
color: #fff;
.arrow {
display: inline-block;
width: 0;
height: 0;
border-top: 5px solid transparent;
border-bottom: 5px solid transparent;
border-left: 6px solid #fff;
margin-left: 8px;
}
}
}
}
.content-box {
width: 100%;
}
}
</style>
<template>
<div class="entity-list">
<div class="header">
<div class="header-title">
<img :src="headerTitle.img" alt="">
<div>
<div class="title">
{{ headerTitle.title }}
<span>{{ headerTitle.titleEn }}</span>
</div>
<div class="department">
{{ headerTitle.department }}
</div>
</div>
<div class="btn">
<img :src="icon01" alt="">切换
</div>
</div>
<div class="header-nav">
<div
class="nav-item"
v-for="(item, index) in headerNavList"
:key="index"
:class="{ active: activeIndex === index }"
@click="activeIndex = index"
>
<img :src="activeIndex === index ? item.imgActive : item.img" alt="">
<span>{{ item.title }}</span>
<div class="active-line" v-if="activeIndex === index"></div>
</div>
</div>
</div>
<div class="main">
<sanctions-overview v-if="activeIndex === 0" @update-entity-info="handleUpdateEntityInfo"></sanctions-overview>
<data-statistics v-if="activeIndex === 1"></data-statistics>
<deep-mining v-if="activeIndex === 2"></deep-mining>
<impact-analysis v-if="activeIndex === 3"></impact-analysis>
</div>
</div>
<div class="entity-list">
<div class="header">
<div class="header-title">
<img :src="headerTitle.img" alt="" />
<div>
<div class="title">
{{ headerTitle.title }}
<span>{{ headerTitle.titleEn }}</span>
</div>
<div class="department">
{{ headerTitle.department }}
</div>
</div>
<div class="btn"><img :src="icon01" alt="" />切换</div>
</div>
<div class="header-nav">
<div
class="nav-item"
v-for="(item, index) in headerNavList"
:key="index"
:class="{ active: activeIndex === index }"
@click="activeIndex = index"
>
<img :src="activeIndex === index ? item.imgActive : item.img" alt="" />
<span>{{ item.title }}</span>
<div class="active-line" v-if="activeIndex === index"></div>
</div>
</div>
</div>
<div class="main">
<sanctions-overview v-if="activeIndex === 0" @update-entity-info="handleUpdateEntityInfo"></sanctions-overview>
<data-statistics v-if="activeIndex === 1"></data-statistics>
<deep-mining v-if="activeIndex === 2"></deep-mining>
<impact-analysis v-if="activeIndex === 3"></impact-analysis>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
import { ref, onMounted } from "vue";
import { useRoute } from "vue-router";
import sanctionsOverview from "./components/sanctionsOverview/index.vue";
import dataStatistics from "./components/dataStatistics/index.vue";
......@@ -58,27 +57,34 @@ 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 headerTitle = ref({
// img: title,
// title: "实体清单",
// titleEn: "Entity List",
// department: "美国商务部工业与安全局"
})
// img: title,
// title: "实体清单",
// titleEn: "Entity List",
// department: "美国商务部工业与安全局"
});
const handleUpdateEntityInfo = (data) => {
if (data) {
headerTitle.value = {
...headerTitle.value,
title: data.name,
titleEn: data.originalName,
department: data.orgName,
departId: data.orgId,
img: data.orgLogoUrl || title
}
}
}
onMounted(() => {
// 获取路由参数id
const id = route.query.id;
console.log("EntityList 页面接收到的 id:", id);
});
const handleUpdateEntityInfo = data => {
console.log("更新实体清单基本信息:", data);
if (data) {
headerTitle.value = {
...headerTitle.value,
title: data.name,
titleEn: data.originalName,
department: data.orgName,
departId: data.orgId,
img: data.orgLogoUrl || title
};
}
};
const activeIndex = ref(0)
const activeIndex = ref(0);
const headerNavList = ref([
{
......
......@@ -137,15 +137,18 @@
<AnalysisBox title="制裁实体国家分布情况">
<div class="country-list">
<div class="list-item" v-for="(item, index) in countryDistribution" :key="index">
<img :src="flag" alt="" class="flag">
<img :src="flag" alt="" class="flag" />
<div class="country-name">{{ item.name }}</div>
<div class="progress-bar-container">
<div class="progress-bar" :style="{
width: item.width,
background: item.gradient
}"></div>
<div
class="progress-bar"
:style="{
width: item.width,
background: item.gradient
}"
></div>
</div>
<div class="count" :class="{ 'highlight': index === 0 }">{{ item.count }}</div>
<div class="count" :class="{ highlight: index === 0 }">{{ item.count }}</div>
</div>
</div>
<div class="bottom">
......@@ -170,9 +173,13 @@
<div class="rank-index" :class="'rank-' + (index + 1)">{{ index + 1 }}</div>
<div class="rank-name">{{ item.name }}</div>
<div class="rank-bar-bg">
<div class="rank-bar-fill"
:style="{ width: (maxRegionCount > 0 ? (item.count / maxRegionCount) * 100 : 0) + '%', background: getBarColor(index) }">
</div>
<div
class="rank-bar-fill"
:style="{
width: (maxRegionCount > 0 ? (item.count / maxRegionCount) * 100 : 0) + '%',
background: getBarColor(index)
}"
></div>
</div>
<div class="rank-value">{{ item.count }}</div>
</div>
......@@ -201,10 +208,18 @@ import * as echarts from "echarts";
import chinaJson from "../../../utils/China.json";
import ai from "./assets/ai.png";
import right from "./assets/right.png";
import flag from "../../assets/default-icon2.png"
import flag from "../../assets/default-icon2.png";
import { useRouter } from "vue-router";
import { getSingleSanctionTotalCount, getSingleSanctionDomainCount, getSingleSanctionEntityTypeCount, getSingleSanctionEntityCountryCount, getSingleSanctionEntityRegionCount } from "@/api/exportControlV2.0";
import {
getSingleSanctionTotalCount,
getSingleSanctionDomainCount,
getSingleSanctionEntityTypeCount,
getSingleSanctionEntityCountryCount,
getSingleSanctionEntityRegionCount
} from "@/api/exportControlV2.0";
import { useRoute } from "vue-router";
const route = useRoute();
// 单次制裁-数据统计-制裁实体地域分布情况
const regionDistribution = ref([]);
const maxRegionCount = ref(0);
......@@ -212,8 +227,8 @@ const maxRegionCount = ref(0);
const getRegionData = async () => {
if (!sanRecordId.value) return;
try {
const params = { sanRecordId: sanRecordId.value };
if (regionTime.value && regionTime.value !== 'all') {
const params = { sanRecordId: sanRecordId.value, sanTypeId: route.query.sanTypeId || "1" };
if (regionTime.value && regionTime.value !== "all") {
params.startDate = `${regionTime.value}-01-01`;
params.endDate = `${regionTime.value}-12-31`;
}
......@@ -226,9 +241,7 @@ const getRegionData = async () => {
} catch (error) {
console.log(error);
}
}
};
// 单次制裁-数据统计-制裁实体国家分布情况
const countryDistribution = ref([]);
......@@ -236,7 +249,7 @@ const countryDistribution = ref([]);
const getCountryCount = async () => {
if (!sanRecordId.value) return;
try {
const params = { sanRecordId: sanRecordId.value };
const params = { sanRecordId: sanRecordId.value, sanTypeId: sanTypeId.value };
const res = await getSingleSanctionEntityCountryCount(params);
if (res.code === 200) {
const rawData = res.data || [];
......@@ -245,7 +258,7 @@ const getCountryCount = async () => {
countryDistribution.value = rawData.map((item, index) => {
// 计算宽度,最大值对应 80%
const width = maxCount > 0 ? (item.count / maxCount) * 80 + '%' : '0%';
const width = maxCount > 0 ? (item.count / maxCount) * 80 + "%" : "0%";
// 根据索引分配渐变色
let gradient = "";
......@@ -267,9 +280,7 @@ const getCountryCount = async () => {
} catch (error) {
console.log(error);
}
}
};
// 单次制裁-数据统计-制裁实体类型分布情况
const entityTypeCount = ref([]);
......@@ -277,8 +288,8 @@ const entityTypeCount = ref([]);
const getEntityTypeCount = async () => {
if (!sanRecordId.value) return;
try {
const params = { sanRecordId: sanRecordId.value };
if (typeTime.value && typeTime.value !== 'all') {
const params = { sanRecordId: sanRecordId.value, sanTypeId: sanTypeId.value };
if (typeTime.value && typeTime.value !== "all") {
params.startDate = `${typeTime.value}-01-01`;
params.endDate = `${typeTime.value}-12-31`;
}
......@@ -290,10 +301,7 @@ const getEntityTypeCount = async () => {
} catch (error) {
console.log(error);
}
}
};
// 单次制裁-数据统计-制裁实体领域分布情况
const domainCount = ref([]);
......@@ -301,8 +309,8 @@ const domainCount = ref([]);
const getDomainCount = async () => {
if (!sanRecordId.value) return;
try {
const params = { sanRecordId: sanRecordId.value };
if (domainTime.value && domainTime.value !== 'all') {
const params = { sanRecordId: sanRecordId.value, sanTypeId: sanTypeId.value };
if (domainTime.value && domainTime.value !== "all") {
params.startDate = `${domainTime.value}-01-01`;
params.endDate = `${domainTime.value}-12-31`;
}
......@@ -314,8 +322,7 @@ const getDomainCount = async () => {
} catch (error) {
console.log(error);
}
}
};
// 单次制裁-数据统计-总量统计
const totalCount = ref({});
......@@ -323,22 +330,21 @@ const totalCount = ref({});
const getTotalCount = async () => {
if (!sanRecordId.value) return;
try {
const res = await getSingleSanctionTotalCount({ sanRecordId: sanRecordId.value });
const res = await getSingleSanctionTotalCount(route.query.sanTypeId);
if (res.code === 200) {
totalCount.value = res.data || {};
}
} catch (error) {
console.log(error);
}
}
};
const router = useRouter();
const sanRecordId = ref("")
const sanRecordId = ref("");
const getUrlParams = () => {
const urlParams = new URLSearchParams(window.location.search);
sanRecordId.value = urlParams.get("id") || ""
}
sanRecordId.value = urlParams.get("id") || "";
};
const regionTime = ref("all");
const domainTime = ref("all");
......@@ -355,11 +361,7 @@ watch(regionTime, () => {
getRegionData();
});
const timeOptions = [
{ label: "全部时间", value: "all" }
];
const timeOptions = [{ label: "全部时间", value: "all" }];
// 生成2000-2025年的选项
for (let i = 2025; i >= 2000; i--) {
timeOptions.push({ label: `${i}年`, value: `${i}` });
......@@ -640,8 +642,11 @@ const initTypeChart = () => {
chart.resize();
});
};
const sanTypeId = ref("");
onMounted(() => {
// 获取路由参数id
sanTypeId.value = route.query.sanTypeId;
console.log("页面接收到的 sanTypeId:", sanTypeId.value);
// 获取url参数
getUrlParams();
// 单次制裁-数据统计-总量统计-请求
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论