提交 82d414ef authored 作者: yanpeng's avatar yanpeng

api

上级 51f07374
...@@ -103,9 +103,9 @@ const router = useRouter(); ...@@ -103,9 +103,9 @@ const router = useRouter();
const handleToHome = () => { const handleToHome = () => {
router.push({ router.push({
path: '/overview' path: "/overview"
}) });
} };
const isShowAiBox = ref(false); const isShowAiBox = ref(false);
...@@ -307,6 +307,7 @@ body { ...@@ -307,6 +307,7 @@ body {
position: absolute; position: absolute;
bottom: 20%; bottom: 20%;
right: 46px; right: 46px;
z-index: 9999;
cursor: pointer; cursor: pointer;
.icon { .icon {
......
import request from "@/api/request.js"; import request from "@/api/request.js";
import { import { ElMessage } from "element-plus";
ElMessage
} from 'element-plus'
const request200 = (requestP) => { const request200 = requestP => {
return requestP.then((data) => { return requestP.then(data => {
if (data.code === 200) { if (data.code === 200) {
return data.data return data.data;
} }
ElMessage({ ElMessage({
message: data.message, message: data.message,
type: 'error', type: "error",
duration: 3 * 1000 duration: 3 * 1000
}) });
return null return null;
}) });
} };
// 实体清单总条数统计 // 实体清单总条数统计
/** /**
* @returns {Promise<number>} * @returns {Promise<number>}
*/ */
export function getEntitiesDataCount() { export function getEntitiesDataCount() {
return request200(request({ return request200(
method: 'GET', request({
url: '/api/entitiesDataCount/countData', method: "GET",
})) url: "/api/entitiesDataCount/countData"
})
);
} }
// 最新实体清单信息查询 // 最新实体清单信息查询
...@@ -43,11 +43,15 @@ export function getEntitiesDataCount() { ...@@ -43,11 +43,15 @@ export function getEntitiesDataCount() {
* startTime: string * startTime: string
*}>} *}>}
*/ */
// 最新出口管制政策
export function getEntitiesDataInfo() { export function getEntitiesDataInfo() {
return request200(request({ return request200(
method: 'GET', request({
url: '/api/entitiesDataInfo/latestInfoSelect', method: "GET",
})) // url: '/api/entitiesDataInfo/latestInfoSelect',
url: "/api/entitiesDataInfo/getLatestInfo"
})
);
} }
/** /**
...@@ -59,10 +63,13 @@ export function getEntitiesDataInfo() { ...@@ -59,10 +63,13 @@ export function getEntitiesDataInfo() {
* }[]>} * }[]>}
*/ */
export function getIndustryCountByYear() { export function getIndustryCountByYear() {
return request200(request({ return request200(
method: 'GET', request({
url: '/api/entitiesDataCount/industryCountByYear', method: "GET",
})) // url: "/api/entitiesDataCount/industryCountByYear"
url: "/api/entitiesDataCount/getAnnualCount"
})
);
} }
/** /**
...@@ -78,10 +85,12 @@ export function getIndustryCountByYear() { ...@@ -78,10 +85,12 @@ export function getIndustryCountByYear() {
* }>} * }>}
*/ */
export function getCountDomainByYear() { export function getCountDomainByYear() {
return request200(request({ return request200(
method: 'GET', request({
url: '/api/entitiesDataCount/countDomainByYear', method: "GET",
})) url: "/api/entitiesDataCount/countDomainByYear"
})
);
} }
/** /**
...@@ -93,10 +102,34 @@ export function getCountDomainByYear() { ...@@ -93,10 +102,34 @@ export function getCountDomainByYear() {
* }[]>} * }[]>}
*/ */
export function getSanctionsInfoCount() { export function getSanctionsInfoCount() {
return request200(request({ return request200(
method: 'GET', request({
url: '/api/entitiesDataCount/sanctionsInfoCount', method: "GET",
})) url: "/api/entitiesDataCount/sanctionsInfoCount"
})
);
}
/**
* 历次制裁过程(月份统计)-new
* @returns {Promise<{
* tittle: string
* entitiesChNum: string
* sanReason: string
* }[]>}
*/
export function getSanctionProcess(typeName = "实体清单", pageNum = 1, pageSize = 10) {
return request200(
request({
method: "POST",
url: "/api/entitiesDataCount/getSanctionProcess",
data: {
typeName,
pageNum,
pageSize
}
})
);
} }
/** /**
...@@ -107,11 +140,17 @@ export function getSanctionsInfoCount() { ...@@ -107,11 +140,17 @@ export function getSanctionsInfoCount() {
* orgIntroduction: string //机构职责 * orgIntroduction: string //机构职责
* }>} * }>}
*/ */
export function getOrganizationInfo() { export function getOrganizationInfo(sanTypeId = 1) {
return request200(request({ return request200(
method: 'GET', request({
url: '/api/entitiesDataInfo/getOrganizationInfo', method: "GET",
})) // url: "/api/entitiesDataInfo/getOrganizationInfo"
url: "/api/sanctionList/getPublishedOrg",
params: {
sanTypeId
}
})
);
} }
/** /**
...@@ -124,10 +163,12 @@ export function getOrganizationInfo() { ...@@ -124,10 +163,12 @@ export function getOrganizationInfo() {
* }[]>} * }[]>}
*/ */
export function getPersonList() { export function getPersonList() {
return request200(request({ return request200(
method: 'GET', request({
url: '/api/entitiesDataInfo/getPersonList', method: "GET",
})) url: "/api/entitiesDataInfo/getPersonList"
})
);
} }
/** /**
...@@ -139,13 +180,16 @@ export function getPersonList() { ...@@ -139,13 +180,16 @@ export function getPersonList() {
* }[]>} * }[]>}
*/ */
export function getCountByDomain(startTime) { export function getCountByDomain(startTime) {
return request200(request({ return request200(
method: 'GET', request({
url: '/api/entitiesDataCount/countByDomain', method: "POST",
params: { // url: "/api/entitiesDataCount/countByDomain",
startTime url: "/api/sanctionListCount/sanctionDomainCountByParam",
data: {
sanctionDate: startTime || "2025-11-11"
} }
})) })
);
} }
/** /**
...@@ -157,13 +201,16 @@ export function getCountByDomain(startTime) { ...@@ -157,13 +201,16 @@ export function getCountByDomain(startTime) {
* }[]>} * }[]>}
*/ */
export function getCountByType(startTime) { export function getCountByType(startTime) {
return request200(request({ return request200(
method: 'GET', request({
url: '/api/entitiesDataCount/countByType', method: "GET",
// url: "/api/entitiesDataCount/countByType",
url: "/api/entitiesDataInfo/getTypeDistribution",
params: { params: {
startTime sanctionDate: startTime || "2025-11-11"
} }
})) })
);
} }
/** /**
...@@ -172,13 +219,16 @@ export function getCountByType(startTime) { ...@@ -172,13 +219,16 @@ export function getCountByType(startTime) {
* @returns {Promise<string[]>} * @returns {Promise<string[]>}
*/ */
export function getSanReasonSelect(startTime) { export function getSanReasonSelect(startTime) {
return request200(request({ return request200(
method: 'GET', request({
url: '/api/entitiesDataInfo/sanReasonSelect', method: "GET",
// url: "/api/entitiesDataInfo/sanReasonSelect",
url: "/api/entitiesDataInfo/getSanReason",
params: { params: {
startTime sanctionDate: startTime || "2025-11-11"
} }
})) })
);
} }
/** /**
...@@ -191,13 +241,53 @@ export function getSanReasonSelect(startTime) { ...@@ -191,13 +241,53 @@ export function getSanReasonSelect(startTime) {
* }[]>} * }[]>}
*/ */
export function getSelectEntitiesList(startTime) { export function getSelectEntitiesList(startTime) {
return request200(request({ return request200(
method: 'GET', request({
url: '/api/entitiesDataInfo/selectEntitiesList', method: "GET",
url: "/api/entitiesDataInfo/selectEntitiesList",
params: { params: {
startTime startTime
} }
})) })
);
}
/**
* 领域分布查询
*/
export function getDomainDistribution(sanctionDate = "2025-11-11") {
return request200(
request({
method: "GET",
url: "/api/entitiesDataInfo/getDomianDistribution",
params: {
sanctionDate
}
})
);
}
/**
* 分页查询实体清单列表
* @param {string} typeName - 实体类型名称
* @returns {Promise<{
* entityNameZh: string
* techDomainList: string[]
* startTime: string
* }[]>}
*/
export function getEntitiesList(typeName = "实体清单", pageNum = 1, pageSize = 10) {
return request200(
request({
method: "POST",
url: "/api/sanctionList/pageQuery",
data: {
typeName,
pageNum,
pageSize
}
})
);
} }
/** /**
...@@ -213,13 +303,15 @@ export function getSelectEntitiesList(startTime) { ...@@ -213,13 +303,15 @@ export function getSelectEntitiesList(startTime) {
* }>} * }>}
*/ */
export function getCompareCountSan(startTime) { export function getCompareCountSan(startTime) {
return request200(request({ return request200(
method: 'GET', request({
url: '/api/entitiesDataCount/compareCountSan', method: "GET",
url: "/api/entitiesDataCount/compareCountSan",
params: { params: {
startTime startTime
} }
})) })
);
} }
/** /**
...@@ -232,15 +324,17 @@ export function getCompareCountSan(startTime) { ...@@ -232,15 +324,17 @@ export function getCompareCountSan(startTime) {
* }[]>} * }[]>}
*/ */
export function getEntitiesChangeCount(domain, type) { export function getEntitiesChangeCount(domain, type) {
return request200(request({ return request200(
method: 'GET', request({
method: "GET",
// url: '/api/entitiesDataCount/entitiesChangeCount', // url: '/api/entitiesDataCount/entitiesChangeCount',
url: '/api/entitiesDataCount/sanCountByYear', url: "/api/entitiesDataCount/sanCountByYear",
params: { params: {
domain, domain,
type type
} }
})) })
);
} }
/** /**
...@@ -251,10 +345,12 @@ export function getEntitiesChangeCount(domain, type) { ...@@ -251,10 +345,12 @@ export function getEntitiesChangeCount(domain, type) {
* }>} * }>}
*/ */
export function getEntitiesGrowthTrend() { export function getEntitiesGrowthTrend() {
return request200(request({ return request200(
method: 'GET', request({
url: '/api/entitiesDataCount/entitiesGrowthTrend', method: "GET",
})) url: "/api/entitiesDataCount/entitiesGrowthTrend"
})
);
} }
/** /**
...@@ -265,10 +361,12 @@ export function getEntitiesGrowthTrend() { ...@@ -265,10 +361,12 @@ export function getEntitiesGrowthTrend() {
* }>} * }>}
*/ */
export function getEntitiesUpdateCount() { export function getEntitiesUpdateCount() {
return request200(request({ return request200(
method: 'GET', request({
url: '/api/entitiesDataCount/entitiesUpdateCount', method: "GET",
})) url: "/api/entitiesDataCount/entitiesUpdateCount"
})
);
} }
/** /**
...@@ -280,13 +378,15 @@ export function getEntitiesUpdateCount() { ...@@ -280,13 +378,15 @@ export function getEntitiesUpdateCount() {
* }[]>} * }[]>}
*/ */
export function getEntitiesAreaCountByYear(sanTime) { export function getEntitiesAreaCountByYear(sanTime) {
return request200(request({ return request200(
method: 'GET', request({
url: '/api/entitiesDataCount/entitiesAreaCountByYear', method: "GET",
url: "/api/entitiesDataCount/entitiesAreaCountByYear",
params: { params: {
sanTime sanTime
} }
})) })
);
} }
/** /**
...@@ -297,10 +397,12 @@ export function getEntitiesAreaCountByYear(sanTime) { ...@@ -297,10 +397,12 @@ export function getEntitiesAreaCountByYear(sanTime) {
* }>} * }>}
*/ */
export function getEntitiesDomainCount() { export function getEntitiesDomainCount() {
return request200(request({ return request200(
method: 'GET', request({
url: '/api/entitiesDataCount/entitiesDomainCount' method: "GET",
})) url: "/api/entitiesDataCount/entitiesDomainCount"
})
);
} }
/** /**
...@@ -312,13 +414,15 @@ export function getEntitiesDomainCount() { ...@@ -312,13 +414,15 @@ export function getEntitiesDomainCount() {
* }[]>} * }[]>}
*/ */
export function getCountThisDomain(param) { export function getCountThisDomain(param) {
return request200(request({ return request200(
method: 'GET', request({
url: '/api/entitiesDataCount/countThisDomain', method: "GET",
url: "/api/entitiesDataCount/countThisDomain",
params: { params: {
param param
} }
})) })
);
} }
/** /**
...@@ -329,10 +433,12 @@ export function getCountThisDomain(param) { ...@@ -329,10 +433,12 @@ export function getCountThisDomain(param) {
* }[]>} * }[]>}
*/ */
export function getCountTypeByYear() { export function getCountTypeByYear() {
return request200(request({ return request200(
method: 'GET', request({
url: '/api/entitiesDataCount/countTypeByYear', method: "GET",
})) url: "/api/entitiesDataCount/countTypeByYear"
})
);
} }
/** /**
...@@ -344,13 +450,15 @@ export function getCountTypeByYear() { ...@@ -344,13 +450,15 @@ export function getCountTypeByYear() {
* }[]>} * }[]>}
*/ */
export function getCountSanTypeByTime(startTime) { export function getCountSanTypeByTime(startTime) {
return request200(request({ return request200(
method: 'GET', request({
url: '/api/entitiesDataCount/countSanTypeByTime', method: "GET",
url: "/api/entitiesDataCount/countSanTypeByTime",
params: { params: {
startTime startTime
} }
})) })
);
} }
/** /**
...@@ -362,12 +470,59 @@ export function getCountSanTypeByTime(startTime) { ...@@ -362,12 +470,59 @@ export function getCountSanTypeByTime(startTime) {
* }[]>} * }[]>}
*/ */
export function getCountThisType(param) { export function getCountThisType(param) {
return request200(request({ return request200(
method: 'GET', request({
url: '/api/entitiesDataCount/countThisType', method: "GET",
url: "/api/entitiesDataCount/countThisType",
params: { params: {
param param
} }
})) })
);
} }
/**
* 产业链信息查询
*/
export function getChainFishbone(chainId) {
return request200(
request({
method: "GET",
url: "/api/chain/getChainFishbone",
params: {
chainId
}
})
);
}
/**
* 产业链结构信息查询
*/
export function getChainStructure(chainId = "") {
return request200(
request({
method: "GET",
url: "/api/chain/getChainTree",
params: {
chainId
}
})
);
}
/**
* 产业链实体列表查询
*/
export function getChainEntities(date, id) {
return request200(
request({
method: "GET",
url: "/api/entitiesDataInfo/getEntityList",
params: {
sanctionDate: date,
domainId: id
}
})
);
}
...@@ -146,6 +146,7 @@ const headerTitleClasses = computed(() => [ ...@@ -146,6 +146,7 @@ const headerTitleClasses = computed(() => [
} }
.header-title { .header-title {
font-family: $base-font-family;
font-size: $base-font-size; font-size: $base-font-size;
font-weight: 700; font-weight: 700;
/* color: rgba(10, 87, 166, 1); */ /* color: rgba(10, 87, 166, 1); */
......
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
$primary-color: var(--el-color-primary); $primary-color: var(--el-color-primary);
$base-color: rgba(10, 87, 166, 1); $base-color: rgba(10, 87, 166, 1);
$base-font-size: 16px; $base-font-size: 16px;
$base-font-family: "微软雅黑";
// :root { // :root {
// --base-color: #{$base-color}; // --base-color: #{$base-color};
......
<template>
<div class="fishbone">
<div class="main-line"></div>
<div class="top-bone">
<div class="left-bone">
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
</div>
<div class="right-bone">
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
</div>
</div>
<div class="top-bone1">
<div class="left-bone">
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
</div>
<div class="right-bone">
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
</div>
</div>
<div class="top-bone2">
<div class="left-bone">
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
</div>
<div class="right-bone">
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
</div>
</div>
<div class="bottom-bone">
<div class="left-bone">
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
</div>
<div class="right-bone">
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
</div>
</div>
<div class="bottom-bone1">
<div class="left-bone">
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
</div>
<div class="right-bone">
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
</div>
</div>
<div class="bottom-bone2">
<div class="left-bone">
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
</div>
<div class="right-bone">
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { getChainFishbone } from "@/api/exportControl";
import { onMounted, ref } from "vue";
const chainId = ref("");
const chainFishbone = ref([]);
onMounted(async () => {
try {
const chainFishboneData = await getChainFishbone(chainId.value);
chainFishbone.value = chainFishboneData ?? [];
} catch (error) {
console.log(error);
}
});
</script>
<style lang="scss" scoped>
.fishbone {
position: relative;
width: 100%;
height: 100%;
margin-top: 40px;
.main-line {
position: absolute;
top: 280px;
right: 0;
width: 888px;
height: 3px;
background: rgba(174, 208, 255, 1);
}
}
.top-bone {
position: absolute;
top: 20px;
right: 200px;
width: 3px;
height: 260px;
background: #90caf9;
transform: skew(30deg);
z-index: 1;
.left-bone {
color: #777;
position: absolute;
top: 0;
left: -150px;
width: 150px;
height: 260px;
// background: orange;
.left-bone-item {
transform: skew(-30deg);
height: 35px;
margin-bottom: 5px;
margin-top: 15px;
// background: #fff;
display: flex;
justify-content: flex-end;
.icon {
margin-top: 7px;
width: 20px;
height: 20px;
img {
width: 100%;
height: 100%;
}
}
.text {
margin-left: 4px;
height: 35px;
line-height: 35px;
}
.line {
margin-left: 7px;
margin-top: 16px;
width: 30px;
height: 2px;
background: rgba(174, 208, 255, 1);
}
}
}
.right-bone {
color: #777;
position: absolute;
top: 0;
right: -150px;
width: 150px;
height: 260px;
// background: pink;
.right-bone-item {
transform: skew(-30deg);
height: 35px;
margin-bottom: 15px;
margin-top: 5px;
display: flex;
justify-content: flex-start;
.line {
margin-right: 7px;
margin-top: 16px;
width: 30px;
height: 2px;
background: rgba(174, 208, 255, 1);
}
.text {
margin-right: 4px;
height: 35px;
line-height: 35px;
}
.icon {
margin-top: 7px;
width: 20px;
height: 20px;
img {
width: 100%;
height: 100%;
}
}
}
}
}
.top-bone1 {
position: absolute;
top: 20px;
right: 500px;
width: 3px;
height: 260px;
background: #90caf9;
transform: skew(30deg);
z-index: 1;
.left-bone {
color: #777;
position: absolute;
top: 0;
left: -150px;
width: 150px;
height: 260px;
// background: orange;
.left-bone-item {
transform: skew(-30deg);
height: 35px;
margin-bottom: 5px;
margin-top: 15px;
// background: #fff;
display: flex;
justify-content: flex-end;
.icon {
margin-top: 7px;
width: 20px;
height: 20px;
img {
width: 100%;
height: 100%;
}
}
.text {
margin-left: 4px;
height: 35px;
line-height: 35px;
}
.line {
margin-left: 7px;
margin-top: 16px;
width: 30px;
height: 2px;
background: rgba(174, 208, 255, 1);
}
}
}
.right-bone {
color: #777;
position: absolute;
top: 0;
right: -150px;
width: 150px;
height: 260px;
// background: pink;
.right-bone-item {
transform: skew(-30deg);
height: 35px;
margin-bottom: 15px;
margin-top: 5px;
display: flex;
justify-content: flex-start;
.line {
margin-right: 7px;
margin-top: 16px;
width: 30px;
height: 2px;
background: rgba(174, 208, 255, 1);
}
.text {
margin-right: 4px;
height: 35px;
line-height: 35px;
}
.icon {
margin-top: 7px;
width: 20px;
height: 20px;
img {
width: 100%;
height: 100%;
}
}
}
}
}
.top-bone2 {
position: absolute;
top: 20px;
right: 800px;
width: 3px;
height: 260px;
background: #90caf9;
transform: skew(30deg);
z-index: 1;
.left-bone {
color: #777;
position: absolute;
top: 0;
left: -150px;
width: 150px;
height: 260px;
// background: orange;
.left-bone-item {
transform: skew(-30deg);
height: 35px;
margin-bottom: 5px;
margin-top: 15px;
// background: #fff;
display: flex;
justify-content: flex-end;
.icon {
margin-top: 7px;
width: 20px;
height: 20px;
img {
width: 100%;
height: 100%;
}
}
.text {
margin-left: 4px;
height: 35px;
line-height: 35px;
}
.line {
margin-left: 7px;
margin-top: 16px;
width: 30px;
height: 2px;
background: rgba(174, 208, 255, 1);
}
}
}
.right-bone {
color: #777;
position: absolute;
top: 0;
right: -150px;
width: 150px;
height: 260px;
// background: pink;
.right-bone-item {
transform: skew(-30deg);
height: 35px;
margin-bottom: 15px;
margin-top: 5px;
display: flex;
justify-content: flex-start;
.line {
margin-right: 7px;
margin-top: 16px;
width: 30px;
height: 2px;
background: rgba(174, 208, 255, 1);
}
.text {
margin-right: 4px;
height: 35px;
line-height: 35px;
}
.icon {
margin-top: 7px;
width: 20px;
height: 20px;
img {
width: 100%;
height: 100%;
}
}
}
}
}
.bottom-bone {
position: absolute;
top: 280px;
right: 360px;
width: 3px;
height: 260px;
background: #90caf9;
transform: skew(-30deg);
z-index: 1;
.left-bone {
color: #777;
position: absolute;
top: 0;
left: -150px;
width: 150px;
height: 260px;
// background: orange;
.left-bone-item {
transform: skew(30deg);
height: 35px;
margin-bottom: 5px;
margin-top: 15px;
// background: #fff;
display: flex;
justify-content: flex-end;
.icon {
margin-top: 7px;
width: 20px;
height: 20px;
img {
width: 100%;
height: 100%;
}
}
.text {
margin-left: 4px;
height: 35px;
line-height: 35px;
}
.line {
margin-left: 7px;
margin-top: 16px;
width: 30px;
height: 2px;
background: rgba(174, 208, 255, 1);
}
}
}
.right-bone {
color: #777;
position: absolute;
top: 0;
right: -150px;
width: 150px;
height: 260px;
// background: pink;
.right-bone-item {
transform: skew(30deg);
height: 35px;
margin-bottom: 15px;
margin-top: 5px;
display: flex;
justify-content: flex-start;
.line {
margin-right: 7px;
margin-top: 16px;
width: 30px;
height: 2px;
background: rgba(174, 208, 255, 1);
}
.text {
margin-right: 4px;
height: 35px;
line-height: 35px;
}
.icon {
margin-top: 7px;
width: 20px;
height: 20px;
img {
width: 100%;
height: 100%;
}
}
}
}
}
.bottom-bone1 {
position: absolute;
top: 280px;
right: 660px;
width: 3px;
height: 260px;
background: #90caf9;
transform: skew(-30deg);
z-index: 1;
.left-bone {
color: #777;
position: absolute;
top: 0;
left: -150px;
width: 150px;
height: 260px;
// background: orange;
.left-bone-item {
transform: skew(30deg);
height: 35px;
margin-bottom: 5px;
margin-top: 15px;
// background: #fff;
display: flex;
justify-content: flex-end;
.icon {
margin-top: 7px;
width: 20px;
height: 20px;
img {
width: 100%;
height: 100%;
}
}
.text {
margin-left: 4px;
height: 35px;
line-height: 35px;
}
.line {
margin-left: 7px;
margin-top: 16px;
width: 30px;
height: 2px;
background: rgba(174, 208, 255, 1);
}
}
}
.right-bone {
color: #777;
position: absolute;
top: 0;
right: -150px;
width: 150px;
height: 260px;
// background: pink;
.right-bone-item {
transform: skew(30deg);
height: 35px;
margin-bottom: 15px;
margin-top: 5px;
display: flex;
justify-content: flex-start;
.line {
margin-right: 7px;
margin-top: 16px;
width: 30px;
height: 2px;
background: rgba(174, 208, 255, 1);
}
.text {
margin-right: 4px;
height: 35px;
line-height: 35px;
}
.icon {
margin-top: 7px;
width: 20px;
height: 20px;
img {
width: 100%;
height: 100%;
}
}
}
}
}
.bottom-bone2 {
position: absolute;
top: 280px;
right: 960px;
width: 3px;
height: 260px;
background: #90caf9;
transform: skew(-30deg);
z-index: 1;
.left-bone {
color: #777;
position: absolute;
top: 0;
left: -150px;
width: 150px;
height: 260px;
// background: orange;
.left-bone-item {
transform: skew(30deg);
height: 35px;
margin-bottom: 5px;
margin-top: 15px;
// background: #fff;
display: flex;
justify-content: flex-end;
.icon {
margin-top: 7px;
width: 20px;
height: 20px;
img {
width: 100%;
height: 100%;
}
}
.text {
margin-left: 4px;
height: 35px;
line-height: 35px;
}
.line {
margin-left: 7px;
margin-top: 16px;
width: 30px;
height: 2px;
background: rgba(174, 208, 255, 1);
}
}
}
.right-bone {
color: #777;
position: absolute;
top: 0;
right: -150px;
width: 150px;
height: 260px;
// background: pink;
.right-bone-item {
transform: skew(30deg);
height: 35px;
margin-bottom: 15px;
margin-top: 5px;
display: flex;
justify-content: flex-start;
.line {
margin-right: 7px;
margin-top: 16px;
width: 30px;
height: 2px;
background: rgba(174, 208, 255, 1);
}
.text {
margin-right: 4px;
height: 35px;
line-height: 35px;
}
.icon {
margin-top: 7px;
width: 20px;
height: 20px;
img {
width: 100%;
height: 100%;
}
}
}
}
}
</style>
[
{
"name": "经济",
"count": 12
},
{
"name": "科技",
"count": 33
},
{
"name": "军事",
"count": 15
},
{
"name": "安全",
"count": 3
}
]
\ No newline at end of file
<template> <template>
<div class="fishbone"> <div class="fishbone">
<div class="main-line"></div> <div class="main-line"></div>
<div class="top-bone"> <div v-for="(causeGroup, groupIndex) in fishboneData.causes" :key="groupIndex" :class="getBoneClass(groupIndex)">
<div class="left-bone"> <div class="left-bone">
<div class="left-bone-item"> <div class="left-bone-item" v-for="(item, index) in getLeftItems(causeGroup.causes)" :key="index">
<div class="icon"> <!-- <div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" /> <img :src="item.picture" alt="" />
</div> </div> -->
<div class="text">{{ "商汤科技" }}</div> <div class="text">{{ item.name }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div> <div class="line"></div>
</div> </div>
</div> </div>
<div class="right-bone"> <div class="right-bone">
<div class="right-bone-item"> <div class="right-bone-item" v-for="(item, index) in getRightItems(causeGroup.causes)" :key="index">
<div class="line"></div> <div class="line"></div>
<div class="text">{{ "华为" }}</div> <div class="text">{{ item.name }}</div>
<div class="icon"> <!-- <div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" /> <img :src="item.picture" :alt="item.name" />
</div> -->
</div> </div>
</div> </div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div> </div>
</div> </div>
<div class="right-bone-item"> </template>
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
</div>
</div>
<div class="top-bone1">
<div class="left-bone">
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div> <script setup>
<div class="line"></div> import { getChainFishbone } from "@/api/exportControl";
</div> import { onMounted, ref } from "vue";
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div> const chainId = ref(1);
<div class="line"></div> const fishboneData = ref({
</div> text: "",
<div class="left-bone-item"> causes: []
<div class="icon"> });
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
</div>
<div class="right-bone">
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
</div>
</div>
<div class="top-bone2">
<div class="left-bone">
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div> // 根据索引确定鱼骨图位置类名
<div class="line"></div> const getBoneClass = index => {
</div> const positions = ["top-bone", "top-bone1", "top-bone2", "bottom-bone", "bottom-bone1", "bottom-bone2"];
<div class="left-bone-item"> return positions[index] || "top-bone";
<div class="icon"> };
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div> // 获取左侧显示的项目(前半部分)
<div class="line"></div> const getLeftItems = items => {
</div> const midpoint = Math.ceil(items.length / 2);
<div class="left-bone-item"> return items.slice(0, midpoint);
<div class="icon"> };
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
</div>
<div class="right-bone">
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
</div>
</div>
<div class="bottom-bone">
<div class="left-bone">
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div> // 获取右侧显示的项目(后半部分)
<div class="line"></div> const getRightItems = items => {
</div> const midpoint = Math.ceil(items.length / 2);
<div class="left-bone-item"> return items.slice(midpoint);
<div class="icon"> };
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
</div>
<div class="right-bone">
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
</div>
</div>
<div class="bottom-bone1">
<div class="left-bone">
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div> onMounted(async () => {
<div class="line"></div> try {
</div> const chainFishboneData = await getChainFishbone(chainId.value);
<div class="left-bone-item"> fishboneData.value = chainFishboneData ?? {
<div class="icon"> text: "",
<img src="../../assets/images/company-logo1.png" alt="" /> causes: []
</div> };
} catch (error) {
<div class="text">{{ "商汤科技" }}</div> console.log(error);
<div class="line"></div> }
</div> });
<div class="left-bone-item"> </script>
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
</div>
<div class="right-bone">
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
</div>
</div>
<div class="bottom-bone2">
<div class="left-bone">
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
<div class="left-bone-item">
<div class="icon">
<img src="../../assets/images/company-logo1.png" alt="" />
</div>
<div class="text">{{ "商汤科技" }}</div>
<div class="line"></div>
</div>
</div>
<div class="right-bone">
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
<div class="right-bone-item">
<div class="line"></div>
<div class="text">{{ "华为" }}</div>
<div class="icon">
<img src="../../assets/images/company-logo2.png" alt="" />
</div>
</div>
</div>
</div>
</div>
</template>
<style lang="scss" scoped> <style lang="scss" scoped>
/* ... 原有的样式保持不变 ... */
.fishbone { .fishbone {
position: relative; position: relative;
width: 100%; width: 100%;
...@@ -486,6 +82,7 @@ ...@@ -486,6 +82,7 @@
background: rgba(174, 208, 255, 1); background: rgba(174, 208, 255, 1);
} }
} }
.top-bone { .top-bone {
position: absolute; position: absolute;
top: 20px; top: 20px;
...@@ -502,13 +99,11 @@ ...@@ -502,13 +99,11 @@
left: -150px; left: -150px;
width: 150px; width: 150px;
height: 260px; height: 260px;
// background: orange;
.left-bone-item { .left-bone-item {
transform: skew(-30deg); transform: skew(-30deg);
height: 35px; height: 35px;
margin-bottom: 5px; margin-bottom: 5px;
margin-top: 15px; margin-top: 15px;
// background: #fff;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
.icon { .icon {
...@@ -541,7 +136,6 @@ ...@@ -541,7 +136,6 @@
right: -150px; right: -150px;
width: 150px; width: 150px;
height: 260px; height: 260px;
// background: pink;
.right-bone-item { .right-bone-item {
transform: skew(-30deg); transform: skew(-30deg);
height: 35px; height: 35px;
...@@ -549,7 +143,6 @@ ...@@ -549,7 +143,6 @@
margin-top: 5px; margin-top: 5px;
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
.line { .line {
margin-right: 7px; margin-right: 7px;
margin-top: 16px; margin-top: 16px;
...@@ -557,7 +150,6 @@ ...@@ -557,7 +150,6 @@
height: 2px; height: 2px;
background: rgba(174, 208, 255, 1); background: rgba(174, 208, 255, 1);
} }
.text { .text {
margin-right: 4px; margin-right: 4px;
height: 35px; height: 35px;
...@@ -575,6 +167,7 @@ ...@@ -575,6 +167,7 @@
} }
} }
} }
.top-bone1 { .top-bone1 {
position: absolute; position: absolute;
top: 20px; top: 20px;
...@@ -591,13 +184,11 @@ ...@@ -591,13 +184,11 @@
left: -150px; left: -150px;
width: 150px; width: 150px;
height: 260px; height: 260px;
// background: orange;
.left-bone-item { .left-bone-item {
transform: skew(-30deg); transform: skew(-30deg);
height: 35px; height: 35px;
margin-bottom: 5px; margin-bottom: 5px;
margin-top: 15px; margin-top: 15px;
// background: #fff;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
.icon { .icon {
...@@ -630,7 +221,6 @@ ...@@ -630,7 +221,6 @@
right: -150px; right: -150px;
width: 150px; width: 150px;
height: 260px; height: 260px;
// background: pink;
.right-bone-item { .right-bone-item {
transform: skew(-30deg); transform: skew(-30deg);
height: 35px; height: 35px;
...@@ -638,7 +228,6 @@ ...@@ -638,7 +228,6 @@
margin-top: 5px; margin-top: 5px;
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
.line { .line {
margin-right: 7px; margin-right: 7px;
margin-top: 16px; margin-top: 16px;
...@@ -646,7 +235,6 @@ ...@@ -646,7 +235,6 @@
height: 2px; height: 2px;
background: rgba(174, 208, 255, 1); background: rgba(174, 208, 255, 1);
} }
.text { .text {
margin-right: 4px; margin-right: 4px;
height: 35px; height: 35px;
...@@ -664,6 +252,7 @@ ...@@ -664,6 +252,7 @@
} }
} }
} }
.top-bone2 { .top-bone2 {
position: absolute; position: absolute;
top: 20px; top: 20px;
...@@ -680,13 +269,11 @@ ...@@ -680,13 +269,11 @@
left: -150px; left: -150px;
width: 150px; width: 150px;
height: 260px; height: 260px;
// background: orange;
.left-bone-item { .left-bone-item {
transform: skew(-30deg); transform: skew(-30deg);
height: 35px; height: 35px;
margin-bottom: 5px; margin-bottom: 5px;
margin-top: 15px; margin-top: 15px;
// background: #fff;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
.icon { .icon {
...@@ -719,7 +306,6 @@ ...@@ -719,7 +306,6 @@
right: -150px; right: -150px;
width: 150px; width: 150px;
height: 260px; height: 260px;
// background: pink;
.right-bone-item { .right-bone-item {
transform: skew(-30deg); transform: skew(-30deg);
height: 35px; height: 35px;
...@@ -727,7 +313,6 @@ ...@@ -727,7 +313,6 @@
margin-top: 5px; margin-top: 5px;
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
.line { .line {
margin-right: 7px; margin-right: 7px;
margin-top: 16px; margin-top: 16px;
...@@ -735,7 +320,6 @@ ...@@ -735,7 +320,6 @@
height: 2px; height: 2px;
background: rgba(174, 208, 255, 1); background: rgba(174, 208, 255, 1);
} }
.text { .text {
margin-right: 4px; margin-right: 4px;
height: 35px; height: 35px;
...@@ -753,6 +337,7 @@ ...@@ -753,6 +337,7 @@
} }
} }
} }
.bottom-bone { .bottom-bone {
position: absolute; position: absolute;
top: 280px; top: 280px;
...@@ -769,13 +354,11 @@ ...@@ -769,13 +354,11 @@
left: -150px; left: -150px;
width: 150px; width: 150px;
height: 260px; height: 260px;
// background: orange;
.left-bone-item { .left-bone-item {
transform: skew(30deg); transform: skew(30deg);
height: 35px; height: 35px;
margin-bottom: 5px; margin-bottom: 5px;
margin-top: 15px; margin-top: 15px;
// background: #fff;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
.icon { .icon {
...@@ -808,7 +391,6 @@ ...@@ -808,7 +391,6 @@
right: -150px; right: -150px;
width: 150px; width: 150px;
height: 260px; height: 260px;
// background: pink;
.right-bone-item { .right-bone-item {
transform: skew(30deg); transform: skew(30deg);
height: 35px; height: 35px;
...@@ -816,7 +398,6 @@ ...@@ -816,7 +398,6 @@
margin-top: 5px; margin-top: 5px;
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
.line { .line {
margin-right: 7px; margin-right: 7px;
margin-top: 16px; margin-top: 16px;
...@@ -824,7 +405,6 @@ ...@@ -824,7 +405,6 @@
height: 2px; height: 2px;
background: rgba(174, 208, 255, 1); background: rgba(174, 208, 255, 1);
} }
.text { .text {
margin-right: 4px; margin-right: 4px;
height: 35px; height: 35px;
...@@ -842,6 +422,7 @@ ...@@ -842,6 +422,7 @@
} }
} }
} }
.bottom-bone1 { .bottom-bone1 {
position: absolute; position: absolute;
top: 280px; top: 280px;
...@@ -858,13 +439,11 @@ ...@@ -858,13 +439,11 @@
left: -150px; left: -150px;
width: 150px; width: 150px;
height: 260px; height: 260px;
// background: orange;
.left-bone-item { .left-bone-item {
transform: skew(30deg); transform: skew(30deg);
height: 35px; height: 35px;
margin-bottom: 5px; margin-bottom: 5px;
margin-top: 15px; margin-top: 15px;
// background: #fff;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
.icon { .icon {
...@@ -897,7 +476,6 @@ ...@@ -897,7 +476,6 @@
right: -150px; right: -150px;
width: 150px; width: 150px;
height: 260px; height: 260px;
// background: pink;
.right-bone-item { .right-bone-item {
transform: skew(30deg); transform: skew(30deg);
height: 35px; height: 35px;
...@@ -905,7 +483,6 @@ ...@@ -905,7 +483,6 @@
margin-top: 5px; margin-top: 5px;
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
.line { .line {
margin-right: 7px; margin-right: 7px;
margin-top: 16px; margin-top: 16px;
...@@ -913,7 +490,6 @@ ...@@ -913,7 +490,6 @@
height: 2px; height: 2px;
background: rgba(174, 208, 255, 1); background: rgba(174, 208, 255, 1);
} }
.text { .text {
margin-right: 4px; margin-right: 4px;
height: 35px; height: 35px;
...@@ -931,6 +507,7 @@ ...@@ -931,6 +507,7 @@
} }
} }
} }
.bottom-bone2 { .bottom-bone2 {
position: absolute; position: absolute;
top: 280px; top: 280px;
...@@ -947,13 +524,11 @@ ...@@ -947,13 +524,11 @@
left: -150px; left: -150px;
width: 150px; width: 150px;
height: 260px; height: 260px;
// background: orange;
.left-bone-item { .left-bone-item {
transform: skew(30deg); transform: skew(30deg);
height: 35px; height: 35px;
margin-bottom: 5px; margin-bottom: 5px;
margin-top: 15px; margin-top: 15px;
// background: #fff;
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;
.icon { .icon {
...@@ -986,7 +561,6 @@ ...@@ -986,7 +561,6 @@
right: -150px; right: -150px;
width: 150px; width: 150px;
height: 260px; height: 260px;
// background: pink;
.right-bone-item { .right-bone-item {
transform: skew(30deg); transform: skew(30deg);
height: 35px; height: 35px;
...@@ -994,7 +568,6 @@ ...@@ -994,7 +568,6 @@
margin-top: 5px; margin-top: 5px;
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
.line { .line {
margin-right: 7px; margin-right: 7px;
margin-top: 16px; margin-top: 16px;
...@@ -1002,7 +575,6 @@ ...@@ -1002,7 +575,6 @@
height: 2px; height: 2px;
background: rgba(174, 208, 255, 1); background: rgba(174, 208, 255, 1);
} }
.text { .text {
margin-right: 4px; margin-right: 4px;
height: 35px; height: 35px;
......
...@@ -70,7 +70,7 @@ ...@@ -70,7 +70,7 @@
</template> </template>
<script setup> <script setup>
import { ref, onMounted, shallowReactive, shallowRef } from "vue"; import { ref, onMounted, shallowReactive, shallowRef, watch } from "vue";
import CardCustom from "../../components/CardCustom.vue"; import CardCustom from "../../components/CardCustom.vue";
import Echarts from "@/components/Chart/index.vue"; import Echarts from "@/components/Chart/index.vue";
import Hint from "./hint.vue"; import Hint from "./hint.vue";
...@@ -88,19 +88,22 @@ import college9 from "../../assets/images/college9.png"; ...@@ -88,19 +88,22 @@ import college9 from "../../assets/images/college9.png";
import college10 from "../../assets/images/college10.png"; import college10 from "../../assets/images/college10.png";
import college11 from "../../assets/images/college11.png"; import college11 from "../../assets/images/college11.png";
import { getHorizontalBarChart2 } from "../../utils/charts"; import { getHorizontalBarChart2 } from "../../utils/charts";
const buttonList = [ import { getDomainDistribution, getChainEntities } from "@/api/exportControl";
import { useRoute } from "vue-router";
const route = useRoute();
const buttonList = ref([
{ id: 1, text: "新能源" }, { id: 1, text: "新能源" },
{ id: 2, text: "半导体" }, { id: 2, text: "半导体" },
{ id: 3, text: "跨境电商" }, { id: 3, text: "跨境电商" },
{ id: 4, text: "金融业" }, { id: 4, text: "金融业" },
{ id: 5, text: "军工" }, { id: 5, text: "军工" },
{ id: 6, text: "贸易" } { id: 6, text: "贸易" }
]; ]);
const activeButtonId = ref(buttonList[0].id); const activeButtonId = ref(buttonList.value[0].id);
const setActiveButtonId = id => { const setActiveButtonId = id => {
activeButtonId.value = id; activeButtonId.value = id;
}; };
const listData = [ const listData = ref([
{ {
name: "宁德时代新能源科技股份有限公司", name: "宁德时代新能源科技股份有限公司",
isUp: false isUp: false
...@@ -153,15 +156,68 @@ const listData = [ ...@@ -153,15 +156,68 @@ const listData = [
name: "上海派能能源科技股份有限公司", name: "上海派能能源科技股份有限公司",
isUp: false isUp: false
} }
]; ]);
const horizontalBarOptions = shallowRef({}); const horizontalBarOptions = shallowRef({});
onMounted(() => {
horizontalBarOptions.value = getHorizontalBarChart2( // 获取领域分布数据并更新图表
["贸易", "军工", "金融业", "跨境电商", "半导体", "新能源"], const fetchDomainDistribution = async () => {
[10, 21, 25, 79, 95, 109], try {
false const data = await getDomainDistribution(route.query.startTime);
); if (data && Array.isArray(data)) {
console.log("data data11", data);
// 按照 count 降序排列
const sortedData = data.sort((a, b) => a.count - b.count);
// 提取 y 轴数据(领域名称)
const yAxisData = sortedData.map(item => item.name);
// 提取 x 轴数据(数量)
const seriesData = sortedData.map(item => item.count);
// 更新图表配置
horizontalBarOptions.value = getHorizontalBarChart2(yAxisData, seriesData, false);
// 更新buttonList
buttonList.value = sortedData.map(item => ({
id: item.id,
text: item.name
}));
console.log("buttonList.value", buttonList.value);
setActiveButtonId(buttonList.value[0].id);
}
} catch (error) {
console.error("获取领域分布数据失败:", error);
}
};
const fetchChainEntities = async () => {
try {
const data = await getChainEntities(route.query.startTime, activeButtonId.value);
if (data && Array.isArray(data)) {
console.log("data data", data);
// 更新 listData
listData.value = data.map(item => ({
name: item.orgNameZh,
isUp: item.isUp
}));
}
} catch (error) {
console.error("获取产业链实体数据失败:", error);
}
};
onMounted(async () => {
fetchDomainDistribution();
// horizontalBarOptions.value = getHorizontalBarChart2(
// ["贸易", "军工", "金融业", "跨境电商", "半导体", "新能源"],
// [10, 21, 25, 79, 95, 109],
// false
// );
fetchChainEntities();
}); });
watch(() => activeButtonId.value, fetchChainEntities);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
...@@ -337,16 +393,19 @@ onMounted(() => { ...@@ -337,16 +393,19 @@ onMounted(() => {
} }
.listWrap { .listWrap {
flex: 1; flex: 1;
height: 42px;
min-height: 0; min-height: 0;
overflow: auto; overflow: auto;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
cursor: pointer;
.item { .item {
display: flex; display: flex;
align-items: center; align-items: center;
height: 42px; height: 42px;
border-bottom: 1px solid rgba(234, 236, 238, 1); border-bottom: 1px solid rgba(234, 236, 238, 1);
overflow: hidden; overflow: hidden;
flex-shrink: 0;
.index { .index {
width: 24px; width: 24px;
height: 24px; height: 24px;
......
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
<div class="infoWrap"> <div class="infoWrap">
<div class="name">{{ item.name }}</div> <div class="name">{{ item.name }}</div>
<div class="enName">{{ item.enName }}</div> <div class="enName">{{ item.enName }}</div>
<div class="party">{{ item.party }}</div> <div class="party">{{ item.position }}</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -257,15 +257,16 @@ onMounted(async () => { ...@@ -257,15 +257,16 @@ onMounted(async () => {
]); ]);
organizationInfo.value = { organizationInfo.value = {
img: panel1_1, img: panel1_1,
mingcheng: organizationInfoData?.orgName, mingcheng: organizationInfoData?.orgNameZh,
cuoshi: organizationInfoData?.cuoshi || "美国商务部工业与安全局", cuoshi: organizationInfoData?.cuoshi || "出口管制条例(EAR)、实体清单、商业管制清单(CCL)、232调查等",
zhize: organizationInfoData?.orgIntroduction || "--" zhize: organizationInfoData?.orgDuty || "--"
}; };
personLis.value = _.map(personListData, item => { personLis.value = _.map(organizationInfoData?.personList, item => {
return { return {
name: item.name, name: item.name,
enName: item.enName, enName: item.enName,
party: item.positionTitle, position: item.position,
party: item.party,
img: item.avatarUrl img: item.avatarUrl
}; };
}); });
......
...@@ -398,6 +398,7 @@ onMounted(() => { ...@@ -398,6 +398,7 @@ onMounted(() => {
margin-top: 21px; margin-top: 21px;
.left-box-bottom-item { .left-box-bottom-item {
display: flex; display: flex;
align-items: center;
margin-right: 32px; margin-right: 32px;
margin-top: 3px; margin-top: 3px;
height: 35px; height: 35px;
...@@ -419,7 +420,7 @@ onMounted(() => { ...@@ -419,7 +420,7 @@ onMounted(() => {
.name { .name {
color: rgba(95, 101, 108, 1); color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei; font-family: Microsoft YaHei;
font-size: 14px; font-size: 18px;
font-weight: 400; font-weight: 400;
line-height: 22px; line-height: 22px;
letter-spacing: 0px; letter-spacing: 0px;
......
...@@ -47,7 +47,7 @@ defineProps({ ...@@ -47,7 +47,7 @@ defineProps({
<style scoped> <style scoped>
.message-bubble { .message-bubble {
display: flex; display: flex;
max-width: 600px; max-width: 700px;
margin: 20px 0; margin: 20px 0;
} }
...@@ -81,6 +81,7 @@ defineProps({ ...@@ -81,6 +81,7 @@ defineProps({
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
margin-bottom: 8px; margin-bottom: 8px;
font-family: "微软雅黑";
} }
.name { .name {
...@@ -95,9 +96,10 @@ defineProps({ ...@@ -95,9 +96,10 @@ defineProps({
} }
.bubble-content { .bubble-content {
font-size: 14px; font-size: 16px;
line-height: 1.5; line-height: 1.5;
color: #333; color: #333;
font-family: "微软雅黑";
} }
.triangle { .triangle {
......
...@@ -37,10 +37,10 @@ defineProps({ ...@@ -37,10 +37,10 @@ defineProps({
}); });
</script> </script>
<style scoped> <style scoped lang="scss">
.info-card { .info-card {
max-width: 388px; max-width: 388px;
min-width: 300px; min-width: 200px;
height: 150px; height: 150px;
border-radius: 12px; border-radius: 12px;
background-color: white; background-color: white;
...@@ -76,10 +76,15 @@ defineProps({ ...@@ -76,10 +76,15 @@ defineProps({
} }
.main-title { .main-title {
font-family: $base-font-family;
font-size: 24px; font-size: 24px;
font-weight: 700; font-weight: 700;
color: #1f2937; color: #1f2937;
line-height: 1.2; line-height: 1.2;
max-width: 70%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
} }
.sub-title { .sub-title {
......
...@@ -19,7 +19,6 @@ ...@@ -19,7 +19,6 @@
</template> </template>
<script setup> <script setup>
const props = defineProps({ const props = defineProps({
listData: { listData: {
type: Array, type: Array,
...@@ -94,6 +93,7 @@ const handleItemClick = item => { ...@@ -94,6 +93,7 @@ const handleItemClick = item => {
} }
.news-title { .news-title {
font-family: "微软雅黑";
font-size: 16px; font-size: 16px;
font-weight: 700; font-weight: 700;
color: rgba(59, 65, 75, 1); color: rgba(59, 65, 75, 1);
...@@ -121,7 +121,9 @@ const handleItemClick = item => { ...@@ -121,7 +121,9 @@ const handleItemClick = item => {
} }
.news-description { .news-description {
font-family: "微软雅黑";
font-size: 16px; font-size: 16px;
font-weight: 400;
color: rgba(59, 65, 75, 1); color: rgba(59, 65, 75, 1);
line-height: 1.5; line-height: 1.5;
display: -webkit-box; display: -webkit-box;
......
...@@ -16,7 +16,7 @@ defineProps({ ...@@ -16,7 +16,7 @@ defineProps({
}); });
</script> </script>
<style scoped> <style scoped lang="scss">
.custom-title { .custom-title {
display: flex; display: flex;
align-items: center; align-items: center;
...@@ -43,7 +43,7 @@ defineProps({ ...@@ -43,7 +43,7 @@ defineProps({
.title-text { .title-text {
color: rgba(10, 18, 30, 1); color: rgba(10, 18, 30, 1);
font-size: 32px; font-size: 32px;
font-family: Microsoft YaHei; font-family: $base-font-family;
font-weight: bold; font-weight: bold;
margin-left: 20px; margin-left: 20px;
white-space: nowrap; white-space: nowrap;
......
...@@ -434,7 +434,7 @@ ...@@ -434,7 +434,7 @@
<template #default> <template #default>
<div class="box5"> <div class="box5">
<el-table <el-table
:data="paginatedData" :data="entitiesList"
class="sanction-table" class="sanction-table"
stripe stripe
empty-text="暂无数据" empty-text="暂无数据"
...@@ -473,14 +473,14 @@ ...@@ -473,14 +473,14 @@
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="strength" label="制裁强度" width="120" align="center"> <!-- <el-table-column prop="strength" label="制裁强度" width="120" align="center">
<template #default="scope"> <template #default="scope">
<div class="sanction-strength"> <div class="sanction-strength">
<div :class="['strength-bar', `strength-${scope.row.strength}`]"></div> <div :class="['strength-bar', `strength-${scope.row.strength}`]"></div>
<span>{{ strengthLabels[scope.row.strength] }}</span> <span>{{ strengthLabels[scope.row.strength] }}</span>
</div> </div>
</template> </template>
</el-table-column> </el-table-column> -->
<!-- <el-table-column prop="revenue" label="营收(亿元)" width="140" align="right"> <!-- <el-table-column prop="revenue" label="营收(亿元)" width="140" align="right">
<template #default="scope"> <template #default="scope">
...@@ -492,12 +492,13 @@ ...@@ -492,12 +492,13 @@
</template> </template>
</el-table-column> --> </el-table-column> -->
<el-table-column prop="revenue" label="50%规则子企业" width="140" align="right"> <el-table-column prop="revenue" label="50%规则子企业" width="280" align="right">
<template #default="scope"> <template #default="scope">
<span <span
:class="['revenue-cell', scope.row.revenue === '无营收数据' ? 'no-revenue' : '']" :class="['revenue-cell', scope.row.revenue === '无营收数据' ? 'no-revenue' : '']"
> >
{{ scope.row.revenue }} {{ scope.row.name }}...等
<span style="color: #409eff">{{ scope.row.ruleOrgCount }}家> </span>
</span> </span>
</template> </template>
</el-table-column> </el-table-column>
...@@ -514,6 +515,7 @@ ...@@ -514,6 +515,7 @@
:pager-count="5" :pager-count="5"
layout="prev, pager, next" layout="prev, pager, next"
background background
@current-change="handlePageChange"
/> />
</div> </div>
</div> </div>
...@@ -561,6 +563,7 @@ import dotIcon from "./assets/images/info2-icon.png"; ...@@ -561,6 +563,7 @@ import dotIcon from "./assets/images/info2-icon.png";
import entityIcon from "./assets/images/icon-entity.png"; import entityIcon from "./assets/images/icon-entity.png";
import newsImg from "@/assets/images/news-img.png"; import newsImg from "@/assets/images/news-img.png";
import newsImg1 from "@/assets/images/newsImg1.png";
import { getHotBills, getBillsByType, getHylyList } from "@/api/home"; import { getHotBills, getBillsByType, getHylyList } from "@/api/home";
...@@ -598,7 +601,9 @@ import { ...@@ -598,7 +601,9 @@ import {
getEntitiesDataInfo, getEntitiesDataInfo,
getIndustryCountByYear, getIndustryCountByYear,
getCountDomainByYear, getCountDomainByYear,
getSanctionsInfoCount getSanctionsInfoCount,
getEntitiesList,
getSanctionProcess
} from "@/api/exportControl"; } from "@/api/exportControl";
import { getMultipleBarChart_m } from "./utils/charts"; import { getMultipleBarChart_m } from "./utils/charts";
import { formatAnyDateToChinese } from "./utils"; import { formatAnyDateToChinese } from "./utils";
...@@ -619,48 +624,67 @@ const trendOption = ref({}); ...@@ -619,48 +624,67 @@ const trendOption = ref({});
const tableData1 = ref([]); const tableData1 = ref([]);
// 历次制裁过程 // 历次制裁过程
const sanctionProcessList = ref([]); const sanctionProcessList = ref([]);
// 制裁实体清单
const entitiesList = ref([]);
onMounted(async () => { onMounted(async () => {
try { try {
const [dataCount, entitiesDataInfo, industryCountByYear, countDomainByYear, sanctionsInfoCount = []] = await Promise.all([ const [dataCount, entitiesDataInfo, industryCountByYear, countDomainByYear, sanctionsInfoCount, entityBody] =
await Promise.all([
getEntitiesDataCount(), getEntitiesDataCount(),
getEntitiesDataInfo(), getEntitiesDataInfo(),
getIndustryCountByYear(), getIndustryCountByYear(),
getCountDomainByYear(), getCountDomainByYear()
getSanctionsInfoCount() // getSanctionsInfoCount()
// getEntitiesList("实体清单")
]); ]);
infoList.value[0].num = dataCount; infoList.value[0].num = dataCount;
const entityList = _.map(entitiesDataInfo?.entities ?? [], ({ entityNameZh, entityName }) => { const entityList = _.map(entitiesDataInfo?.sanEntities ?? [], ({ entityNameZh, entityName }) => {
return { name: entityNameZh, enName: entityName }; return { name: entityNameZh, enName: entityName };
}); });
entitiesDataInfoReactive.value = { entitiesDataInfoReactive.value = {
entityList, entityList,
chNum: entitiesDataInfo?.chNum, chNum: entitiesDataInfo?.cnEntityCount,
domains: entitiesDataInfo?.domains ?? [], domains: entitiesDataInfo?.domains ?? [],
startTime: formatAnyDateToChinese(entitiesDataInfo?.startTime ?? ""), // startTime: formatAnyDateToChinese(entitiesDataInfo?.startTime ?? ""),
startTime: entitiesDataInfo.postDate,
rawStartTime: entitiesDataInfo?.startTime ?? "", rawStartTime: entitiesDataInfo?.startTime ?? "",
orgName: entitiesDataInfo?.organization?.orgName orgName: entitiesDataInfo?.postOrgName
}; };
const list = _.chain(industryCountByYear).filter("year").orderBy("year", "desc").value(); const list = _.chain(industryCountByYear).filter("year").orderBy("year", "desc").value();
const total = _.sumBy(list, "maxCount"); const total = _.sumBy(list, "count");
tableData1.value = _.map(list, item => { tableData1.value = _.map(list, item => {
return { return {
year: item.year, year: item.year,
num: item.maxCount, num: item.count,
percent: item.maxCount / total, percent: item.count / total,
tags: item.maxDomain.split(",") tags: item.domain
}; };
}); }).slice(0, 5);
console.log("tableData1", tableData1.value);
trendOption.value = getMultipleBarChart_m(countDomainByYear); trendOption.value = getMultipleBarChart_m(countDomainByYear);
sanctionProcessList.value = _.map(_.slice(sanctionsInfoCount, 0, 5), item => { // sanctionProcessList.value = _.map(_.slice(sanctionsInfoCount, 0, 5), item => {
return { // return {
title: item.tittle, // title: item.tittle,
desc: `${item.entitiesChNum} 家中国实体`, // desc: `${item.entitiesChNum} 家中国实体`,
content: // content:
item.sanReason || // item.sanReason ||
"2025年3月25日,美国商务部工业与安全局以从事有悖于美国国家安全和外交政策利益的活动为由,宣布将来自中国的54家实体新增至“实体清单”。" // "2025年3月25日,美国商务部工业与安全局以从事有悖于美国国家安全和外交政策利益的活动为由,宣布将来自中国的54家实体新增至“实体清单”。"
}; // };
}); // });
await fetchEntitiesList(currentPage.value, pageSize.value);
await fetchSanctionProcess(1, pageSize.value);
// console.log("entitiesList entitiesList", entityBody);
// entitiesList.value = _.map(entityBody.content, item => {
// return {
// ...item,
// name: item.entityNameZh,
// enName: item.entityName,
// domains: item.techDomains,
// sanctionDate: item.startTime
// };
// });
// console.log("entitiesList entitiesList 1", entitiesList.value);
} catch (err) { } catch (err) {
console.log(err); console.log(err);
} }
...@@ -683,7 +707,7 @@ const handleToDetail = () => { ...@@ -683,7 +707,7 @@ const handleToDetail = () => {
const route = router.resolve({ const route = router.resolve({
path: "/exportControlAnalysis", path: "/exportControlAnalysis",
query: { query: {
startTime: entitiesDataInfoReactive.value.rawStartTime startTime: entitiesDataInfoReactive.value.startTime
} }
}); });
window.open(route.href, "_blank"); window.open(route.href, "_blank");
...@@ -772,27 +796,27 @@ const customNewsData = ref([ ...@@ -772,27 +796,27 @@ const customNewsData = ref([
}, },
{ {
image: newsImg, image: newsImg,
title: "美国智库激辩人工智能监管路径", title: "布鲁金斯学会称美国低估中国在“印太”战略",
time: "11-4", time: "11-3",
source: "华盛顿邮报", source: "纽约时报",
description: "各方就AI监管模式展开讨论。有观点认为碎片化州级监管比全面联邦法规更灵活,也有分析..." description: "分析认为,当美国注意力被其他地区分散时,中国通过外交、发展和防务多管齐下,系统性......"
}, },
{ {
image: newsImg, image: newsImg1,
title: "美国智库激辩人工智能监管路径", title: "五角大楼指令引发智库与国防部“脱钩”震荡",
time: "11-4", time: "11-3",
source: "华盛顿邮报", source: "洛杉矶时报",
description: "各方就AI监管模式展开讨论。有观点认为碎片化州级监管比全面联邦法规更灵活,也有分析..." description: "美国国防部长下令全面暂停部内人员参与所有智库活动,标志着传统的“旋转门”关系发生......"
}, },
{ {
image: newsImg, image: newsImg,
title: "美国智库激辩人工智能监管路径", title: "CSIS建议美国建立跨机构AI基准测试体系",
time: "11-4", time: "11-3",
source: "华盛顿邮报", source: "福克斯新闻网",
description: "各方就AI监管模式展开讨论。有观点认为碎片化州级监管比全面联邦法规更灵活,也有分析..." description: "指出美国《人工智能行动计划》忽视了基准测试这一关键环节,建议由国家标准与技术研究........."
}, },
{ {
image: newsImg, image: newsImg1,
title: "美国智库激辩人工智能监管路径", title: "美国智库激辩人工智能监管路径",
time: "11-4", time: "11-4",
source: "华盛顿邮报", source: "华盛顿邮报",
...@@ -875,6 +899,53 @@ const getStatus = _percent => { ...@@ -875,6 +899,53 @@ const getStatus = _percent => {
// 制裁实体 // 制裁实体
const currentPage = ref(1); // 默认显示第5页 const currentPage = ref(1); // 默认显示第5页
const pageSize = ref(10); const pageSize = ref(10);
const total = ref(0);
// 获取实体清单数据
const fetchEntitiesList = async (page = 1, size = 10) => {
try {
const res = await getEntitiesList("实体清单", page, size);
if (res) {
entitiesList.value = res.content.map(item => ({
...item,
name: item.entityNameZh,
enName: item.entityName,
domains: item.techDomains,
sanctionDate: item.startTime
}));
total.value = res.totalElements;
currentPage.value = res.number + 1; // API返回的页码从0开始,前端从1开始
}
} catch (err) {
console.error(err);
}
};
// 获取历次制裁过程数据
const fetchSanctionProcess = async (page = 1, size = 10) => {
try {
const res = await getSanctionProcess("实体清单", page, size);
if (res) {
sanctionProcessList.value = res.content.slice(0, 5).map(item => ({
...item,
title: item.name,
desc: `${item.cnEntityCount} 家中国实体`,
content:
item.summary ||
"2025年3月25日,美国商务部工业与安全局以从事有悖于美国国家安全和外交政策利益的活动为由,宣布将来自中国的54家实体新增至“实体清单”。"
}));
}
} catch (err) {
console.error(err);
}
};
// 分页改变时的处理函数
const handlePageChange = page => {
currentPage.value = page;
fetchEntitiesList(page, pageSize.value);
};
const searchKeyword = ref(""); const searchKeyword = ref("");
const strengthLabels = { const strengthLabels = {
strong: "强", strong: "强",
...@@ -883,141 +954,141 @@ const strengthLabels = { ...@@ -883,141 +954,141 @@ const strengthLabels = {
none: "无" none: "无"
}; };
// 模拟数据 // 模拟数据
const mockData = [ // const mockData = [
{ // {
name: "科大讯飞股份有限公司", // name: "科大讯飞股份有限公司",
domains: ["人工智能"], // domains: ["人工智能"],
sanctionDate: "2025年9月", // sanctionDate: "2025年9月",
strength: "strong", // strength: "strong",
revenue: "325" // revenue: "325"
}, // },
{ // {
name: "华为技术有限公司", // name: "华为技术有限公司",
domains: ["通信网络", "集成电路"], // domains: ["通信网络", "集成电路"],
sanctionDate: "2025年9月", // sanctionDate: "2025年9月",
strength: "medium", // strength: "medium",
revenue: "290" // revenue: "290"
}, // },
{ // {
name: "中国航空工业集团", // name: "中国航空工业集团",
domains: ["航空航天"], // domains: ["航空航天"],
sanctionDate: "2025年9月", // sanctionDate: "2025年9月",
strength: "medium", // strength: "medium",
revenue: "288" // revenue: "288"
}, // },
{ // {
name: "杭州海康威视数字技术股份有限公司", // name: "杭州海康威视数字技术股份有限公司",
domains: ["人工智能"], // domains: ["人工智能"],
sanctionDate: "2025年9月", // sanctionDate: "2025年9月",
strength: "weak", // strength: "weak",
revenue: "203" // revenue: "203"
}, // },
{ // {
name: "浪潮集团有限公司", // name: "浪潮集团有限公司",
domains: ["人工智能"], // domains: ["人工智能"],
sanctionDate: "2025年9月", // sanctionDate: "2025年9月",
strength: "medium", // strength: "medium",
revenue: "195" // revenue: "195"
}, // },
{ // {
name: "中芯国际集成电路制造有限公司", // name: "中芯国际集成电路制造有限公司",
domains: ["集成电路"], // domains: ["集成电路"],
sanctionDate: "2025年9月", // sanctionDate: "2025年9月",
strength: "medium", // strength: "medium",
revenue: "190" // revenue: "190"
}, // },
{ // {
name: "北京复旦微电子技术有限公司", // name: "北京复旦微电子技术有限公司",
domains: ["集成电路"], // domains: ["集成电路"],
sanctionDate: "2025年9月", // sanctionDate: "2025年9月",
strength: "medium", // strength: "medium",
revenue: "184" // revenue: "184"
}, // },
{ // {
name: "哈尔滨工业大学", // name: "哈尔滨工业大学",
domains: ["人工智能", "集成电路"], // domains: ["人工智能", "集成电路"],
sanctionDate: "2025年9月", // sanctionDate: "2025年9月",
strength: "medium", // strength: "medium",
revenue: "无营收数据" // revenue: "无营收数据"
}, // },
{ // {
name: "ZTE中兴", // name: "ZTE中兴",
domains: ["通信网络", "集成电路"], // domains: ["通信网络", "集成电路"],
sanctionDate: "2025年9月", // sanctionDate: "2025年9月",
strength: "medium", // strength: "medium",
revenue: "154" // revenue: "154"
}, // },
{ // {
name: "中兴通讯股份有限公司", // name: "中兴通讯股份有限公司",
domains: ["通信网络", "集成电路"], // domains: ["通信网络", "集成电路"],
sanctionDate: "2025年9月", // sanctionDate: "2025年9月",
strength: "medium", // strength: "medium",
revenue: "117" // revenue: "117"
}, // },
{ // {
name: "大疆创新科技有限公司", // name: "大疆创新科技有限公司",
domains: ["航空航天"], // domains: ["航空航天"],
sanctionDate: "2025年9月", // sanctionDate: "2025年9月",
strength: "medium", // strength: "medium",
revenue: "1" // revenue: "1"
} // }
]; // ];
// 生成更多数据以模拟1329家实体 // 生成更多数据以模拟1329家实体
const generateMoreData = () => { // const generateMoreData = () => {
const moreData = []; // const moreData = [];
const companySuffixes = ["有限公司", "集团", "股份有限公司", "技术有限公司", "研究所"]; // const companySuffixes = ["有限公司", "集团", "股份有限公司", "技术有限公司", "研究所"];
const domainsList = [ // const domainsList = [
["人工智能"], // ["人工智能"],
["通信网络"], // ["通信网络"],
["航空航天"], // ["航空航天"],
["集成电路"], // ["集成电路"],
["人工智能", "集成电路"], // ["人工智能", "集成电路"],
["通信网络", "集成电路"], // ["通信网络", "集成电路"],
["航空航天", "人工智能"] // ["航空航天", "人工智能"]
]; // ];
const strengths = ["strong", "medium", "weak"]; // const strengths = ["strong", "medium", "weak"];
for (let i = 0; i < 1318; i++) { // for (let i = 0; i < 1318; i++) {
const nameSuffix = companySuffixes[Math.floor(Math.random() * companySuffixes.length)]; // const nameSuffix = companySuffixes[Math.floor(Math.random() * companySuffixes.length)];
const companyName = `实体${i + 12}${nameSuffix}`; // const companyName = `实体${i + 12}${nameSuffix}`;
const domains = domainsList[Math.floor(Math.random() * domainsList.length)]; // const domains = domainsList[Math.floor(Math.random() * domainsList.length)];
const strength = strengths[Math.floor(Math.random() * strengths.length)]; // const strength = strengths[Math.floor(Math.random() * strengths.length)];
const revenue = Math.floor(Math.random() * 400) + 1; // const revenue = Math.floor(Math.random() * 400) + 1;
moreData.push({ // moreData.push({
name: companyName, // name: companyName,
domains: domains, // domains: domains,
sanctionDate: "2025年9月", // sanctionDate: "2025年9月",
strength: strength, // strength: strength,
revenue: revenue.toString() // revenue: revenue.toString()
}); // });
} // }
return moreData; // return moreData;
}; // };
const allData = [...mockData, ...generateMoreData()]; // const allData = [...mockData, ...generateMoreData()];
// 计算属性 // 计算属性
const total = computed(() => allData.length); // const total = computed(() => allData.length);
const totalPages = computed(() => Math.ceil(total.value / pageSize.value)); // const totalPages = computed(() => Math.ceil(total.value / pageSize.value));
const filteredData = computed(() => { // const filteredData = computed(() => {
if (!searchKeyword.value) return allData; // if (!searchKeyword.value) return allData;
const keyword = searchKeyword.value.toLowerCase(); // const keyword = searchKeyword.value.toLowerCase();
return allData.filter( // return allData.filter(
item => item.name.toLowerCase().includes(keyword) || item.domains.some(domain => domain.toLowerCase().includes(keyword)) // item => item.name.toLowerCase().includes(keyword) || item.domains.some(domain => domain.toLowerCase().includes(keyword))
); // );
}); // });
const paginatedData = computed(() => { // const paginatedData = computed(() => {
const start = (currentPage.value - 1) * pageSize.value; // const start = (currentPage.value - 1) * pageSize.value;
const end = start + pageSize.value; // const end = start + pageSize.value;
return filteredData.value.slice(start, end); // return filteredData.value.slice(start, end);
}); // });
const warningList = ref([ const warningList = ref([
{ {
...@@ -1798,7 +1869,7 @@ onMounted(async () => { ...@@ -1798,7 +1869,7 @@ onMounted(async () => {
} }
.home-main-header-footer-link, .home-main-header-footer-link,
.home-main-header-footer-info { .home-main-header-footer-info {
width: 1600px; width: 100%;
display: flex; display: flex;
justify-content: center; justify-content: center;
gap: 16px; gap: 16px;
......
{
"code": 200,
"message": "操作成功",
"success": true,
"data": {
"content": [
{
"createTime": null,
"updateTime": null,
"id": "3357",
"entityName": "Arrow Electronics (Hong Kong) Co., Ltd.",
"sanTypeId": 1,
"entityType": 2,
"entityId": null,
"entityNameZh": "艾睿电子(香港)有限公司",
"countryId": "0101",
"sanReason": "对于所有受《出口管理条例》(EAR)管制的项目,协助为伊朗代理人(包括哈马斯(Hamas))购买美国原产的电子元件,用于武器化无人机(UAV),违反美国国家安全;协助为伊朗代理人操作的武器化无人驾驶航空系统(UAS)购买美国原产的电子元件。",
"sanIntensity": "\u0000",
"startTime": "2025-10-09",
"endTime": null,
"isKey": "\u0000",
"techDomainList": null,
"techDomains": [],
"ruleOrgCount": 39
},
{
"createTime": null,
"updateTime": null,
"id": "3ef6b0b3-4f6a-4",
"entityName": "Shanghai Langqing Electronic Technology Co.",
"sanTypeId": 1,
"entityType": 2,
"entityId": null,
"entityNameZh": "上海朗晴电子科技有限公司",
"countryId": "0101",
"sanReason": "对于所有受《出口管理条例》(EAR)管辖的物品",
"sanIntensity": "\u0000",
"startTime": "2025-10-09",
"endTime": null,
"isKey": "\u0000",
"techDomainList": null,
"techDomains": [
"经济"
],
"ruleOrgCount": 93
},
{
"createTime": null,
"updateTime": null,
"id": "81fc1a85-a2be-4",
"entityName": "Easy Fly Intelligent Technology Co., Ltd.",
"sanTypeId": 1,
"entityType": 2,
"entityId": null,
"entityNameZh": "易飞智能科技有限公司",
"countryId": "0101",
"sanReason": "对于所有受《出口管理条例》(EAR)管辖的物品",
"sanIntensity": "\u0000",
"startTime": "2025-10-09",
"endTime": null,
"isKey": "\u0000",
"techDomainList": null,
"techDomains": [
"科技"
],
"ruleOrgCount": 18
},
{
"createTime": null,
"updateTime": null,
"id": "2813d17d-8edd-4",
"entityName": "Beijing Rageflight Technology Co., Ltd.",
"sanTypeId": 1,
"entityType": 2,
"entityId": null,
"entityNameZh": "北京锐飞科技有限公司",
"countryId": "0101",
"sanReason": "对于所有受《出口管理条例》(EAR)管辖的物品,为伊朗代理人操作的武器化无人驾驶航空系统(UAS)采购美国原产电子组件提供了便利。",
"sanIntensity": "\u0000",
"startTime": "2025-10-09",
"endTime": null,
"isKey": "\u0000",
"techDomainList": null,
"techDomains": [
"科技",
"军事"
],
"ruleOrgCount": 2
},
{
"createTime": null,
"updateTime": null,
"id": "f7bf81c6-9f5c-4",
"entityName": "Beijing Kevins Technology Development Co., Ltd.",
"sanTypeId": 1,
"entityType": 2,
"entityId": null,
"entityNameZh": "北京凯文斯科技发展有限公司",
"countryId": "0101",
"sanReason": "对于所有受《出口管理条例》(EAR)管辖的项目,协助为伊朗代理人操作的武器化无人飞行系统(UAS)采购美国原产电子元件;协助为伊朗代理人,包括哈马斯(Hamas),采购用于武器化无人飞行器(UAV)的美国原产电子元件,此举违背了美国国家安全。",
"sanIntensity": "\u0000",
"startTime": "2025-10-09",
"endTime": null,
"isKey": "\u0000",
"techDomainList": null,
"techDomains": [
"经济",
"安全"
],
"ruleOrgCount": 51
},
{
"createTime": null,
"updateTime": null,
"id": "3add08b1-3a8a-4",
"entityName": "China Address 17",
"sanTypeId": 1,
"entityType": 7,
"entityId": null,
"entityNameZh": "中国地址17",
"countryId": "0101",
"sanReason": "与艾米丽·刘(Emily Liu)的采购网络相关联,此人先前被海外资产控制办公室(OFAC)指定为支持伊朗设拉子电子工业(SEI)",
"sanIntensity": "\u0000",
"startTime": "2025-10-09",
"endTime": null,
"isKey": "\u0000",
"techDomainList": null,
"techDomains": [
"安全"
],
"ruleOrgCount": 66
},
{
"createTime": null,
"updateTime": null,
"id": "2b660bc7-d770-4",
"entityName": "Address 18",
"sanTypeId": 1,
"entityType": 7,
"entityId": null,
"entityNameZh": "地址18",
"countryId": "0101",
"sanReason": "对于商业管制清单(CCL)上的物品以及《出口管理条例》(EAR)第746部分第7号补编中列出的EAR 99物品",
"sanIntensity": "\u0000",
"startTime": "2025-10-09",
"endTime": null,
"isKey": "\u0000",
"techDomainList": null,
"techDomains": [
"经济"
],
"ruleOrgCount": 1
},
{
"createTime": null,
"updateTime": null,
"id": "ccaa8cd6-2b78-4",
"entityName": "Shanghai Bitconn Electronics Co., Ltd.",
"sanTypeId": 1,
"entityType": 2,
"entityId": null,
"entityNameZh": "上海比通电子有限公司",
"countryId": "0101",
"sanReason": "对于所有受《出口管理条例》(EAR)约束的项目,为伊朗代理人操作的武器化无人驾驶航空系统(UAS)购买美国原产电子元件提供了便利。",
"sanIntensity": "\u0000",
"startTime": "2025-10-09",
"endTime": null,
"isKey": "\u0000",
"techDomainList": null,
"techDomains": [
"经济",
"军事",
"科技"
],
"ruleOrgCount": 15
},
{
"createTime": null,
"updateTime": null,
"id": "8aa1686a-33e8-4",
"entityName": "Feng Bao Electronic Information Technology (Shanghai) Co., Ltd.",
"sanTypeId": 1,
"entityType": 2,
"entityId": null,
"entityNameZh": "丰宝电子信息科技(上海)有限公司",
"countryId": "0101",
"sanReason": "对于所有受《出口管理条例》(EAR)管辖的项目",
"sanIntensity": "\u0000",
"startTime": "2025-10-09",
"endTime": null,
"isKey": "\u0000",
"techDomainList": null,
"techDomains": [
"科技"
],
"ruleOrgCount": 42
},
{
"createTime": null,
"updateTime": null,
"id": "d9016b50-dee1-4",
"entityName": "Royal Impact Trading L.L.C.",
"sanTypeId": 1,
"entityType": 2,
"entityId": null,
"entityNameZh": "皇家影响力贸易有限责任公司",
"countryId": "134",
"sanReason": "对于所有受《出口管理条例》(EAR)管辖的项目,根据EAR第744.11节的规定,推定为拒绝批准,将美国原产项目转移至伊朗,包括归类于ECCN 2B350的项目。",
"sanIntensity": "\u0000",
"startTime": "2025-10-09",
"endTime": null,
"isKey": "\u0000",
"techDomainList": null,
"techDomains": [
"经济"
],
"ruleOrgCount": 39
}
],
"pageable": {
"sort": {
"unsorted": false,
"sorted": true,
"empty": false
},
"pageNumber": 0,
"pageSize": 10,
"offset": 0,
"unpaged": false,
"paged": true
},
"totalPages": 347,
"last": false,
"totalElements": 3461,
"sort": {
"unsorted": false,
"sorted": true,
"empty": false
},
"first": true,
"numberOfElements": 10,
"size": 10,
"number": 0,
"empty": false
}
}
\ No newline at end of file
# 交互消息类
## ApiResult
```java
public class ApiResult<T> {
@ApiModelProperty("响应码")
private int code;
@ApiModelProperty("响应消息")
private String message;
@ApiModelProperty("是否成功")
private boolean success;
@ApiModelProperty("响应数据")
private T data;
}
```
## LatestExportControlInfo
```java
public class LatestExportControlInfo {
// 出口管制事件ID
private String id;
// 管制信息标题
private String name;
// 管制内容简述
private String summary;
// 发布机构名称
private String postOrgName;
// 发布时间
private Date postDate;
// 涉及领域
private List<String> domains;
// 涉及中国实体数
private Integer cnEntityCount;
// 涉及主要实体
private List<SanctionListBean> sanEntities;
}
```
## AnnualCount
```java
public class AnnualCount {
// 年份
private Integer year;
// 数量
private Integer count;
// 领域列表
private List<String> domain;
}
```
## DomainCount
```java
public class DomainCount {
// 制裁类型名称
private String sanTypeName;
// 领域统计信息
private List<BaseCount> domainCountInfo;
}
```
## BaseCount
```java
public class BaseCount {
// 统计名称
private String name;
// 数量
private Integer count;
}
```
## ExportPageQuery
```java
public class ExportPageQuery extends BasePageQuery {
// 类型名称(实体清单)
private String typeName;
// 制裁时间
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date sanctionDate;
}
```
## BasePageQuery
```java
public class BasePageQuery {
// 查询页
private Integer pageNum = 1;
// 每页数量
private Integer pageSize = 10;
// 排序字段
private String sortField;
// 排序方式
private String sortOrder;
}
```
## SanctionProcess
```java
public class SanctionProcess {
// 制裁事件ID
private String id;
// 制裁时间
private Date postDate;
// 制裁标题
private String name;
// 制裁内容简述
private String summary;
// 涉及中国实体数
private Integer cnEntityCount;
}
```
## SanctionListBean
```java
public class SanctionListBean extends BaseBean {
@Id
@Column(name = "ID", nullable = false)
private String id;
@Column(name = "ENTITY_NAME")
private String entityName;
@Column(name = "SAN_TYPE_ID")
private Integer sanTypeId;
@Column(name = "ENTITY_TYPE")
private Integer entityType;
@Column(name = "ENTITY_ID")
private String entityId;
@Column(name = "ENTITY_NAME_ZH")
private String entityNameZh;
@Column(name = "COUNTRY_ID")
private String countryId;
@Column(name = "SAN_REASON")
private String sanReason;
@Column(name = "SAN_INTENSITY")
private char sanIntensity;
@Column(name = "START_TIME")
private Date startTime;
@Column(name = "END_TIME")
private Date endTime;
@Column(name = "IS_KEY")
private char isKey;
@Transient
private List<TechDomainBean> techDomainList;
/**
* 领域列表
*/
@Transient
private List<String> techDomains;
/**
* 50%规则子企业数
*/
@Transient
private Integer ruleOrgCount;
}
```
## OrgInfo
```java
public class OrgInfo {
// 机构id
private String id;
// 机构名称
private String orgName;
// 相关制裁措施列表
private List<String> sanTypeList;
// 机构职责
private String orgDuty;
// 机构图片
private String imageUrl;
// 人员列表
private List<PersonInfo> personList;
}
```
## PersonInfo
```java
public class PersonInfo {
// id
private String id;
// 姓名
private String name;
// 党派
private String party;
// 职位
private String position;
// 头像链接
private String imageUrl;
}
```
## SanCountInfo
```java
public class SanCountInfo {
// 实体数
private Integer entityNum;
// 实体变动数
private Integer entityChange;
// 上市公司数
private Integer listedCompanyNum;
// 上市公司变动数
private Integer listedCompanyChange;
// 涉及领域名数
private Integer domainNum;
// 涉及领域变动数
private Integer domainChange;
// 实体类型数
private Integer typeNum;
// 实体类型变动数
private Integer typeChange;
}
```
## Chain
```java
public class Chain {
@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
// 名称
@Column(name = "name")
private String name;
// 中文名称
@Column(name = "name_zh")
private String nameZh;
// 值
@Column(name = "description")
private String description;
// 父级id
@Column(name = "parent_id")
private Integer parentId;
// 是否为产业链主分支
@Column(name = "is_main_branch")
private String isMainBranch;
// 下属产业链分支
@Transient
private List<Chain> children;
}
```
## FishboneResp
```java
public class FishboneResp<T> {
private String text;
private List<T> causes;
}
```
## AreasStreamResp
```java
public class AreasStreamResp {
// 上游国内企业数量
private int upstreamInternalCount;
// 上游国内占比
private double upstreamInternalRate;
// 上游受制裁企业数量
private int upstreamEntityCount;
// 上游受制裁占比
private double upstreamEntityRate;
// 中游国内企业数量
private int midstreamInternalCount;
// 中游国内占比
private double midstreamInternalRate;
// 中游受制裁企业数量
private int midstreamEntityCount;
// 中游受制裁占比
private double midstreamEntityRate;
// 下游国内企业数量
private int downstreamInternalCount;
// 下游国内占比
private double downstreamInternalRate;
// 下游受制裁企业数量
private int downstreamEntityCount;
// 下游受制裁占比
private double downstreamEntityRate;
}
```
# 字典
## 领域类别(id:name)
1:人工智能、2:生物科技、3:新一代信息技术、4:量子科技、5:新能源、6:集成电路、7:海洋、8:先进制造、9:新材料、10:航空航天、11:深海、12:极地、13:太空、14:核
## 实体类别(id:name)
1:人物、2:机构
# 出口管制
## **实体清单总发布次数统计**
请求地址:http://8.140.26.4:9085/entitiesDataCount/getTotalPostNum
请求类型:GET
输入参数:
​ 参数:无输入
​ 请求头:携带token,内容为:
```
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkYXRhLWNlbnRlciIsImF1ZCI6IndlYiIsImlzcyI6ImRhdGEtY2VudGVyIiwiZXhwIjozODI1ODM1NTkxLCJpYXQiOjE2NzgzNTE5NTMsImp0aSI6IjI4YmY1NTZjMTc0MDQ3YjJiNTExNWM3NzVhYjhlNWRmIiwidXNlcm5hbWUiOiJzdXBlcl91c2VyIn0.zHyVzsleX2lEqjDBYRpwluu_wy2nZKGl0dw3IUGnKNw
```
输出结果:ApiResult<Integer>
## 最新出口管制政策
请求地址:http://8.140.26.4:9085/entitiesDataInfo/getLatestInfo
请求类型:GET
输入参数:
​ 参数:无输入
​ 请求头:携带token,内容为:
```
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkYXRhLWNlbnRlciIsImF1ZCI6IndlYiIsImlzcyI6ImRhdGEtY2VudGVyIiwiZXhwIjozODI1ODM1NTkxLCJpYXQiOjE2NzgzNTE5NTMsImp0aSI6IjI4YmY1NTZjMTc0MDQ3YjJiNTExNWM3NzVhYjhlNWRmIiwidXNlcm5hbWUiOiJzdXBlcl91c2VyIn0.zHyVzsleX2lEqjDBYRpwluu_wy2nZKGl0dw3IUGnKNw
```
输出结果:ApiResult<LatestExportControlInfo>
## 实体清单发布(更新)频度
请求地址:http://8.140.26.4:9085/entitiesDataCount/getAnnualCount
请求类型:GET
输入参数:
​ 参数:无输入
​ 请求头:携带token,内容为:
```
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkYXRhLWNlbnRlciIsImF1ZCI6IndlYiIsImlzcyI6ImRhdGEtY2VudGVyIiwiZXhwIjozODI1ODM1NTkxLCJpYXQiOjE2NzgzNTE5NTMsImp0aSI6IjI4YmY1NTZjMTc0MDQ3YjJiNTExNWM3NzVhYjhlNWRmIiwidXNlcm5hbWUiOiJzdXBlcl91c2VyIn0.zHyVzsleX2lEqjDBYRpwluu_wy2nZKGl0dw3IUGnKNw
```
输出结果:ApiResult<List<AnnualCount>>
## **制裁领域分析**
请求地址:http://8.140.26.4:9085/entitiesDataCount/getSanDomainCount
请求类型:GET
输入参数:
​ 参数:无输入
​ 请求头:携带token,内容为:
```
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkYXRhLWNlbnRlciIsImF1ZCI6IndlYiIsImlzcyI6ImRhdGEtY2VudGVyIiwiZXhwIjozODI1ODM1NTkxLCJpYXQiOjE2NzgzNTE5NTMsImp0aSI6IjI4YmY1NTZjMTc0MDQ3YjJiNTExNWM3NzVhYjhlNWRmIiwidXNlcm5hbWUiOiJzdXBlcl91c2VyIn0.zHyVzsleX2lEqjDBYRpwluu_wy2nZKGl0dw3IUGnKNw
```
输出结果:ApiResult<List<DomainCount>>
## **历次制裁过程**
请求地址:http://8.140.26.4:9085/entitiesDataCount/getSanctionProcess
请求类型:POST
输入参数:
​ 参数:ExportPageQuery exportPageQuery
​ 请求头:携带token,内容为:
```
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkYXRhLWNlbnRlciIsImF1ZCI6IndlYiIsImlzcyI6ImRhdGEtY2VudGVyIiwiZXhwIjozODI1ODM1NTkxLCJpYXQiOjE2NzgzNTE5NTMsImp0aSI6IjI4YmY1NTZjMTc0MDQ3YjJiNTExNWM3NzVhYjhlNWRmIiwidXNlcm5hbWUiOiJzdXBlcl91c2VyIn0.zHyVzsleX2lEqjDBYRpwluu_wy2nZKGl0dw3IUGnKNw
```
输出结果:ApiResult<Page<SanctionProcess>>
## **制裁实体清单**列表
请求地址:http://8.140.26.4:9085/sanctionList/pageQuery
请求类型:POST
输入参数:
​ 参数:ExportPageQuery exportPageQuery
​ 出口管制-概览页请求时:typeName=实体清单
​ 实体清单-制裁概览页请求时:typeName=实体清单,sanctionDate=该次制裁的具体时间
​ 请求头:携带token,内容为:
```
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkYXRhLWNlbnRlciIsImF1ZCI6IndlYiIsImlzcyI6ImRhdGEtY2VudGVyIiwiZXhwIjozODI1ODM1NTkxLCJpYXQiOjE2NzgzNTE5NTMsImp0aSI6IjI4YmY1NTZjMTc0MDQ3YjJiNTExNWM3NzVhYjhlNWRmIiwidXNlcm5hbWUiOiJzdXBlcl91c2VyIn0.zHyVzsleX2lEqjDBYRpwluu_wy2nZKGl0dw3IUGnKNw
```
输出结果:ApiResult<Page<SanctionListBean>>
## **发布机构与重点人物**
请求地址:/sanctionList/getPublishedOrg
请求类型:GET
输入参数:
​ 参数:Integer sanTypeId
​ 暂时固定输入:1;对应实体清单发布机构
​ 请求头:携带token
输出结果:ApiResult<OrgInfo>
## **领域分布查询**
请求地址:/entitiesDataInfo/getDomianDistribution
请求类型:GET
输入参数:
​ 参数:String sanctionDate (制裁时间)
​ 请求头:携带token
输出结果:ApiResult<List<BaseCount>>
## **类型分布查询**
请求地址:/entitiesDataInfo/getTypeDistribution
请求类型:GET
输入参数:
​ 参数:String sanctionDate (制裁时间)
​ 请求头:携带token
输出结果:ApiResult<List<BaseCount>>
## **制裁理由查询**
请求地址:/entitiesDataInfo/getSanReason
请求类型:GET
输入参数:
​ 参数:String sanctionDate (制裁时间)
​ 请求头:携带token
输出结果:ApiResult<List<String>>
## **深度挖掘-制裁信息变化统计**
请求地址:/entitiesDataInfo/getSanCountInfo
请求类型:GET
输入参数:
​ 参数:String sanctionDate (制裁时间)
​ 请求头:携带token
输出结果:ApiResult<SanCountInfo>
## **年度实体数统计**
请求地址:/entitiesDataInfo/getCountByDomianAndType
请求类型:GET
输入参数:
​ 参数:String domianId (非必需,领域类别ID),Integer typeId (非必需,实体类别ID)
​ 参考字典
​ 请求头:携带token
输出结果:ApiResult<SanCountInfo>
## **重点实体列表查询**
请求地址:/entitiesDataInfo/getKeyEntities
请求类型:GET
输入参数:
​ 参数:String sanctionDate(必需),String searchText(非必需,检索文本)
​ 请求头:携带token
输出结果:ApiResult<List<OrgInfo>>
## **上市企业制裁强度**
请求地址:/entitiesDataInfo/listedEntity/sanInfo
请求类型:GET
输入参数:
​ 参数:无
​ 请求头:携带token
输出结果:ApiResult<List<BaseCount>>
## **上市企业融资变化情况**
请求地址:/entitiesDataInfo/listedEntity/financing
请求类型:GET
输入参数:
​ 参数:无
​ 请求头:携带token
输出结果:ApiResult<List<BaseCount>>
## **上市企业市值变化情况**
请求地址:/entitiesDataInfo/listedEntity/market
请求类型:GET
输入参数:
​ 参数:无
​ 请求头:携带token
输出结果:ApiResult<List<BaseCount>>
## **重点上市企业列表**
请求地址:/entitiesDataInfo/listedEntity/keyEntity
请求类型:GET
输入参数:
​ 参数:String sanctionDate, 制裁时间
​ 请求头:携带token
输出结果:ApiResult<List<BaseCount>>
## **历次制裁涉及领域数查询**
请求地址:/entitiesDataInfo/getPreviousDomian
请求类型:GET
输入参数:
​ 参数:无
​ 请求头:携带token
输出结果:ApiResult<List<BaseCount>>
## **具体领域的制裁实体数统计**
请求地址:/entitiesDataInfo/getDomianAnnual
请求类型:GET
输入参数:
​ 参数:String domainId
​ 请求头:携带token
输出结果:ApiResult<List<AnnualCount>>
## **产业链结构查询**
请求地址:/chain/getChainTree
请求类型:GET
输入参数:
​ 参数:Integer chainId,非必需
​ 请求头:携带token
输出结果:ApiResult<List<Chain>>
## **产业链鱼骨图信息查询**
请求地址:/chain/getChainFishbone
请求类型:GET
输入参数:
​ 参数:Integer chainId
​ 请求头:携带token
输出结果:ApiResult<FishboneResp>
## **产业链中国企业实体信息查询**
请求地址:/chain/getChainEntityStat
请求类型:GET
输入参数:
​ 参数:Integer chainId
​ 请求头:携带token
输出结果:ApiResult<AreasStreamResp>
\ No newline at end of file
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论