提交 ddb456bf authored 作者: 张伊明's avatar 张伊明

撤销 "合并分支 'yp-dev' 到 'pre'"

这将还原合并请求 !228
上级 f2109b91
......@@ -3,65 +3,66 @@ import request from "@/api/request.js";
// 中美博弈概览V2:最新风险动态统计
export function getLatestRiskUpdates(params) {
return request({
method: "GET",
method: 'GET',
url: `/api/rivalryIndexV2/LatestRiskUpdates`,
params: params
});
})
}
// 中美博弈概览V2:最新风险信号
export function getLatestRisks() {
return request({
method: "GET",
url: `/api/rivalryIndexV2/LatestRisks`
});
method: 'GET',
url: `/api/rivalryIndexV2/LatestRisks`,
})
}
// 中美博弈概览V2:美对华制裁措施数量趋势
export function geDomainContainmentTrend(params) {
return request({
method: "GET",
method: 'GET',
url: `/api/rivalryIndexV2/DomainContainmentTrend`,
params: params
});
})
}
// 中美博弈概况:获取榜单字典
export function getChartDict() {
return request({
method: "GET",
url: `/api/union/summary/chartDict`
});
method: 'GET',
url: `/api/union/summary/chartDict`,
})
}
// 根据字典信息,获取年份信息
export function getYearDict(id) {
return request({
method: "GET",
url: `/api/union/summary/chartYear/${id}`
});
}
// 中美博弈概况:中美科技实力对比
export function getCompare(id, year) {
export function getCompare(id) {
return request({
method: "GET",
url: `/api/union/summary/compare/${id}/${year}`
});
method: 'GET',
url: `/api/union/summary/compare/${id}`,
})
}
// 中美博弈分析
export function getTechnologyGameAnalysis() {
return request({
method: "GET",
url: `/api/rivalryIndexV2/TechnologyGameAnalysis`
});
method: 'GET',
url: `/api/rivalryIndexV2/TechnologyGameAnalysis`,
})
}
//中美博弈概览V7:美国政府部门对华制裁最新动态
export function getGovernmentSanctionsDynamics() {
return request({
method: "GET",
url: `/api/rivalryIndex/governmentSanctionsDynamics`
});
method: 'GET',
url: `/api/rivalryIndex/governmentSanctionsDynamics`,
})
}
\ No newline at end of file
......@@ -18,15 +18,6 @@
>
<el-option :value="value.id" :label="value.name" v-for="(value, index) in originList" :key="index" />
</el-select>
<el-select
class="select-item"
size="default"
style="margin-left: 15px; width: 200px; height: 32px"
v-model="year"
@change="handleGetCompare()"
>
<el-option :value="value" :label="value" v-for="(value, index) in yearList" :key="index" />
</el-select>
</div>
</div>
<div style="display: flex; height: 650px; width: 100%; padding-top: 12px">
......@@ -246,7 +237,7 @@ import Echarts from "@/components/Chart/index.vue";
import mockData from "./mock.json";
import radarChart from "./radarChart3.js";
import { getCompare, getChartDict, getYearDict, getTechnologyGameAnalysis } from "@/api/zmOverview/risk/index.js";
import { getCompare, getChartDict, getTechnologyGameAnalysis } from "@/api/zmOverview/risk/index.js";
import icon1 from "./icon/btn-icon-0.png";
import icon2 from "./icon/btn-icon-1.png";
import icon3 from "./icon/btn-icon-2.png";
......@@ -360,27 +351,10 @@ const handleGetChartDict = async () => {
console.error("获取数据来源error", error);
}
};
const yearList = ref([]);
const year = ref("");
//年份
const handleGetYearDict = async () => {
try {
const res = await getYearDict(origin.value);
console.log("年份", res);
if (res.code === 200 && res.data) {
yearList.value = res.data;
year.value = res.data[0];
}
} catch (error) {
console.error("获取年份error", error);
}
};
//中美科技实力对比
const handleGetCompare = async () => {
try {
const res = await getCompare(origin.value, year.value);
const res = await getCompare(origin.value);
console.log("中美科技实力对比", res);
if (res.code === 200 && res.data) {
tableData.value = res.data[0].children;
......@@ -418,7 +392,6 @@ const handlegetTechnologyGameAnalysis = async () => {
};
onMounted(async () => {
await handleGetChartDict();
await handleGetYearDict();
await handleGetCompare();
await handlegetTechnologyGameAnalysis();
// const dom = document.getElementById("char");
......@@ -593,7 +566,6 @@ const lineOption = ref({
},
yAxis: {
type: "value",
min: 77,
// name: "指数",
nameLocation: "top",
nameGap: 35,
......
......@@ -37,7 +37,7 @@
<fourSuppress></fourSuppress>
<!-- 中美博弈概况 -->
<commonTitle id="zm-overview" title="中美博弈概况" style="margin-top: 64px; margin-bottom: 36px"></commonTitle>
<gameProfile />
<gameProfile></gameProfile>
<div class="bottom-info">
<div class="info-item">
<div class="info-item-left">
......
......@@ -4,13 +4,8 @@
<div class="home-top-bg"></div>
<div class="home-main-header">
<div class="home-main-header-center">
<SearchContainer
style="margin-bottom: 0; margin-top: 48px; height: fit-content"
v-if="containerRef"
placeholder="搜索政令"
:containerRef="containerRef"
areaName="政令"
/>
<SearchContainer style="margin-bottom: 0; margin-top: 48px; height: fit-content" v-if="containerRef"
placeholder="搜索政令" :containerRef="containerRef" areaName="政令" />
</div>
<!-- <div class="home-main-header-footer" v-show="!isShow">
<div class="home-main-header-footer-item">
......@@ -36,28 +31,23 @@
</div> -->
<div class="date-box" v-if="keyOrganizationList.length">
<div class="date-icon">
<img :src="tipsTcon" alt="" />
<img :src="tipsTcon" alt="">
</div>
<div class="date-text">近期美国各联邦政府机构发布涉华政令数量汇总</div>
<TimeTabPane @time-click="onKeyOrganization" />
</div>
<div class="home-main-header-item-box" v-if="keyOrganizationList.length">
<div
class="organization-item"
v-for="(item, index) in keyOrganizationList"
:key="index"
@click="handleToInstitution(item)"
>
<div class="organization-item" v-for="(item, index) in keyOrganizationList" :key="index" @click="handleToInstitution(item)">
<div class="item-left">
<img :src="item.imgUrl || DefaultIcon2" alt="" />
</div>
<div class="item-right one-line-ellipsis">{{ item.orgName }}</div>
<div class="item-total">{{ item.totalOrderNum }}</div>
<el-icon color="var(--color-primary-100)"><ArrowRightBold /></el-icon>
<div class="item-dot" v-if="item.recentOrderNum">+{{ item.recentOrderNum }}</div>
<div class="item-dot" v-if="item.recentOrderNum">+{{item.recentOrderNum}}</div>
</div>
<div class="organization-item" @click="onNavigateTo()">
<div class="item-more">查看全部机构 ({{ govInsList.length + 1 }}家)</div>
<div class="item-more">查看全部机构 ({{govInsList.length+1}}家)</div>
<el-icon color="var(--color-primary-100)"><ArrowRightBold /></el-icon>
</div>
</div>
......@@ -87,14 +77,8 @@
{{ "查看详情 >" }}
</div>
</div>
<el-carousel
ref="carouselRef"
height="395px"
:autoplay="true"
:interval="3000"
arrow="never"
indicator-position="none"
>
<el-carousel ref="carouselRef" height="395px" :autoplay="true" :interval="3000" arrow="never"
indicator-position="none">
<el-carousel-item v-for="(item, index) in box1DataList" :key="index">
<div class="box1-main">
<div class="box1-main-left">
......@@ -111,11 +95,7 @@
{{ item.name }}
</div>
<div class="box1-main-right-info">
<AreaTag
v-for="(tag, index) in item.industryList"
:key="index"
:tagName="tag.industryName"
/>
<AreaTag v-for="(tag, index) in item.industryList" :key="index" :tagName="tag.industryName" />
</div>
<div class="box1-main-right-center">
{{ item.describe }}
......@@ -177,26 +157,15 @@
<div class="text">{{ "查看更多" }}</div>
</div>
</div> -->
<RiskSignal
:list="warningList"
@item-click="handleClickToDetail"
@more-click="handleToMoreRiskSignal"
riskLevel="signalLevel"
postDate="signalTime"
name="signalTitle"
>
<RiskSignal :list="warningList" @item-click="handleClickToDetail" @more-click="handleToMoreRiskSignal"
riskLevel="signalLevel" postDate="signalTime" name="signalTitle">
</RiskSignal>
</div>
<DivideHeader id="position2" class="divide2" :titleText="'资讯要闻'"></DivideHeader>
<div class="center-center">
<NewsList :newsList="newsList" @item-click="handleToNewsAnalysis" @more-click="handleToMoreNews" />
<MessageBubble
:messageList="messageList"
@person-click="handleClickPerson"
@info-click="handleGetMessage"
imageUrl="img"
@more-click="handleToSocialDetail"
/>
<MessageBubble :messageList="messageList" @person-click="handleClickPerson" @info-click="handleGetMessage"
imageUrl="img" @more-click="handleToSocialDetail" />
</div>
<DivideHeader id="position3" class="divide3" :titleText="'数据总览'"></DivideHeader>
<div class="center-footer">
......@@ -206,46 +175,21 @@
<img src="./assets/images/box3-header-icon.png" alt="" />
</div>
<div class="box5-header-title">{{ "数量变化趋势" }}</div>
<div style="margin-right: 20px">
<el-select
@change="handleBox5"
v-model="box5Params.proposeName"
:empty-values="[null, undefined]"
style="width: 150px"
>
<div style="margin-right: 20px;">
<el-select @change="handleBox5" v-model="box5Params.proposeName" :empty-values="[null, undefined]" style="width:150px">
<el-option label="全部政府部门" value="" />
<el-option
v-for="item in keyOrganizationList"
:key="item.orgId"
:label="item.orgName"
:value="item.orgId"
/>
<el-option v-for="item in keyOrganizationList" :key="item.orgId" :label="item.orgName" :value="item.orgId" />
</el-select>
</div>
<div style="margin-right: 20px">
<el-select
@change="handleBox5"
v-model="box5Params.domainId"
:empty-values="[null, undefined]"
style="width: 120px"
>
<div style="margin-right: 20px;">
<el-select @change="handleBox5" v-model="box5Params.domainId" :empty-values="[null, undefined]" style="width:120px">
<el-option label="全部领域" value="" />
<el-option v-for="item in areaList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</div>
<div style="margin-right: 20px">
<el-select
@change="handleBox5"
v-model="box5Params.year"
placeholder="选择时间"
style="width: 120px"
>
<el-option
v-for="item in yearList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
<div style="margin-right: 20px;">
<el-select @change="handleBox5" v-model="box5Params.year" placeholder="选择时间" style="width:120px">
<el-option v-for="item in yearList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
</div>
......@@ -254,7 +198,7 @@
</div>
<div class="data-origin-box">
<div class="data-origin-icon">
<img :src="tipsTcon" alt="" />
<img :src="tipsTcon" alt="">
</div>
<div class="data-origin-text">科技政令数量变化趋势,数据来源:美国各行政机构官网</div>
</div>
......@@ -270,35 +214,15 @@
<img src="./assets/images/box4-header-icon.png" alt="" />
</div>
<div class="box5-header-title">{{ "领域分布情况" }}</div>
<div style="margin-right: 20px">
<el-select
@change="handleBox6YearChange"
v-model="box6Params.proposeName"
:empty-values="[null, undefined]"
style="width: 150px"
>
<div style="margin-right: 20px;">
<el-select @change="handleBox6YearChange" v-model="box6Params.proposeName" :empty-values="[null, undefined]" style="width:150px">
<el-option label="全部政府部门" value="" />
<el-option
v-for="item in keyOrganizationList"
:key="item.orgId"
:label="item.orgName"
:value="item.orgId"
/>
<el-option v-for="item in keyOrganizationList" :key="item.orgId" :label="item.orgName" :value="item.orgId" />
</el-select>
</div>
<div style="margin-right: 20px">
<el-select
@change="handleBox6YearChange"
v-model="box6Params.year"
placeholder="选择时间"
style="width: 120px"
>
<el-option
v-for="item in yearList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
<div style="margin-right: 20px;">
<el-select @change="handleBox6YearChange" v-model="box6Params.year" placeholder="选择时间" style="width: 120px">
<el-option v-for="item in yearList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
</div>
......@@ -307,9 +231,9 @@
</div>
<div class="data-origin-box">
<div class="data-origin-icon">
<img :src="tipsTcon" alt="" />
<img :src="tipsTcon" alt="">
</div>
<div class="data-origin-text">科技政领域分布情况,数据来源:美国各行政机构官网</div>
<div class="data-origin-text">科技政领域分布情况,数据来源:美国各行政机构官网</div>
</div>
<div class="ai-pane">
<AiButton />
......@@ -324,57 +248,27 @@
<img src="./assets/images/box5-header-icon.png" alt="" />
</div>
<div class="header-title">{{ "关键科技政令" }}</div>
<div style="margin-right: 20px">
<el-select
@change="handleGetKeyDecree"
v-model="box7Params.proposeName"
:empty-values="[null, undefined]"
style="width: 150px"
>
<div style="margin-right: 20px;">
<el-select @change="handleGetKeyDecree" v-model="box7Params.proposeName" :empty-values="[null, undefined]" style="width:150px">
<el-option label="全部政府部门" value="" />
<el-option
v-for="item in keyOrganizationList"
:key="item.orgId"
:label="item.orgName"
:value="item.orgId"
/>
<el-option v-for="item in keyOrganizationList" :key="item.orgId" :label="item.orgName" :value="item.orgId" />
</el-select>
</div>
<div style="margin-right: 20px">
<el-select
@change="handleGetKeyDecree"
v-model="box7Params.domainId"
:empty-values="[null, undefined]"
style="width: 120px"
>
<div style="margin-right: 20px;">
<el-select @change="handleGetKeyDecree" v-model="box7Params.domainId" :empty-values="[null, undefined]" style="width:120px">
<el-option label="全部领域" value="" />
<el-option v-for="item in areaList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</div>
<div style="margin-right: 20px">
<el-select
@change="handleGetKeyDecree"
v-model="box7Params.year"
placeholder="选择时间"
style="width: 120px"
>
<el-option
v-for="item in yearList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
<div style="margin-right: 20px;">
<el-select @change="handleGetKeyDecree" v-model="box7Params.year" placeholder="选择时间" style="width:120px">
<el-option v-for="item in yearList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
</div>
<div class="box7-main" v-loading="box7Params.loading">
<div class="box7-list">
<div
class="box7-item"
v-for="(item, index) in keyDecreeList"
:key="index"
@click="handleKeyDecree(item)"
>
<div class="box7-item" v-for="(item, index) in keyDecreeList" :key="index" @click="handleKeyDecree(item)">
<div class="icon">
<img src="./assets/images/warning.png" alt="" />
</div>
......@@ -388,17 +282,12 @@
</div>
</div>
</div>
<SimplePagination
v-model:current-page="keyDecreeInfo.page"
:page-size="keyDecreeInfo.size"
:total="keyDecreeInfo.total"
@page-change="handleGetKeyDecree"
/>
<SimplePagination v-model:current-page="keyDecreeInfo.page" :page-size="keyDecreeInfo.size" :total="keyDecreeInfo.total" @page-change="handleGetKeyDecree" />
<div class="data-origin-box">
<div class="data-origin-icon">
<img :src="tipsTcon" alt="" />
<img :src="tipsTcon" alt="">
</div>
<div class="data-origin-text">关键科技政列表,数据来源:美国各行政机构官网</div>
<div class="data-origin-text">关键科技政列表,数据来源:美国各行政机构官网</div>
</div>
</div>
<div class="box8">
......@@ -407,46 +296,21 @@
<img src="./assets/images/box5-header-icon.png" alt="" />
</div>
<div class="header-title">{{ "关键条款词云" }}</div>
<div style="margin-right: 20px">
<el-select
@change="handleGetDecreeKeyInstruction"
v-model="box8Params.proposeName"
:empty-values="[null, undefined]"
style="width: 150px"
>
<div style="margin-right: 20px;">
<el-select @change="handleGetDecreeKeyInstruction" v-model="box8Params.proposeName" :empty-values="[null, undefined]" style="width:150px">
<el-option label="全部政府部门" value="" />
<el-option
v-for="item in keyOrganizationList"
:key="item.orgId"
:label="item.orgName"
:value="item.orgId"
/>
<el-option v-for="item in keyOrganizationList" :key="item.orgId" :label="item.orgName" :value="item.orgId" />
</el-select>
</div>
<div style="margin-right: 20px">
<el-select
@change="handleGetDecreeKeyInstruction"
v-model="box8Params.domainId"
:empty-values="[null, undefined]"
style="width: 120px"
>
<div style="margin-right: 20px;">
<el-select @change="handleGetDecreeKeyInstruction" v-model="box8Params.domainId" :empty-values="[null, undefined]" style="width:120px">
<el-option label="全部领域" value="" />
<el-option v-for="item in areaList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</div>
<div style="margin-right: 20px">
<el-select
@change="handleGetDecreeKeyInstruction"
v-model="box8Params.year"
placeholder="选择时间"
style="width: 120px"
>
<el-option
v-for="item in yearList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
<div style="margin-right: 20px;">
<el-select @change="handleGetDecreeKeyInstruction" v-model="box8Params.year" placeholder="选择时间" style="width:120px">
<el-option v-for="item in yearList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
</div>
......@@ -455,9 +319,9 @@
</div>
<div class="data-origin-box">
<div class="data-origin-icon">
<img :src="tipsTcon" alt="" />
<img :src="tipsTcon" alt="">
</div>
<div class="data-origin-text">科技政重点条款词云,数据来源:美国各行政机构官网</div>
<div class="data-origin-text">科技政重点条款词云,数据来源:美国各行政机构官网</div>
</div>
</div>
</div>
......@@ -471,10 +335,10 @@
<el-option v-for="item in govInsList" :key="item.orgId" :label="item.orgName" :value="item.orgId" />
</el-select>
</div>
<div style="flex: auto"></div>
<div style="flex: auto;"></div>
<el-checkbox v-model="isChina">只看涉华政令</el-checkbox>
<div class="select-box">
<el-select v-model="isSort" placeholder="发布时间" style="width: 120px; margin-left: 8px">
<el-select v-model="isSort" placeholder="发布时间" style="width:120px; margin-left:8px;">
<template #prefix>
<div class="icon1">
<img v-if="isSort" src="@/assets/icons/shengxu1.png" alt="" />
......@@ -495,15 +359,9 @@
</div>
<div class="select-main">
<div class="checkbox-group">
<el-checkbox
v-for="type in decreeTypeList"
:key="type.id"
v-model="checkedDecreeType"
:label="type.typeId"
style="width: 180px"
class="filter-checkbox"
@change="handleChangeCheckedDecreeType"
>
<el-checkbox v-for="type in decreeTypeList" :key="type.id" v-model="checkedDecreeType" :label="type.typeId"
style="width: 180px" class="filter-checkbox"
@change="handleChangeCheckedDecreeType">
{{ type.typeName }}
</el-checkbox>
</div>
......@@ -516,24 +374,12 @@
</div>
<div class="select-main">
<div class="checkbox-group">
<el-checkbox
v-model="activeAreaList"
label="all"
style="width: 100px"
class="filter-checkbox"
@change="checked => handleAreaChange('all', checked)"
>
<el-checkbox v-model="activeAreaList" label="all"
style="width: 100px" class="filter-checkbox" @change="checked => handleAreaChange('all', checked)">
{{ "全部领域" }}
</el-checkbox>
<el-checkbox
v-for="area in areaList"
:key="area.id"
v-model="activeAreaList"
:label="area.id"
style="width: 100px"
class="filter-checkbox"
@change="checked => handleAreaChange(area.id, checked)"
>
<el-checkbox v-for="area in areaList" :key="area.id" v-model="activeAreaList" :label="area.id"
style="width: 100px" class="filter-checkbox" @change="checked => handleAreaChange(area.id, checked)">
{{ area.name }}
</el-checkbox>
</div>
......@@ -546,15 +392,8 @@
</div>
<div class="select-main">
<div class="checkbox-group">
<el-checkbox
v-for="time in pubTime"
:key="time.id"
v-model="activePubTime"
:label="time.id"
style="width: 100px"
class="filter-checkbox"
@change="checked => handlePubTimeChange(time.id, checked)"
>
<el-checkbox v-for="time in pubTime" :key="time.id" v-model="activePubTime" :label="time.id"
style="width: 100px" class="filter-checkbox" @change="checked => handlePubTimeChange(time.id, checked)">
{{ time.name }}
</el-checkbox>
</div>
......@@ -569,12 +408,7 @@
<div class="title">{{ "政令库" }}</div>
</div>
<div class="content-box" v-show="decreeList">
<div
class="main-item"
v-for="(item, index) in decreeList"
:key="index"
@click="handleClickDecree(item)"
>
<div class="main-item" v-for="(item, index) in decreeList" :key="index" @click="handleClickDecree(item)">
<div class="main-item-left">
<div class="left-left">
{{ item.time?.split("-")[0] }}<br />{{ item.time?.split("-")[1] }}月{{
......@@ -605,14 +439,8 @@
{{ `共 ${totalDecreesNum} 项` }}
</div>
<div class="footer-right">
<el-pagination
@current-change="handleCurrentChange"
:pageSize="10"
:current-page="currentPage"
background
layout="prev, pager, next"
:total="totalDecreesNum"
/>
<el-pagination @current-change="handleCurrentChange" :pageSize="10" :current-page="currentPage"
background layout="prev, pager, next" :total="totalDecreesNum" />
</div>
</div>
</div>
......@@ -625,11 +453,11 @@
<script setup>
import { onMounted, ref, watch, nextTick, reactive } from "vue";
import router from "@/router";
import WordCloudChart from "@/components/base/WordCloundChart/index.vue";
import WordCloudChart from "@/components/base/WordCloundChart/index.vue"
import SimplePagination from "@/components/SimplePagination.vue";
import TimeTabPane from "@/components/base/TimeTabPane/index.vue";
import AiButton from "@/components/base/Ai/AiButton/index.vue";
import AiPane from "@/components/base/Ai/AiPane/index.vue";
import TimeTabPane from '@/components/base/TimeTabPane/index.vue';
import AiButton from '@/components/base/Ai/AiButton/index.vue';
import AiPane from '@/components/base/Ai/AiPane/index.vue';
import {
getDepartmentList,
getLatestDecree,
......@@ -641,7 +469,7 @@ import {
getDecreeOrderList,
getDecreehylyList,
getDecreeTypeList,
getKeyOrganization
getKeyOrganization,
} from "@/api/decree/home";
import { getPersonSummaryInfo } from "@/api/common/index";
import { getNews, getSocialMedia } from "@/api/general/index";
......@@ -656,7 +484,7 @@ import DefaultIcon2 from "@/assets/icons/default-icon2.png";
import tipsTcon from "./assets/images/tips-icon.png";
import { ElMessage } from "element-plus";
import { useGotoNewsDetail } from "@/router/modules/news";
import { useGotoNewsDetail } from '@/router/modules/news';
const containerRef = ref(null);
const { isShow } = useContainerScroll(containerRef);
......@@ -665,7 +493,7 @@ const pageSize = ref(10);
// 处理页码改变事件
const handleCurrentChange = page => {
currentPage.value = page;
handleToPosi("position4");
handleToPosi('position4')
handleGetDecreeOrderList();
};
......@@ -674,7 +502,7 @@ const govInsList = ref([]);
const checkedGovIns = ref([]);
const handleGetDepartmentList = async () => {
try {
const res = await getDepartmentList({ day: 7 });
const res = await getDepartmentList({day:7});
console.log("机构列表", res);
if (res.code === 200 && res.data) {
govInsList.value = res.data;
......@@ -696,8 +524,8 @@ const handleToInstitution = item => {
};
// 跳转全部机构页面
const onNavigateTo = () => {
router.push({ name: "allOrganization" });
};
router.push({name: "allOrganization"});
}
// 查看更多风险信号
const handleToMoreRiskSignal = () => {
......@@ -826,7 +654,7 @@ const newsList = ref([
]);
const handleGetNews = async () => {
try {
const res = await getNews({ moduleId: "0101" });
const res = await getNews({moduleId: "0101"});
console.log("新闻资讯", res);
if (res.code === 200 && res.data) {
newsList.value = (res.data ?? []).map(item => {
......@@ -844,9 +672,9 @@ const handleGetNews = async () => {
}
};
// 点击新闻条目,跳转到新闻分析页
const gotoNewsDetail = useGotoNewsDetail();
const gotoNewsDetail = useGotoNewsDetail()
const handleToNewsAnalysis = news => {
gotoNewsDetail(news.newsId);
gotoNewsDetail(news.newsId)
};
// 社交媒体
......@@ -883,7 +711,7 @@ const handleGetMessage = async () => {
remarksId: item.remarksId
};
});
} catch (error) {}
} catch (error) { }
};
handleGetMessage();
......@@ -941,7 +769,7 @@ const handleClickPerson = async item => {
ElMessage.warning("找不到当前人员的类型值!");
return;
}
} catch (error) {}
} catch (error) { }
};
// 获取最近年份列表
......@@ -963,13 +791,13 @@ const chart1Data = ref({
});
const box5Params = reactive({
year: yearList[0].value,
domainId: "",
proposeName: "",
loading: false
});
const summarize1 = ref();
domainId: '',
proposeName: '',
loading: false,
})
const summarize1 = ref()
const handleGetDecreeYearOrder = async () => {
box5Params.loading = true;
box5Params.loading = true
try {
let { year, domainId, proposeName } = box5Params;
const res = await getDecreeYearOrder({
......@@ -985,53 +813,53 @@ const handleGetDecreeYearOrder = async () => {
chart1Data.value.dataY = res.data.map(item => {
return item.count;
});
summarize1.value = await onChartInterpretation({ type: "柱状图", name: "数量变化趋势", data: res.data });
summarize1.value = await onChartInterpretation({type:"柱状图",name:"数量变化趋势",data:res.data})
}
} catch (error) {
console.error("行政令发布频度error", error);
}
box5Params.loading = false;
box5Params.loading = false
};
// AI智能总结
const onChartInterpretation = async text => {
const response = await fetch("/aiAnalysis/chart_interpretation", {
method: "POST",
const onChartInterpretation = async (text) => {
const response = await fetch('/aiAnalysis/chart_interpretation', {
method: 'POST',
headers: {
"X-API-Key": "aircasKEY19491001",
"Content-Type": "application/json"
'Content-Type': 'application/json',
},
body: JSON.stringify({ text }) // 把参数转为JSON字符串
body: JSON.stringify({text}) // 把参数转为JSON字符串
});
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = "";
let summarize = "";
let buffer = '';
let summarize = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split("\n");
buffer = lines.pop() || "";
const lines = buffer.split('\n');
buffer = lines.pop() || '';
for (const line of lines) {
if (line.startsWith("data: ")) {
if (line.startsWith('data: ')) {
const content = line.substring(6);
const textMatch = content.match(/"解读":\s*"([^"]*)"/);
if (textMatch && textMatch[1]) summarize = textMatch[1];
}
}
}
return summarize;
};
return summarize
}
const handleBox5 = async () => {
await handleGetDecreeYearOrder();
let chart1 = getBarChart(chart1Data.value.dataX, chart1Data.value.dataY);
chart1.yAxis.name = "数量";
chart1.yAxis.nameTextStyle = { align: "right" };
chart1.yAxis.nameTextStyle = { align: 'right' }
setChart(chart1, "chart1");
};
......@@ -1050,12 +878,12 @@ const chart2Data = ref([
const box6Params = reactive({
year: yearList[0].value,
proposeName: "",
loading: false
proposeName: '',
loading: false,
});
const summarize2 = ref();
const summarize2 = ref()
const handleGetDecreeArea = async () => {
box6Params.loading = true;
box6Params.loading = true
try {
let { year, proposeName } = box6Params;
const res = await getDecreeArea({
......@@ -1070,12 +898,12 @@ const handleGetDecreeArea = async () => {
value: item.count
};
});
summarize2.value = await onChartInterpretation({ type: "环形图", name: "领域分布情况", data: res.data });
summarize2.value = await onChartInterpretation({type:"环形图",name:"领域分布情况",data:res.data})
}
} catch (error) {
console.error("政令科技领域error", error);
}
box6Params.loading = false;
box6Params.loading = false
};
const handleBox6 = async () => {
await handleGetDecreeArea();
......@@ -1092,21 +920,21 @@ const keyDecreeList = ref([]);
const keyDecreeInfo = reactive({
total: 0,
page: 1,
size: 4
});
size: 4,
})
const box7Params = reactive({
year: yearList[0].value,
domainId: "",
proposeName: "",
loading: false
});
domainId: '',
proposeName: '',
loading: false,
})
const handleGetKeyDecree = async () => {
box7Params.loading = true;
box7Params.loading = true
try {
let { year, domainId, proposeName } = box7Params;
const res = await getKeyDecree({
pageSize: keyDecreeInfo.size,
pageNum: keyDecreeInfo.page - 1,
pageSize:keyDecreeInfo.size,
pageNum:keyDecreeInfo.page-1,
year,
domainId: domainId || undefined,
orgId: proposeName || undefined
......@@ -1123,20 +951,20 @@ const handleGetKeyDecree = async () => {
};
});
}
} catch (error) {}
box7Params.loading = false;
} catch (error) { }
box7Params.loading = false
};
// 政令重点条款
const wordCloudData = ref([]);
const box8Params = reactive({
year: yearList[0].value,
domainId: "",
proposeName: "",
loading: false
});
domainId: '',
proposeName: '',
loading: false,
})
const handleGetDecreeKeyInstruction = async () => {
box8Params.loading = true;
box8Params.loading = true
try {
let { year, domainId, proposeName } = box8Params;
const res = await getDecreeKeyInstruction({
......@@ -1145,11 +973,11 @@ const handleGetDecreeKeyInstruction = async () => {
orgId: proposeName || undefined
});
console.log("政令重点条款", res);
wordCloudData.value = res.data.map(item => ({ name: item.clause, value: item.count }));
wordCloudData.value = res.data.map(item => ({name: item.clause, value: item.count}));
} catch (error) {
console.error("政令重点条款error", error);
}
box8Params.loading = false;
box8Params.loading = false
};
// 资源库
......@@ -1191,7 +1019,7 @@ const handleGetDecreeTypeList = async () => {
if (res.code === 200 && res.data) {
decreeTypeList.value = res.data;
}
} catch (error) {}
} catch (error) { }
};
// 查看社交媒体详情
const handleToSocialDetail = item => {
......@@ -1275,7 +1103,7 @@ const handleGetAreaList = async () => {
// 获取列表后重新查询
handleGetDecreeOrderList();
}
} catch (error) {}
} catch (error) { }
};
const totalDecreesNum = ref(0);
......@@ -1375,19 +1203,19 @@ const handleSearch = () => {
// 关键机构
const keyOrganizationList = ref([]);
const onKeyOrganization = async event => {
let day = 7;
if (event?.time === "近一周") day = 7;
if (event?.time === "近一月") day = 30;
if (event?.time === "近一年") day = 365;
const onKeyOrganization = async (event) => {
let day = 7
if (event?.time === '近一周') day = 7
if (event?.time === '近一月') day = 30
if (event?.time === '近一年') day = 365
try {
const res = await getKeyOrganization({ day });
const res = await getKeyOrganization({day});
console.log("关键机构", res);
if (res.code === 200) {
keyOrganizationList.value = res.data;
}
} catch (error) {}
};
} catch (error) { }
}
onMounted(async () => {
onKeyOrganization();
......@@ -1443,7 +1271,7 @@ onMounted(async () => {
height: 16px;
font-size: 0px;
margin-right: 8px;
img {
img{
width: 100%;
height: 100%;
}
......@@ -1468,9 +1296,7 @@ onMounted(async () => {
overflow-y: auto;
.home-top-bg {
background:
url("./assets/images/background.png"),
linear-gradient(180deg, rgba(229, 241, 254, 1) 0%, rgba(246, 251, 255, 0) 30%);
background: url("./assets/images/background.png"), linear-gradient(180deg, rgba(229, 241, 254, 1) 0%, rgba(246, 251, 255, 0) 30%);
background-size: 100% 100%;
position: absolute;
width: 100%;
......@@ -1624,9 +1450,7 @@ onMounted(async () => {
align-items: center;
justify-content: center;
cursor: pointer;
transition:
transform 0.3s ease,
box-shadow 0.3s ease;
transition: transform 0.3s ease, box-shadow 0.3s ease;
position: relative;
&:hover {
......@@ -1678,7 +1502,7 @@ onMounted(async () => {
top: -10px;
padding: 0 8px;
height: 26px;
background-color: #ff4d4f;
background-color: #FF4D4F;
color: white;
font-size: 16px;
line-height: 26px;
......
......@@ -368,29 +368,19 @@
</el-col>
</el-row>
<el-row :gutter="20" style="width: 1600px; margin: 0 auto; height: 540px; margin-top: 16px">
<el-row :gutter="20" style="width: 1600px; margin: 0 auto; height: 505px; margin-top: 16px">
<el-col :span="8">
<custom-container title="实体领域分布" :titleIcon="radarIcon" height="520px">
<custom-container title="实体领域分布" :titleIcon="radarIcon" height="480px">
<template #header-right>
<el-checkbox v-model="domainChecked" label="50%规则" size="large" />
</template>
<template #default>
<EChart :option="radarOption" autoresize :style="{ height: '400px' }" />
<div class="data-origin-box">
<div class="data-origin-icon">
<img :src="tipsIcon" alt="" />
</div>
<div class="data-origin-text">出口管制实体领域分布情况,数据来源:美国各行政机构官网</div>
</div>
<div class="ai-pane">
<AiButton />
<AiPane :aiContent="radarChart.interpretation" />
</div>
<EChart :option="radarOption" autoresize :style="{ height: '460px' }" />
</template>
</custom-container>
</el-col>
<el-col :span="16">
<custom-container title="实体清单数量增长趋势" :titleIcon="qushiIcon" height="520px">
<custom-container title="实体清单数量增长趋势" :titleIcon="qushiIcon" height="480px">
<template #header-right>
<div style="display: flex; align-items: center; gap: 16px">
<el-checkbox v-model="trendChecked" label="50%规则" size="large" />
......@@ -401,16 +391,6 @@
</template>
<template #default>
<EChart :option="trendOption" autoresize :style="{ height: '400px' }" />
<div class="data-origin-box">
<div class="data-origin-icon">
<img :src="tipsIcon" alt="" />
</div>
<div class="data-origin-text">出口管制实体清单数量增长趋势,数据来源:美国各行政机构官网</div>
</div>
<div class="ai-pane">
<AiButton />
<AiPane :aiContent="trendChart.interpretation" />
</div>
</template>
</custom-container>
</el-col>
......@@ -732,10 +712,9 @@ import * as echarts from "echarts";
import setChart from "@/utils/setChart";
import { ElMessage, ElMessageBox } from "element-plus";
import { DArrowRight, Warning, Search, TrendCharts } from "@element-plus/icons-vue";
import { DArrowRight, Warning, Search } from "@element-plus/icons-vue";
import EChart from "@/components/Chart/index.vue";
import { TAGTYPE } from "@/public/constant";
import { useChartInterpretation } from "@/views/exportControl/utils/common";
import { useGotoCompanyPages } from "@/router/modules/company";
import { useGotoNewsDetail } from "@/router/modules/news";
const gotoCompanyPages = useGotoCompanyPages();
......@@ -747,8 +726,6 @@ const router = useRouter();
import CustomContainer from "@/components/Container/index.vue";
import ClickableCard from "./components/link.vue";
import AiButton from "@/components/base/Ai/AiButton/index.vue";
import AiPane from "@/components/base/Ai/AiPane/index.vue";
import InfoCard from "./components/info.vue";
import CustomTitle from "./components/title.vue";
import CommonPrompt from "./commonPrompt/index.vue";
......@@ -769,7 +746,6 @@ import entityIcon from "./assets/images/icon-entity.png";
import comTitle from "./assets/images/panel1_1.png";
import getMultiLineChart from "./utils/multiLineChart";
import icon01 from "./assets/images/jianzhu.png";
import tipsIcon from "./assets/icons/info-icon.png";
import {
getEntitiesDataCount,
getEntitiesDataInfo,
......@@ -1039,7 +1015,6 @@ const handleToSocialDetail = item => {
});
window.open(route.href, "_blank");
};
const trendChart = useChartInterpretation();
// 获取趋势图数据
const fetchTrendData = async () => {
try {
......@@ -1051,7 +1026,6 @@ const fetchTrendData = async () => {
});
if (res && res[0] && res[0].yearDomainCount) {
trendOption.value = processYearDomainCountData(res[0].yearDomainCount);
trendChart.interpret({ type: "柱状图", name: "实体清单数量增长趋势", data: res[0].yearDomainCount });
}
} catch (error) {
console.error("获取趋势图数据失败:", error);
......@@ -1231,7 +1205,7 @@ const radarOption = ref({
},
radar: {
radius: "60%",
center: ["52%", "45%"],
center: ["50%", "50%"],
// shape: 'circle',
indicator: [],
axisName: {
......@@ -1251,14 +1225,11 @@ const radarOption = ref({
]
});
const radarChart = useChartInterpretation();
// 获取雷达图数据
const fetchRadarData = async checked => {
try {
const data = await getSanDomainCount(checked, "export");
console.log("雷达数据data", data);
if (data && Array.isArray(data) && data.length > 0) {
radarChart.interpret({ type: "雷达图", name: "实体领域分布", data: data });
// 收集所有可能的领域名称
const allDomains = new Set();
data.forEach(item => {
......@@ -1660,11 +1631,10 @@ const fetchNewsInfo = async () => {
const handlePerClick = item => {
// console.log("点击了社交媒体消息:", item);
window.sessionStorage.setItem("curTabName", item.name);
console.log("人物点击 =>", item);
const route = router.resolve({
path: "/characterPage",
query: {
type: item.personType || [1, 2, 3][Math.floor(Math.random() * 3)],
type: item.type || [1, 2, 3][Math.floor(Math.random() * 3)],
personId: item.personId
}
});
......@@ -3626,50 +3596,4 @@ const handleMediaClick = item => {
background: rgba(255, 255, 255, 1);
}
}
.data-origin-box {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
padding: 22px 0;
.data-origin-icon {
width: 16px;
height: 16px;
font-size: 0px;
margin-right: 8px;
img {
width: 100%;
height: 100%;
}
}
.data-origin-text {
font-family: Source Han Sans CN;
font-size: 14px;
color: var(--text-primary-50-color);
}
}
.ai-pane {
position: absolute;
right: 0px;
bottom: 15px;
z-index: 2;
:deep(.ai-pane-wrapper) {
display: none;
}
:deep(.ai-button-wrapper) {
display: flex;
}
&:hover {
width: 100%;
bottom: 0px;
:deep(.ai-pane-wrapper) {
display: block;
}
:deep(.ai-button-wrapper) {
display: none;
}
}
}
</style>
import * as echarts from "echarts";
import chinaJson from "./China.json";
import _ from "lodash";
import { name } from "dayjs/locale/zh-cn";
//饼图
export function getPieOption(data, title) {
let option = {
......@@ -1023,12 +1022,6 @@ export const getMultipleBarChart_m = object => {
},
yAxis: {
type: "value",
name: "数量",
nameLocation: "end",
nameGap: 5,
nameTextStyle: {
padding: [0, 40, 10, 0] // [上, 右, 下, 左] —— 减少右侧 padding 相当于左移
},
splitNumber: 5,
alignTicks: false,
axisLabel: {
......
import { ref } from "vue";
export const useChartInterpretation = () => {
const loading = ref(false);
const interpretation = ref("");
const error = ref(null);
const interpret = async text => {
loading.value = true;
error.value = null;
interpretation.value = "";
try {
const response = await fetch("/aiAnalysis/chart_interpretation", {
method: "POST",
headers: {
"X-API-Key": "aircasKEY19491001",
"Content-Type": "application/json"
},
body: JSON.stringify({ text })
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = "";
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split("\n");
buffer = lines.pop() || "";
for (const line of lines) {
if (line.startsWith("data: ")) {
const content = line.substring(6);
const textMatch = content.match(/"解读":\s*"([^"]*)"/);
if (textMatch && textMatch[1]) {
interpretation.value = textMatch[1];
}
}
}
}
} catch (err) {
error.value = err.message || "AI 解读失败";
console.error("AI Chart Interpretation Error:", err);
} finally {
loading.value = false;
}
};
return {
loading,
interpretation,
error,
interpret
};
};
......@@ -19,7 +19,6 @@
<div class="title">
<div class="box"></div>
<div class="text">科技领域</div>
<!-- <el-checkbox v-model="allTechFieldsChecked" label="全部" @change="handleAllTechFieldsChange" /> -->
</div>
<div class="checkbox-group">
<el-checkbox
......@@ -32,8 +31,7 @@
</div>
<div class="title">
<div class="box"></div>
<div class="text">管控等级</div>
<!-- <el-checkbox v-model="allControlReasonChecked" label="全部" @change="handleAllControlReasonChange" /> -->
<div class="text">管控原因</div>
</div>
<div class="checkbox-group">
<el-checkbox
......@@ -62,7 +60,7 @@
<div class="list-content" v-for="(ele, j) in element.cclChildren" :key="j">
<div class="content-title" @click="ele.isExpand = !ele.isExpand">
<div class="code-zone">
<div class="dot" v-if="ele.changeFlag"></div>
<!-- <div class="dot" v-if="ele.isDot"></div> -->
<span class="code">{{ ele.cclCode }}</span>
</div>
<span class="name">{{ ele.cclTitleZh }}</span>
......@@ -123,9 +121,9 @@ const getTechFields = async () => {
const res = await getAreaType();
if (res && res.code === 200) {
console.log("-----getTechFields", res.data);
techFields.value = [{ id: "0", name: "全部领域", checked: true }].concat(res.data);
techFields.value = res.data;
// 默认选中第一个
// techFields.value[0].checked = true;
techFields.value[0].checked = true;
}
} catch (error) {
console.error("获取科技领域字典失败:", error);
......@@ -138,9 +136,9 @@ const getControlReasonList = async () => {
const res = await getControlReason();
if (res && res.code === 200) {
console.log("-----getControlReasonList", res.data);
controlReason.value = [{ id: "0", name: "全部等级", checked: true }].concat(res.data);
controlReason.value = res.data;
// 默认选中第一个
// controlReason.value[0].checked = true;
controlReason.value[0].checked = true;
}
} catch (error) {
console.error("获取管控原因字典失败:", error);
......@@ -153,22 +151,8 @@ const viewNew = ref(true);
// 获取ccl清单列表
const getCclList = async () => {
let techDomains = [];
// 判断是否“全部领域”被选中(即 techFields[0].checked === true)
if (techFields.value.length > 0 && techFields.value[0].checked) {
techDomains = []; // 全部领域 → 不传过滤条件(空数组)
} else {
// 否则,只取非 "0" 且 checked 的项的 id
techDomains = techFields.value.filter(item => item.id !== "0" && item.checked).map(item => item.id);
}
let controls = [];
if (controlReason.value.length > 0 && controlReason.value[0].checked) {
controls = []; // 全部等级 → 不过滤
} else {
controls = controlReason.value.filter(item => item.id !== "0" && item.checked).map(item => item.id);
}
// let controls = controlReason.value.filter(item => item.checked).map(item => item.id);
let techDomains = techFields.value.filter(item => item.checked).map(item => +item.id);
let controls = controlReason.value.filter(item => item.checked).map(item => +item.id);
const params = {
categoryCode: currentCCLType.value,
techDomainIds: techDomains,
......@@ -181,7 +165,70 @@ const getCclList = async () => {
try {
// const res = await getCclQuery(null);
const res = await getCclQuery(params);
// const res = {
// "code": 200,
// "message": "操作成功",
// "success": true,
// "data": [
// {
// "id": 1,
// "cclCode": "0",
// "cclTitle": "Nuclear Materials, Facilities and Equipment and Miscellaneous",
// "cclTitleZh": "核材料、设备设施及其他类似物项",
// "cclDescription": null,
// "cclDescriptionZh": null,
// "cclChildren": [
// {
// "id": 11,
// "cclCode": "A",
// "cclTitle": "Equipment, Assemblies and Components",
// "cclTitleZh": "设备、组件和部件",
// "cclDescription": null,
// "cclDescriptionZh": null,
// "cclChildren": [
// {
// "id": 1,
// "cclCode": "0A002",
// "cclTitle": "Power generating or propulsion equipment \"specially designed\" for use with space, marine or mobile \"nuclear reactors\". (These items are \"subject to the ITAR.\" See 22 CFR parts 120 through 130.)",
// "cclTitleZh": "专为太空、海洋或移动“核反应堆”设计的发电或推进设备。(这些项目“受 ITAR 约束”。参见 22 CFR 第 120 至 130 部分。)",
// "cclDescription": null,
// "cclDescriptionZh": null,
// "cclChildren": null
// },
// {
// "id": 2,
// "cclCode": "0A501",
// "cclTitle": "Firearms (except 0A502 shotguns, 0A506 semi-automatic rifles, 0A507 semi-automatic pistols, and 0A508 semi-automatic shotguns) and related commodities (except semi-automatic related commodities enumerated or otherwise described in Eccn 0A509 for Eccns 0A506, 0A507, or 0A508) as follows (see List of Items controlled).",
// "cclTitleZh": "火器(除 0A502 霰弹枪、0A506 半自动步枪、0A507 半自动手枪和 0A508 半自动霰弹枪外)及相关商品(除 Eccn 0A509 中列举或以其他方式描述的 Eccns 0A506、0A507 或 0A508 相关物品外),具体如下(参见管制物品列表)。",
// "cclDescription": "<p class=\"flush-paragraph-1\"> <span class=\"minor-caps\">License Requirements</span></p><p class=\"flush-paragraph-1\"><em>Reason for Control:</em> NS, RS, FC, UN, AT</p><div class=\"table-wrapper\"><div class=\"gpotbl_div\"><table border=\"1\" cellpadding=\"1\" cellspacing=\"1\" class=\"gpo_table\" frame=\"void\" width=\"100%\"><thead><tr><th class=\"center\">Control(s)</th><th class=\"center\">Country chart<br>(see Supp. No. 1 to part 738)</th></tr></thead><tbody><tr><td class=\"left\">NS applies to entire entry except 0A501.y</td><td class=\"left\">NS Column 1.</td></tr><tr><td class=\"left\">RS applies to entire entry except 0A501.y</td><td class=\"left\">RS Column 1.</td></tr><tr><td class=\"left\">FC applies to entire entry except 0A501.y</td><td class=\"left\">FC Column 1.</td></tr><tr><td class=\"left\">UN applies to entire entry</td><td class=\"left\">See § 746.1 of the EAR for UN controls.</td></tr><tr><td class=\"left\">AT applies to entire entry</td><td class=\"left\">AT Column 1.</td></tr></tbody></table></div></div><div class=\"note\"><div class=\"header\"><em>License Requirement Note:</em></div><p><em>In addition to using the Commerce Country Chart to determine license requirements, a license is required for exports and reexports of ECCN 0A501.y.7 firearms to the People's Republic of China.</em></p></div><p class=\"flush-paragraph-1\">List Based License Exceptions (See Part 740 for a Description of All License Exceptions)</p><p class=\"flush-paragraph-1\"><em>LVS:</em> $500 for 0A501.c, .d, and .x.</p><p class=\"flush-paragraph-1\">$500 for 0A501.c, .d, .e, and .x if the ultimate destination is Canada.</p><p class=\"flush-paragraph-1\"><em>GBS:</em> N/A</p><p class=\"flush-paragraph-1\"> <span class=\"minor-caps\">Special Conditions for STA</span></p><p class=\"flush-paragraph-1\">License Exception STA may not be used for ECCN 0A501.a, .b, .c, .d, or .e, to any of the destinations listed in Country Group A:5 or A:6 (See supplement no.1 to part 740 of the EAR). License Exception STA may not be used for any item in this entry to any of the destinations listed in Country Group A:6 (See Supplement No.1 to part 740 of the EAR).</p><p class=\"flush-paragraph-1\"> <span class=\"minor-caps\">List of Items Controlled</span></p><p class=\"flush-paragraph-1\"><em>Related Controls:</em> (1) See USML Category I for firearms that are fully automatic, and certain related parts, components, accessories, and attachments (including magazines with a capacity of greater than 50 rounds). (2) See ECCN 0A506 for semi-automatic rifles. (3) See ECCN 0A507 for semi-automatic pistols. (4) See ECCN 0A508 for semi-automatic shotguns and ECCN 0A502 for certain \"parts\" and \"components\" for semi-automatic shotguns that are not controlled by 0A509.a or .c. (5) See ECCN 0A509 for enumerated or otherwise described \"parts,\" \"components,\" devices, \"accessories,\" and \"attachments\" for ECCNs 0A506, 0A507, and 0A508. (6) See .d, .x, and .y of this entry for other \"parts,\" \"components,\" \"accessories,\" and \"attachments\" \"specially designed\" for 0A506 and 0A507, or 0A508. (7) See ECCN 0A502 for non-automatic shotguns and their \"parts\" and \"components\" that are subject to the EAR and for certain \"parts\" and \"components\" for semi-automatic shotguns that are not controlled by 0A509.a or .c. (8) See ECCN 0A504 and USML Category XII for controls on optical sighting devices.</p><p class=\"flush-paragraph-1\"><em>Related Definitions:</em> N/A.</p><p class=\"flush-paragraph\"><em>Items:</em></p><p>a. Non-automatic and non-semi-automatic firearms equal to .50 caliber (12.7 mm) or less.</p><div class=\"note\"><div class=\"header\"><em>Note 1 to paragraph 0A501.a:</em></div><p><em>'Combination pistols' are controlled under ECCN 0A501.a. A 'combination pistol' (a.k.a., a combination gun) has at least one rifled barrel and at least one smoothbore barrel (generally a shotgun style barrel).</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 2 to paragraph 0A501.a:</em></div><p><em>Semi-automatic firearms</em> equal to .50 caliber (12.7 mm) or less <em>are controlled under ECCNs 0A506 and 0A507.</em></p></div><div class=\"note\"><div class=\"header\"><em>Technical Note to 0A501.a:</em></div><p><em>Firearms described in 0A501.a include those chambered for the .50 BMG cartridge.</em></p></div><p>b. Non-automatic and non-semi-automatic rifles, carbines, revolvers or pistols with a caliber greater than .50 inches (12.7 mm) but less than or equal to .72 inches (18.0 mm).</p><p>c. The following types of \"parts\" and \"components\" if \"specially designed\" for a commodity controlled by paragraph .a or .b of this entry or ECCNs 0A506 or 0A507, or USML Category I (unless otherwise enumerated or elsewhere specified on the USML or controlled under ECCN 0A509): Barrels, cylinders, barrel extensions, mounting blocks (trunnions), bolts, bolt carriers, operating rods, gas pistons, trigger housings, triggers, hammers/striker, sears, disconnectors, pistol grips that contain fire control \"parts\" or \"components\" (<em>e.g.,</em> triggers, hammers/striker, sears, disconnectors) and buttstocks that contain fire control \"parts\" or \"components.\"</p><div class=\"note\"><div class=\"header\"><em>Technical Note to 0A501.c:</em></div><p><em>Barrel blanks that have reached a stage in manufacturing in which they are either chambered or rifled are controlled by 0A501.c.</em></p></div><p>d. Detachable magazines with a capacity of 17 to 50 rounds \"specially designed\" for a commodity controlled by paragraph .a or .b of this entry or controlled by ECCNs 0A506 or 0A507.</p><div class=\"note\"><div class=\"header\"><em>Note 3 to paragraph 0A501.d</em></div><p><em>Magazines with a capacity of 16 rounds or less are controlled under 0A501.x; for magazines with a capacity greater than 50 rounds, see USML Category I. Magazines that hold only blank ammunition controlled under 0A505.d are controlled under 0A501.d or 0A501.x, depending on the magazine's capacity.</em></p></div><p>e. Receivers (frames) and \"complete breech mechanisms,\" including castings, forgings, stampings, or machined items thereof, \"specially designed\" for a commodity controlled by paragraph .a or .b of this entry.</p><div class=\"note\"><div class=\"header\"><em>Note 4 to 0A501.e:</em></div><p><em>Frames (receivers) under 0A501.e refers to any \"part\" or \"component\" of the firearm that has or is customarily marked with a serial number when required by law. This paragraph 0A501.e is synonymous with a \"part\" or \"component\" that is regulated by the Bureau of Alcohol, Tobacco, Firearms and Explosives (see <a href=\"https://www.govinfo.gov/link/uscode/18/921\" class=\"usc external\" target=\"_blank\" rel=\"noopener noreferrer\">18 U.S.C. 921(a)(3)</a>; <a href=\"https://www.ecfr.gov/current/title-27/part-447\" class=\"cfr external\">27 CFR parts 447</a>, <a href=\"https://www.ecfr.gov/current/title-27/part-478\" class=\"cfr external\">478</a>, and <a href=\"https://www.ecfr.gov/current/title-27/part-479\" class=\"cfr external\">479</a>,) as a firearm.</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 5 to 0A501.e:</em></div><p><em>Frames (receivers) \"specially designed\" for semi-automatic firearms are controlled under ECCN 0A509.b or .c.</em></p></div><p>f. through w. [Reserved]</p><p>x. \"Parts\" and \"components\" that are \"specially designed\" for a commodity classified under paragraphs .a through .c of this entry, a commodity classified under ECCNs 0A506 or 0A507, or the USML and not elsewhere specified on the USML or CCL or controlled under ECCN 0A509.</p><p>y. Specific \"parts,\" \"components,\" \"accessories\" and \"attachments\" \"specially designed\" for a commodity subject to control in this ECCN, ECCNs 0A506, 0A507, or common to a defense article in USML Category I and not elsewhere specified in the USML or CCL as follows, and \"parts,\" \"components,\" \"accessories,\" and \"attachments\" \"specially designed\" therefor.</p><p>y.1. Stocks (including adjustable, collapsible, blades and braces), grips, handguards, or forends, that do not contain any fire control \"parts\" or \"components\" (<em>e.g.,</em> triggers, hammers/striker, sears, disconnectors);</p><p>y.2 through y.5. [Reserved]</p><p>y.6. Bayonets; and</p><p>y.7. Firearms manufactured from 1890 to 1898 and reproductions thereof.</p><div class=\"note\"><div class=\"header\"><em>Technical Note 1 to 0A501:</em></div><p><em>ECCN 0A501 includes \"parts\" and \"components\" that are not \"subject to the ITAR\" even though they are common to firearms described in ECCN 0A501 and to those firearms \"subject to the ITAR.\"</em></p></div><div class=\"note\"><div class=\"header\"><em>Technical Note 2 to 0A501:</em></div><p><em>A receiver with any other controlled \"part\" or \"component\" ( e.g., a barrel (0A501.c), or trigger guard (0A501.x), or stock (0A501.y.1)) is still controlled under 0A501.e.</em></p></div><div class=\"note\"><div class=\"header\"><em>Technical Note 3 to 0A501:</em></div><p><em>Blank firing adapters, which are attachments to semi-automatic and automatic firearms used in conjunction with blank cartridges for safety and functional reasons and used for firearm training purposes by police, military, sporting shooters, as well as in the movie industry, are designated as EAR99.</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 6 to 0A501:</em></div><p><em>Antique firearms (i.e., those manufactured before 1890) and reproductions thereof, muzzle loading and black powder firearms except those designs based on centerfire weapons of a post 1937 design, BB guns, pellet rifles, paint ball, and all other air rifles are EAR99 commodities.</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 7 to 0A501:</em></div><p><em>Muzzle loading and black powder firearms with a caliber less than 20 mm that were manufactured post 1937 that are used for hunting or sporting purposes that were not \"specially designed\" for military use and are not described on the USML nor controlled as shotguns under ECCN 0A502 are EAR99 commodities.</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 8 to 0A501:</em></div><p><em>Scope mounts or accessory rails, iron sights, sling swivels, and butt plates or recoil pads that are subject to the EAR are designated as EAR99. These commodities have been determined to no longer warrant being \"specially designed\" for purposes of ECCN 0A501.</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 9 to 0A501:</em></div><p><em>A kit, including a replacement or repair kit, of firearms \"parts\" or \"components\" customarily sold and exported together takes on the classification of the most restrictive \"part\" or \"component\" that is included in the kit. For example, a kit containing 0A501.y and .x \"parts,\" is controlled as a 0A501.x kit because the .x \"part\" is the most restrictive \"part\" included in the kit. A complete 0A501 firearm disassembled in a kit form is controlled as a firearm under 0A501.a, .b, or .y.7.</em></p></div>",
// "cclDescriptionZh": "<p class=\"flush-paragraph-1\"> <span class=\"minor-caps\">License Requirements</span></p><p class=\"flush-paragraph-1\"><em>Reason for Control:</em> NS, RS, FC, UN, AT</p><div class=\"table-wrapper\"><div class=\"gpotbl_div\"><table border=\"1\" cellpadding=\"1\" cellspacing=\"1\" class=\"gpo_table\" frame=\"void\" width=\"100%\"><thead><tr><th class=\"center\">控制原因</th><th class=\"center\">Country chart<br>(参见第738部分补充1号文)</th></tr></thead><tbody><tr><td class=\"left\">NS applies to entire entry except 0A501.y</td><td class=\"left\">NS Column 1.</td></tr><tr><td class=\"left\">RS applies to entire entry except 0A501.y</td><td class=\"left\">RS Column 1.</td></tr><tr><td class=\"left\">FC applies to entire entry except 0A501.y</td><td class=\"left\">FC Column 1.</td></tr><tr><td class=\"left\">UN applies to entire entry</td><td class=\"left\">See § 746.1 of the EAR for UN controls.</td></tr><tr><td class=\"left\">AT applies to entire entry</td><td class=\"left\">AT Column 1.</td></tr></tbody></table></div></div><div class=\"note\"><div class=\"header\"><em>License Requirement Note:</em></div><p><em>In addition to using the Commerce Country Chart to determine license requirements, a license is required for exports and reexports of ECCN 0A501.y.7 firearms to the People's Republic of China.</em></p></div><p class=\"flush-paragraph-1\">List Based License Exceptions (See Part 740 for a Description of All License Exceptions)</p><p class=\"flush-paragraph-1\"><em>LVS:</em> $500 for 0A501.c, .d, and .x.</p><p class=\"flush-paragraph-1\">$500 for 0A501.c, .d, .e, and .x if the ultimate destination is Canada.</p><p class=\"flush-paragraph-1\"><em>GBS:</em> N/A</p><p class=\"flush-paragraph-1\"> <span class=\"minor-caps\">Special Conditions for STA</span></p><p class=\"flush-paragraph-1\">License Exception STA may not be used for ECCN 0A501.a, .b, .c, .d, or .e, to any of the destinations listed in Country Group A:5 or A:6 (See supplement no.1 to part 740 of the EAR). License Exception STA may not be used for any item in this entry to any of the destinations listed in Country Group A:6 (See Supplement No.1 to part 740 of the EAR).</p><p class=\"flush-paragraph-1\"> <span class=\"minor-caps\">List of Items Controlled</span></p><p class=\"flush-paragraph-1\"><em>Related Controls:</em> (1) See USML Category I for firearms that are fully automatic, and certain related parts, components, accessories, and attachments (including magazines with a capacity of greater than 50 rounds). (2) See ECCN 0A506 for semi-automatic rifles. (3) See ECCN 0A507 for semi-automatic pistols. (4) See ECCN 0A508 for semi-automatic shotguns and ECCN 0A502 for certain \"parts\" and \"components\" for semi-automatic shotguns that are not controlled by 0A509.a or .c. (5) See ECCN 0A509 for enumerated or otherwise described \"parts,\" \"components,\" devices, \"accessories,\" and \"attachments\" for ECCNs 0A506, 0A507, and 0A508. (6) See .d, .x, and .y of this entry for other \"parts,\" \"components,\" \"accessories,\" and \"attachments\" \"specially designed\" for 0A506 and 0A507, or 0A508. (7) See ECCN 0A502 for non-automatic shotguns and their \"parts\" and \"components\" that are subject to the EAR and for certain \"parts\" and \"components\" for semi-automatic shotguns that are not controlled by 0A509.a or .c. (8) See ECCN 0A504 and USML Category XII for controls on optical sighting devices.</p><p class=\"flush-paragraph-1\"><em>Related Definitions:</em> N/A.</p><p class=\"flush-paragraph\"><em>Items:</em></p><p>a. Non-automatic and non-semi-automatic firearms equal to .50 caliber (12.7 mm) or less.</p><div class=\"note\"><div class=\"header\"><em>Note 1 to paragraph 0A501.a:</em></div><p><em>'Combination pistols' are controlled under ECCN 0A501.a. A 'combination pistol' (a.k.a., a combination gun) has at least one rifled barrel and at least one smoothbore barrel (generally a shotgun style barrel).</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 2 to paragraph 0A501.a:</em></div><p><em>Semi-automatic firearms</em> equal to .50 caliber (12.7 mm) or less <em>are controlled under ECCNs 0A506 and 0A507.</em></p></div><div class=\"note\"><div class=\"header\"><em>Technical Note to 0A501.a:</em></div><p><em>Firearms described in 0A501.a include those chambered for the .50 BMG cartridge.</em></p></div><p>b. Non-automatic and non-semi-automatic rifles, carbines, revolvers or pistols with a caliber greater than .50 inches (12.7 mm) but less than or equal to .72 inches (18.0 mm).</p><p>c. The following types of \"parts\" and \"components\" if \"specially designed\" for a commodity controlled by paragraph .a or .b of this entry or ECCNs 0A506 or 0A507, or USML Category I (unless otherwise enumerated or elsewhere specified on the USML or controlled under ECCN 0A509): Barrels, cylinders, barrel extensions, mounting blocks (trunnions), bolts, bolt carriers, operating rods, gas pistons, trigger housings, triggers, hammers/striker, sears, disconnectors, pistol grips that contain fire control \"parts\" or \"components\" (<em>e.g.,</em> triggers, hammers/striker, sears, disconnectors) and buttstocks that contain fire control \"parts\" or \"components.\"</p><div class=\"note\"><div class=\"header\"><em>Technical Note to 0A501.c:</em></div><p><em>Barrel blanks that have reached a stage in manufacturing in which they are either chambered or rifled are controlled by 0A501.c.</em></p></div><p>d. Detachable magazines with a capacity of 17 to 50 rounds \"specially designed\" for a commodity controlled by paragraph .a or .b of this entry or controlled by ECCNs 0A506 or 0A507.</p><div class=\"note\"><div class=\"header\"><em>Note 3 to paragraph 0A501.d</em></div><p><em>Magazines with a capacity of 16 rounds or less are controlled under 0A501.x; for magazines with a capacity greater than 50 rounds, see USML Category I. Magazines that hold only blank ammunition controlled under 0A505.d are controlled under 0A501.d or 0A501.x, depending on the magazine's capacity.</em></p></div><p>e. Receivers (frames) and \"complete breech mechanisms,\" including castings, forgings, stampings, or machined items thereof, \"specially designed\" for a commodity controlled by paragraph .a or .b of this entry.</p><div class=\"note\"><div class=\"header\"><em>Note 4 to 0A501.e:</em></div><p><em>Frames (receivers) under 0A501.e refers to any \"part\" or \"component\" of the firearm that has or is customarily marked with a serial number when required by law. This paragraph 0A501.e is synonymous with a \"part\" or \"component\" that is regulated by the Bureau of Alcohol, Tobacco, Firearms and Explosives (see <a href=\"https://www.govinfo.gov/link/uscode/18/921\" class=\"usc external\" target=\"_blank\" rel=\"noopener noreferrer\">18 U.S.C. 921(a)(3)</a>; <a href=\"https://www.ecfr.gov/current/title-27/part-447\" class=\"cfr external\">27 CFR parts 447</a>, <a href=\"https://www.ecfr.gov/current/title-27/part-478\" class=\"cfr external\">478</a>, and <a href=\"https://www.ecfr.gov/current/title-27/part-479\" class=\"cfr external\">479</a>,) as a firearm.</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 5 to 0A501.e:</em></div><p><em>Frames (receivers) \"specially designed\" for semi-automatic firearms are controlled under ECCN 0A509.b or .c.</em></p></div><p>f. through w. [Reserved]</p><p>x. \"Parts\" and \"components\" that are \"specially designed\" for a commodity classified under paragraphs .a through .c of this entry, a commodity classified under ECCNs 0A506 or 0A507, or the USML and not elsewhere specified on the USML or CCL or controlled under ECCN 0A509.</p><p>y. Specific \"parts,\" \"components,\" \"accessories\" and \"attachments\" \"specially designed\" for a commodity subject to control in this ECCN, ECCNs 0A506, 0A507, or common to a defense article in USML Category I and not elsewhere specified in the USML or CCL as follows, and \"parts,\" \"components,\" \"accessories,\" and \"attachments\" \"specially designed\" therefor.</p><p>y.1. Stocks (including adjustable, collapsible, blades and braces), grips, handguards, or forends, that do not contain any fire control \"parts\" or \"components\" (<em>e.g.,</em> triggers, hammers/striker, sears, disconnectors);</p><p>y.2 through y.5. [Reserved]</p><p>y.6. Bayonets; and</p><p>y.7. Firearms manufactured from 1890 to 1898 and reproductions thereof.</p><div class=\"note\"><div class=\"header\"><em>Technical Note 1 to 0A501:</em></div><p><em>ECCN 0A501 includes \"parts\" and \"components\" that are not \"subject to the ITAR\" even though they are common to firearms described in ECCN 0A501 and to those firearms \"subject to the ITAR.\"</em></p></div><div class=\"note\"><div class=\"header\"><em>Technical Note 2 to 0A501:</em></div><p><em>A receiver with any other controlled \"part\" or \"component\" ( e.g., a barrel (0A501.c), or trigger guard (0A501.x), or stock (0A501.y.1)) is still controlled under 0A501.e.</em></p></div><div class=\"note\"><div class=\"header\"><em>Technical Note 3 to 0A501:</em></div><p><em>Blank firing adapters, which are attachments to semi-automatic and automatic firearms used in conjunction with blank cartridges for safety and functional reasons and used for firearm training purposes by police, military, sporting shooters, as well as in the movie industry, are designated as EAR99.</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 6 to 0A501:</em></div><p><em>Antique firearms (i.e., those manufactured before 1890) and reproductions thereof, muzzle loading and black powder firearms except those designs based on centerfire weapons of a post 1937 design, BB guns, pellet rifles, paint ball, and all other air rifles are EAR99 commodities.</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 7 to 0A501:</em></div><p><em>Muzzle loading and black powder firearms with a caliber less than 20 mm that were manufactured post 1937 that are used for hunting or sporting purposes that were not \"specially designed\" for military use and are not described on the USML nor controlled as shotguns under ECCN 0A502 are EAR99 commodities.</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 8 to 0A501:</em></div><p><em>Scope mounts or accessory rails, iron sights, sling swivels, and butt plates or recoil pads that are subject to the EAR are designated as EAR99. These commodities have been determined to no longer warrant being \"specially designed\" for purposes of ECCN 0A501.</em></p></div><div class=\"note\"><div class=\"header\"><em>Note 9 to 0A501:</em></div><p><em>A kit, including a replacement or repair kit, of firearms \"parts\" or \"components\" customarily sold and exported together takes on the classification of the most restrictive \"part\" or \"component\" that is included in the kit. For example, a kit containing 0A501.y and .x \"parts,\" is controlled as a 0A501.x kit because the .x \"part\" is the most restrictive \"part\" included in the kit. A complete 0A501 firearm disassembled in a kit form is controlled as a firearm under 0A501.a, .b, or .y.7.</em></p></div>",
// "cclChildren": null
// },
// {
// "id": 3,
// "cclCode": "0A502",
// "cclTitle": "Shotguns; shotguns \"parts\" and \"components,\" consisting of complete trigger mechanisms; magazines and magazine extension tubes; \"complete breech mechanisms;\" except: semi-automatic shotguns controlled under Eccn 0A508; certain \"parts,\" components,\" devices, \"accessories,\" and \"attachments\" for semi-automatic shotguns controlled under Eccn 0A509; equipment used to slaughter domestic animals or used exclusively to treat or tranquilize animals; and arms designed solely for signal, flare, or saluting use.",
// "cclTitleZh": "霰弹枪;霰弹枪“零件”和“组件”,由完整的扳机机构组成;弹药库和弹匣延长管;“完整的闭锁机构”;除外:根据 Eccn 0A508 控制的半自动霰弹枪;根据 Eccn 0A509 控制的某些半自动霰弹枪的“零件”、“组件”、“装置”、“配件”;用于屠宰家畜或专门用于治疗或镇静动物的设备;以及仅用于信号、照明或敬礼使用的武器。",
// "cclDescription": null,
// "cclDescriptionZh": null,
// "cclChildren": null
// }
// ]
// }
// ]
// }
// ]
// }
// cclList.value = res.data
// // 给数据添加isExpand字段
// cclList.value.forEach((item) => {
// item.isExpand = false
// item.cclChildren.forEach((ele) => {
// ele.cclChildren.forEach((i) => {
// i.isExpand = false
// })
// })
// })
if (res && res.code === 200) {
console.log("----getCclList", res.data);
cclList.value = res.data;
......@@ -223,100 +270,26 @@ const getCCLVersionListApi = async () => {
console.error("获取清单版本列表失败:", error);
}
};
const allTechFieldsChecked = ref(false);
const allControlReasonChecked = ref(false);
// 筛选逻辑处理
// 筛选逻辑处理
const handleFilterChange = (item, list, type) => {
console.log(item, list, type);
if (type === "tech") {
if (item.id == "0") {
if (item.checked) {
list.forEach((field, index) => {
if (index !== 0) field.checked = false;
});
} else {
if (list.length > 1) {
list[1].checked = true;
for (let i = 2; i < list.length; i++) {
list[i].checked = false;
}
}
}
} else {
const allItem = list[0];
if (allItem) {
allItem.checked = false;
}
}
} else if (type === "reason") {
// 👇 新增:对 controlReason 做同样处理
if (item.id == "0") {
if (item.checked) {
// 选中“全部等级” → 取消其他
list.forEach((field, index) => {
if (index !== 0) field.checked = false;
});
} else {
// 取消“全部等级” → 选中 index=1
if (list.length > 1) {
list[1].checked = true;
for (let i = 2; i < list.length; i++) {
list[i].checked = false;
}
}
}
} else {
// 点击非“全部”项 → 取消“全部”
const allItem = list[0];
if (allItem) {
allItem.checked = false;
}
}
}
getCclList();
};
// 处理“科技领域-全部”复选框变化
const handleAllTechFieldsChange = checked => {
if (checked) {
// 全选:所有 techFields.checked = true
techFields.value.forEach(item => (item.checked = true));
} else {
// 取消全选:只保留第一个选中
techFields.value.forEach((item, index) => {
item.checked = index === 0;
});
}
// 触发数据刷新
watch(viewNew, newValue => {
getCclList();
};
});
// 处理“管控原因-全部”复选框变化
const handleAllControlReasonChange = checked => {
if (checked) {
controlReason.value.forEach(item => (item.checked = true));
} else {
controlReason.value.forEach((item, index) => {
item.checked = index === 0;
});
}
watch(currentCCLType, newValue => {
console.log(newValue);
getCclList();
};
// watch(viewNew, newValue => {
// getCclList();
// });
// watch(currentCCLType, newValue => {
// console.log(newValue);
// getCclList();
// });
});
// watch(currentCCLVersion, newValue => {
// console.log(newValue);
// getCclList();
// });
watch(currentCCLVersion, newValue => {
console.log(newValue);
getCclList();
});
// const searchDebounceTimer = ref(null);
// watch(searchKeyword, () => {
......@@ -328,21 +301,10 @@ const handleAllControlReasonChange = checked => {
// getExportControlListApi();
// }, 300);
// });
// watch(searchKeyword, newValue => {
// console.log("-----searchKey", newValue);
// getCclList();
// });
watch(
[viewNew, currentCCLType, currentCCLVersion, searchKeyword],
([newViewNew, newType, newVersion, newKeyword], [oldViewNew, oldType, oldVersion, oldKeyword]) => {
// 可选:判断是否是真正有意义的变化(避免初始赋值触发)
if (newViewNew !== oldViewNew || newType !== oldType || newVersion !== oldVersion || newKeyword !== oldKeyword) {
watch(searchKeyword, newValue => {
console.log("-----searchKey", newValue);
getCclList();
}
},
{ immediate: false } // 如果不需要初始触发,设为 false(默认)
);
});
// 模拟清单列表
const cclList = ref([
......@@ -411,9 +373,6 @@ onMounted(async () => {
:deep(.el-input__wrapper) {
padding: 0 11px;
border: 1px solid #dcdfe6;
background-color: #fff;
border-radius: 4px;
}
:deep(.el-input__inner) {
......@@ -775,9 +734,7 @@ onMounted(async () => {
display: flex;
align-items: center;
padding: 14px 12px 16px 0;
display: flex;
align-items: center;
justify-content: space-between;
.box {
width: 8px;
height: 16px;
......@@ -793,7 +750,6 @@ onMounted(async () => {
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(5, 95, 194);
margin-right: auto;
}
}
</style>
......@@ -31,7 +31,7 @@
<div class="info-row">
<div class="label">发布人:</div>
<div class="value link">
<img :src="formattedData.avartarUrl" alt="" class="icon avatar" />
<img :src="defaultTitle" alt="" class="icon avatar" />
<span @click="handleClick">{{ formattedData.postPersonName }} ></span>
</div>
</div>
......@@ -46,7 +46,7 @@
<div class="content-title">制裁实体分布:</div>
<div class="distribution-list">
<div class="list-item" v-for="(item, index) in entityDistribution" :key="index">
<img :src="item.imageUrl || flag" alt="" class="flag" />
<img :src="flag" alt="" class="flag" />
<div class="country-name">{{ item.name }}</div>
<div class="progress-bar-container">
<div
......@@ -152,7 +152,6 @@
</div>
<div class="right-content">
<div class="sanction-group-list">
<el-empty v-if="sanctionList.length === 0" description="暂无制裁清单数据" />
<div class="sanction-group" v-for="(group, index) in sanctionList" :key="index">
<el-table :data="group.entities" style="width: 100%">
<el-table-column label="实体名称" min-width="280">
......@@ -303,7 +302,7 @@ const getSanctionOverviewList = async () => {
removeCount.value = data.removeCount || 0;
removeRuleCount.value = data.removeRuleCount || 0;
const list = searchType.value == "add" ? data.sanList : data.removeList || [];
const list = data.sanList || [];
sanctionList.value = list.map(item => ({
reason: item.sanReason,
entities: (item.orgList || []).map(org => ({
......@@ -449,8 +448,7 @@ const formattedData = computed(() => {
fileCode: info.fileCode ? `${info.fileCode} ` : "",
administrativeOrderId: info.administrativeOrderId ? `No. ${info.administrativeOrderId}` : "",
postPersonName: info.postPersonName,
domains: info.domainNames,
avartarUrl: info.postPersonAvatarUrl
domains: info.domainNames
};
});
......
......@@ -13,14 +13,8 @@
</div> -->
<div class="home-main-header-center">
<SearchContainer
class="think-tank-search"
style="margin-bottom: 0; margin-top: 51px; height: fit-content"
v-if="containerRef"
placeholder="搜索智库、报告或政策建议"
:containerRef="containerRef"
areaName="智库"
/>
<SearchContainer class="think-tank-search" style="margin-bottom: 0; margin-top: 51px; height: fit-content;"
v-if="containerRef" placeholder="搜索智库、报告或政策建议" :containerRef="containerRef" areaName="智库" />
<!-- <el-input v-model="searchThinktankText" @keyup.enter="handleSearch"
style="width: 838px; height: 100%" placeholder="搜索智库报告" />
<div class="search">
......@@ -63,9 +57,8 @@
</div>
<div class="home-main-header-card-box">
<div class="card" v-for="(item, index) in sortedCardList" :key="index" @click="handleClick(item)">
<div class="red-info" v-if="item.increaseReportNumber != 0 && item.increaseReportNumber != null">
{{ "+" }}{{ item.increaseReportNumber }}
</div>
<div class="red-info" v-if="item.increaseReportNumber != 0 && item.increaseReportNumber != null">{{ "+" }}{{
item.increaseReportNumber }}</div>
<div class="card-header">
<div class="icon">
<img :src="item.logo" alt="" />
......@@ -74,7 +67,8 @@
{{ "No." + (index + 1) }}
</div> -->
<div class="rank">
<div class="number">{{ item.reportNumber }} {{ "篇报告" }}</div>
<div class=" number">{{ item.reportNumber }} {{ "篇报告" }}</div>
</div>
</div>
<div class="card-title">
......@@ -128,14 +122,8 @@
</div>
<div class="box1-header-right" @click="handleClickToDetail">查看详情 ></div>
</div>
<el-carousel
ref="carouselRef"
height="395px"
:autoplay="true"
:interval="3000"
arrow="never"
indicator-position="none"
>
<el-carousel ref="carouselRef" height="395px" :autoplay="true" :interval="3000" arrow="never"
indicator-position="none">
<el-carousel-item v-for="(itemData, index) in box1Data" :key="index">
<div class="box1-main">
<div class="box1-main-left">
......@@ -144,6 +132,7 @@
<div class="box1-main-right">
<div class="title">{{ itemData?.reportName }}</div>
<div class="name">
<div class="logo-title-box">
<div class="logo">
......@@ -159,11 +148,8 @@
<!-- <div class="tag" v-for="(item, index) in itemData?.industryVOList" :key="index">
{{ item.industryName }}
</div> -->
<AreaTag
v-for="(item, index) in itemData?.industryVOList"
:key="index"
:tagName="item.industryName"
>
<AreaTag v-for="(item, index) in itemData?.industryVOList" :key="index"
:tagName="item.industryName">
</AreaTag>
</div>
</div>
......@@ -172,34 +158,15 @@
</el-carousel-item>
</el-carousel>
</div>
<RiskSignal
:list="warningList"
@more-click="handleToMoreRiskSignal"
postDate="time"
name="title"
@item-click="handleClickToDetail"
/>
<RiskSignal :list="warningList" @more-click="handleToMoreRiskSignal" postDate="time" name="title"
@item-click="handleClickToDetail" />
</div>
<DivideHeader id="position2" class="divide-header" :titleText="'资讯要闻'"></DivideHeader>
<div class="center-center">
<NewsList
:newsList="newsList"
@item-click="handleToNewsAnalysis"
@more-click="handleToMoreNews"
img="newsImage"
title="newsTitle"
content="newsContent"
from="from"
/>
<MessageBubble
:messageList="messageList"
imageUrl="personImage"
@more-click="handleToSocialDetail"
@person-click="handleClickPerson"
name="personName"
content="remarks"
source="orgName"
/>
<NewsList :newsList="newsList" @item-click="handleToNewsAnalysis" @more-click="handleToMoreNews"
img="newsImage" title="newsTitle" content="newsContent" from="from" />
<MessageBubble :messageList="messageList" imageUrl="personImage" @more-click="handleToSocialDetail"
@person-click="handleClickPerson" name="personName" content="remarks" source="orgName" />
</div>
<DivideHeader id="position3" class="divide-header" :titleText="'数据总览'"></DivideHeader>
<div class="center-footer">
......@@ -212,33 +179,16 @@
<div class="box5-header-title">{{ "数量变化趋势" }}</div>
</div>
<div class="box5-select-box">
<el-select
v-model="box5selectetedArea"
placeholder="选择领域"
style="width: 120px"
@change="handleBox5AreaChange"
>
<el-select v-model="box5selectetedArea" placeholder="选择领域" style="width: 120px"
@change="handleBox5AreaChange">
<el-option label="全部领域" value="全部领域" />
<el-option
v-for="item in box5RawData.data"
:key="item.name"
:label="item.name"
:value="item.name"
/>
<el-option v-for="item in box5RawData.data" :key="item.name" :label="item.name" :value="item.name" />
</el-select>
<el-select
v-model="box5selectetedYear"
placeholder="选择年份"
style="width: 120px"
@change="changeBox5Data"
>
<el-option
v-for="item in box5YearList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
<el-select v-model="box5selectetedYear" placeholder="选择年份" style="width: 120px"
@change="changeBox5Data">
<el-option v-for="item in box5YearList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
</div>
<div class="box5-main" :class="{ 'box5-main--empty': !hasBox5ChartData }">
......@@ -253,18 +203,11 @@
<TipTab :text="'智库报告数量变化趋势,数据来源:美国各智库官网'" />
</div>
<div class="chart-box">
<div
class="btn-box"
v-if="!isShowAiContentBox5"
@mouseenter="handleSwitchAiContentShowBox5(true)"
>
<div class="btn-box" v-if="!isShowAiContentBox5" @mouseenter="handleSwitchAiContentShowBox5(true)">
<AiButton />
</div>
<div
class="content-box"
v-if="isShowAiContentBox5"
@mouseleave="handleSwitchAiContentShowBox5(false)"
>
<div class="content-box" v-if="isShowAiContentBox5"
@mouseleave="handleSwitchAiContentShowBox5(false)">
<AiPane :aiContent="aiContentBox5" />
</div>
</div>
......@@ -280,22 +223,13 @@
<div class="box6-select-box">
<el-select v-model="box6selectetedTank" placeholder="选择智库" style="width: 120px">
<el-option label="全部智库" value="全部智库" />
<el-option
v-for="item in box6TankList"
:key="item.value"
:label="item.label"
:value="item.value"
/>
<el-option v-for="item in box6TankList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-select v-model="box6selectetedYear" placeholder="选择时间" style="width: 120px">
<el-option
v-for="item in box6YearList"
:key="item.value"
:label="item.label"
:value="item.value"
@click="handleBox6()"
/>
<el-option v-for="item in box6YearList" :key="item.value" :label="item.label" :value="item.value"
@click="handleBox6()" />
</el-select>
</div>
</div>
......@@ -309,18 +243,11 @@
<TipTab :text="'智库报告领域分布情况,数据来源:美国各智库官网'" />
</div>
<div class="chart-box">
<div
class="btn-box"
v-if="!isShowAiContentBox6"
@mouseenter="handleSwitchAiContentShowBox6(true)"
>
<div class="btn-box" v-if="!isShowAiContentBox6" @mouseenter="handleSwitchAiContentShowBox6(true)">
<AiButton />
</div>
<div
class="content-box"
v-if="isShowAiContentBox6"
@mouseleave="handleSwitchAiContentShowBox6(false)"
>
<div class="content-box" v-if="isShowAiContentBox6"
@mouseleave="handleSwitchAiContentShowBox6(false)">
<AiPane :aiContent="aiContentBox6" />
</div>
</div>
......@@ -348,18 +275,11 @@
<TipTab :text="'美国科技智库与主要政府机构之间的资金往来,数据来源:美国各智库官网'" />
</div>
<div class="chart-box">
<div
class="btn-box"
v-if="!isShowAiContentBox7"
@mouseenter="handleSwitchAiContentShowBox7(true)"
>
<div class="btn-box" v-if="!isShowAiContentBox7" @mouseenter="handleSwitchAiContentShowBox7(true)">
<AiButton />
</div>
<div
class="content-box"
v-if="isShowAiContentBox7"
@mouseleave="handleSwitchAiContentShowBox7(false)"
>
<div class="content-box" v-if="isShowAiContentBox7"
@mouseleave="handleSwitchAiContentShowBox7(false)">
<AiPane :aiContent="aiContentBox7" />
</div>
</div>
......@@ -374,22 +294,19 @@
</div>
<div class="box8-header-title">{{ "智库研究热点" }}</div>
</div>
</div>
<div class="box8-main">
<div class="box8-main-item">
<div class="box8-item" v-for="(item, index) in box8Data" :key="index">
<div
class="item-left"
:class="{ itemBold1: index === 0, itemBold2: index === 1, itemBold3: index === 2 }"
>
<div class="item-left"
:class="{ itemBold1: index === 0, itemBold2: index === 1, itemBold3: index === 2 }">
{{ index + 1 }}
</div>
<!-- <el-popover effect="dark" :content="item.clause" placement="top-start">
<template #reference> -->
<div
class="item-center"
:class="{ itemBold1: index === 0, itemBold2: index === 1, itemBold3: index === 2 }"
>
<div class="item-center"
:class="{ itemBold1: index === 0, itemBold2: index === 1, itemBold3: index === 2 }">
{{ item.clause }}
</div>
<!-- </template>
......@@ -398,7 +315,9 @@
<!-- <div class="item-right">{{ `${item.count}份报告 >` }}</div> -->
<div class="item-count">{{ item.count + "份报告 >" }}</div>
</div>
</div>
</div>
</div>
</div>
......@@ -409,42 +328,21 @@
<div class="home-main-footer-header">
<div class="btn-box">
<div
class="btn"
:class="{ btnActive: activeCate === cate }"
v-for="(cate, index) in categoryList"
:key="index"
@click="handleClickCate(cate)"
>
<div class="btn" :class="{ btnActive: activeCate === cate }" v-for="(cate, index) in categoryList"
:key="index" @click="handleClickCate(cate)">
{{ cate }}
</div>
</div>
<div class="select-box">
<el-select
v-model="resourceLibrarySortModel"
class="resource-library-sort-select"
placeholder="发布时间"
style="width: 120px"
:teleported="true"
placement="bottom-start"
:popper-options="resourceLibrarySortPopperOptions"
@change="handleResourceLibrarySortChange"
>
<el-select v-model="resourceLibrarySortModel" class="resource-library-sort-select" placeholder="发布时间"
style="width: 120px" :teleported="true" placement="bottom-start"
:popper-options="resourceLibrarySortPopperOptions" @change="handleResourceLibrarySortChange">
<template #prefix>
<img
v-if="resourceLibrarySortModel !== true"
<img v-if="resourceLibrarySortModel !== true"
src="@/views/thinkTank/ThinkTankDetail/thinkDynamics/images/image down.png"
class="resource-library-sort-prefix-img"
alt=""
@click.stop="toggleResourceLibrarySortPrefix"
/>
<img
v-else
src="@/views/thinkTank/ThinkTankDetail/thinkDynamics/images/image up.png"
class="resource-library-sort-prefix-img"
alt=""
@click.stop="toggleResourceLibrarySortPrefix"
/>
class="resource-library-sort-prefix-img" alt="" @click.stop="toggleResourceLibrarySortPrefix" />
<img v-else src="@/views/thinkTank/ThinkTankDetail/thinkDynamics/images/image up.png"
class="resource-library-sort-prefix-img" alt="" @click.stop="toggleResourceLibrarySortPrefix" />
</template>
<el-option :key="'resource-lib-sort-asc'" label="正序" :value="true" />
<el-option :key="'resource-lib-sort-desc'" label="倒序" :value="false" />
......@@ -456,54 +354,25 @@
</el-select> -->
</div>
<div class="resource-library-content">
<HomeMainFooterMain
v-if="activeCate === '智库报告'"
:area-list="areaList"
v-model:selectedAreaList="selectedAreaList"
:pub-time-list="pubTimeList"
v-model:selectedPubTimeList="selectedPubTimeList"
@filter-change="handleThinkTankReportFilterChange"
:cur-footer-list="curFooterList"
:total="total"
:current-page="currentPage"
@report-click="handleToReportDetail"
@page-change="handleCurrentChange"
/>
<HomeMainFooterSurvey
v-else-if="activeCate === '调查项目'"
:area-list="areaList"
v-model:selectedAreaList="surveySelectedAreaList"
:pub-time-list="pubTimeList"
v-model:selectedPubTimeList="surveySelectedPubTimeList"
@filter-change="handleSurveyFilterChange"
:cur-footer-list="surveyFooterList"
:total="surveyTotal"
:current-page="surveyCurrentPage"
@report-click="handleToReportDetail"
@page-change="handleSurveyCurrentChange"
/>
<ThinkTankCongressHearingOverview
v-else-if="activeCate === '国会听证会'"
:key="`congress-${resourceTabResetKey}`"
:research-type-list="areaList"
:research-time-list="pubTimeList"
@report-click="handleToReportDetail"
/>
<ThinkTankPolicyAdviceOverview
v-else
:key="`policy-${resourceTabResetKey}`"
:research-type-list="areaList"
:research-time-list="pubTimeList"
:list="policyFooterList"
:total="policyTotal"
:current-page="policyCurrentPage"
:page-size="7"
@filter-change="handlePolicyFilterChange"
@page-change="handlePolicyCurrentChange"
/>
<HomeMainFooterMain v-if="activeCate === '智库报告'" :area-list="areaList"
v-model:selectedAreaList="selectedAreaList" :pub-time-list="pubTimeList"
v-model:selectedPubTimeList="selectedPubTimeList" @filter-change="handleThinkTankReportFilterChange"
:cur-footer-list="curFooterList" :total="total" :current-page="currentPage"
@report-click="handleToReportDetail" @page-change="handleCurrentChange" />
<HomeMainFooterSurvey v-else-if="activeCate === '调查项目'" :area-list="areaList"
v-model:selectedAreaList="surveySelectedAreaList" :pub-time-list="pubTimeList"
v-model:selectedPubTimeList="surveySelectedPubTimeList" @filter-change="handleSurveyFilterChange"
:cur-footer-list="surveyFooterList" :total="surveyTotal" :current-page="surveyCurrentPage"
@report-click="handleToReportDetail" @page-change="handleSurveyCurrentChange" />
<ThinkTankCongressHearingOverview v-else-if="activeCate === '国会听证会'" :key="`congress-${resourceTabResetKey}`"
:research-type-list="areaList" :research-time-list="pubTimeList" @report-click="handleToReportDetail" />
<ThinkTankPolicyAdviceOverview v-else :key="`policy-${resourceTabResetKey}`" :research-type-list="areaList"
:research-time-list="pubTimeList" :list="policyFooterList" :total="policyTotal"
:current-page="policyCurrentPage" :page-size="7" @filter-change="handlePolicyFilterChange"
@page-change="handlePolicyCurrentChange" />
</div>
</div>
</div>
......@@ -513,7 +382,7 @@
<script setup>
import RiskSignal from "@/components/base/riskSignal/index.vue";
import NewsList from "@/components/base/newsList/index.vue";
import MessageBubble from "@/components/base/messageBubble/index.vue";
import MessageBubble from "@/components/base/messageBubble/index.vue"
import { onMounted, ref, computed, reactive, nextTick } from "vue";
import scrollToTop from "@/utils/scrollToTop";
import router from "@/router";
......@@ -551,8 +420,8 @@ import News2 from "./assets/images/news2.png";
import News3 from "./assets/images/news3.png";
import News4 from "./assets/images/news4.png";
import News5 from "./assets/images/news5.png";
import AiButton from "@/components/base/Ai/AiButton/index.vue";
import AiPane from "@/components/base/Ai/AiPane/index.vue";
import AiButton from '@/components/base/Ai/AiButton/index.vue'
import AiPane from '@/components/base/Ai/AiPane/index.vue'
import TipTab from "./TipTab/index.vue";
import {
RESOURCE_FILTER_ALL_AREA,
......@@ -592,15 +461,15 @@ import Box1Img from "./assets/images/box1-img.png";
import Box1Logo from "./assets/images/box1-logo.png";
import { setCanvasCreator } from "echarts/core";
import { ElMessage } from "element-plus";
import { useRouter } from "vue-router";
import { useRouter } from 'vue-router';
const containerRef = ref(null);
const statCountInfo = ref([]);
const pageSize = ref(15);
const totalAllItem = ref(0);
const pageSize = ref(15)
const totalAllItem = ref(0)
const isShowAiContentBox5 = ref(false);
const aiContentBox5 = ref("");
const isBox5InterpretLoading = ref(false);
const handleSwitchAiContentShowBox5 = val => {
const handleSwitchAiContentShowBox5 = (val) => {
isShowAiContentBox5.value = val;
if (val) {
fetchBox5ChartInterpretation();
......@@ -609,7 +478,7 @@ const handleSwitchAiContentShowBox5 = val => {
const isShowAiContentBox6 = ref(false);
const aiContentBox6 = ref("");
const isBox6InterpretLoading = ref(false);
const handleSwitchAiContentShowBox6 = val => {
const handleSwitchAiContentShowBox6 = (val) => {
isShowAiContentBox6.value = val;
if (val) {
fetchBox6ChartInterpretation();
......@@ -618,7 +487,7 @@ const handleSwitchAiContentShowBox6 = val => {
const isShowAiContentBox7 = ref(false);
const aiContentBox7 = ref("");
const isBox7InterpretLoading = ref(false);
const handleSwitchAiContentShowBox7 = val => {
const handleSwitchAiContentShowBox7 = (val) => {
isShowAiContentBox7.value = val;
if (val) {
fetchBox7ChartInterpretation();
......@@ -635,36 +504,40 @@ const handleGetAllThinkTankList = async () => {
console.log("智库列表", res);
if (res.code === 200 && res.data) {
totalAllItem.value = res.data.totalElements;
}
} catch (error) {
console.error("获取智库列表error", error);
}
};
const routerTo = useRouter();
const routerTo = useRouter()
// 跳转到全部智库页面
const goToAllThinkTank = () => {
// 替换为你的实际路由路径
routerTo.push("/thinkTank/allThinkTank");
routerTo.push('/thinkTank/allThinkTank');
};
const timePeriod = ref("WEEK");
const timePeriod = ref("WEEK")
const handleTimeClick = item => {
const time = item?.time;
const time = item?.time
if (time === "近一周") {
timePeriod.value = "WEEK";
timePeriod.value = "WEEK"
} else if (time === "近一月") {
timePeriod.value = "MONTH";
timePeriod.value = "MONTH"
} else if (time === "近一年") {
timePeriod.value = "YEAR";
timePeriod.value = "YEAR"
}
// 切换时间范围后重新拉取(从第一页开始)
currentPage.value = 1;
handleGetAllThinkTankList();
currentPage.value = 1
handleGetAllThinkTankList()
// 同步刷新首页卡片数据(包含 increaseReportNumber)
handleGetThinkTankList();
};
handleGetThinkTankList()
}
const getStatCountInfo = async () => {
// console.log('----getStatCountInfo', res.data)
statCountInfo.value = [
{
......@@ -684,6 +557,8 @@ const getStatCountInfo = async () => {
count: "2"
}
];
};
const searchThinktankText = ref(""); //搜索科技人物及观点
// 智库列表
......@@ -748,7 +623,7 @@ const handleGetThinkTankList = async () => {
// 兼容两种返回结构:
// 1) data.content(分页)
// 2) data 直接是数组(非分页)
const list = Array.isArray(res.data) ? res.data : res.data?.content || [];
const list = Array.isArray(res.data) ? res.data : (res.data?.content || []);
cardList.value = list.map(item => ({
id: item.id,
logo: item.imageUrl,
......@@ -784,16 +659,17 @@ const handleGetNewReport = async () => {
console.log("智库发布", res);
if (res.code === 200 && res.data) {
box1Data.value = res.data.map(item => {
const formatDate = dateStr => {
if (!dateStr) return ""; // 处理空值,避免报错
const [year, month, day] = dateStr.split("-");
const formatDate = (dateStr) => {
if (!dateStr) return ''; // 处理空值,避免报错
const [year, month, day] = dateStr.split('-');
return `${year}${parseInt(month, 10)}${parseInt(day, 10)}日`;
};
return {
...item,
reportDate: formatDate(item.reportDate)
};
});
}
})
}
} catch (error) {
console.error("获取智库列表error", error);
......@@ -1153,10 +1029,16 @@ const handleBox5 = async year => {
};
/** 兼容 getChartAnalysis 返回对象:从 data[0] 提取「解读」文本 */
const getInterpretationTextFromChartResponse = res => {
const getInterpretationTextFromChartResponse = (res) => {
const list = res?.data;
const first = Array.isArray(list) ? list[0] : null;
return first?.["解读"] || first?.["interpretation"] || first?.["analysis"] || first?.["content"] || "";
return (
first?.["解读"] ||
first?.["interpretation"] ||
first?.["analysis"] ||
first?.["content"] ||
""
);
};
/** 参考科技法案数量变化趋势:按 chunk 增量拼接展示 */
......@@ -1191,7 +1073,7 @@ const fetchBox5ChartInterpretation = async () => {
name: "数量变化趋势",
data: v.title.map((label, i) => {
const point = { period: label };
v.data.forEach(s => {
v.data.forEach((s) => {
point[s.name] = s.value[i] ?? 0;
});
return point;
......@@ -1304,7 +1186,9 @@ const box6PieDisplayData = computed(() => {
/** 饼图解读用数据:排除占位项 */
const getBox6InterpretationSeries = () => {
const pie = box6PieDisplayData.value;
return pie.filter(item => item.name !== "暂无数据" && item.name !== "暂无该领域数据");
return pie.filter(
item => item.name !== "暂无数据" && item.name !== "暂无该领域数据"
);
};
/** 请求 box6 领域分布饼图解读(入参:{ text: JSON.stringify({ type, name, data }) },与柱状图示例同结构) */
......@@ -1352,7 +1236,9 @@ const fetchBox6ChartInterpretation = async () => {
}
};
const box6AreaList = ref([]);
const box6AreaList = ref([
]);
const box6selectetedTank = ref("全部智库");
const box6TankList = ref([
{
......@@ -1657,25 +1543,25 @@ const handleGetThinkTankHot = async date => {
// 资源库
const categoryList = ref(["智库报告", "调查项目", "国会听证会", "政策建议"]);
const activeCate = ref("智库报告");
const resourceTabResetKey = ref(0);
const resourceTabResetKey = ref(0)
const resetResourceTabCommon = () => {
// 统一回到“刷新后刚加载出来的状态”
// 分页归 1,排序占位「发布时间」且默认倒序(null),与智库动态一致
currentPage.value = 1;
sort.value = null;
currentPage.value = 1
sort.value = null
surveyCurrentPage.value = 1;
surveySort.value = null;
surveyCurrentPage.value = 1
surveySort.value = null
policyCurrentPage.value = 1;
policySort.value = null;
policyCurrentPage.value = 1
policySort.value = null
congressResourceSort.value = null;
congressResourceSort.value = null
// 强制重置那些在子组件内部维护状态的组件(国会听证会/政策建议筛选)
resourceTabResetKey.value += 1;
};
resourceTabResetKey.value += 1
}
const resetThinkTankReportFilters = () => {
selectedAreaList.value = [RESOURCE_FILTER_ALL_AREA];
......@@ -1697,19 +1583,19 @@ const handleClickCate = cate => {
activeCate.value = cate;
// 切换到不同分类时,触发对应数据加载,且互不影响
if (cate === "智库报告") {
resetResourceTabCommon();
resetThinkTankReportFilters();
resetResourceTabCommon()
resetThinkTankReportFilters()
handleGetetThinkTankReport();
} else if (cate === "调查项目") {
resetResourceTabCommon();
resetSurveyFilters();
resetResourceTabCommon()
resetSurveyFilters()
handleGetThinkTankSurvey();
} else if (cate === "政策建议") {
resetResourceTabCommon();
resetPolicyFilters();
resetResourceTabCommon()
resetPolicyFilters()
handleGetThinkTankPolicyAdvice();
} else if (cate === "国会听证会") {
resetResourceTabCommon();
resetResourceTabCommon()
}
};
......@@ -1945,7 +1831,7 @@ const handleSurveyCurrentChange = page => {
const handleGetThinkTankSurvey = async () => {
const { startDate, endDate } = getResourceLibraryReportDateRangeFromTimeSelection(
stripAllTimeForRequest(surveySelectedPubTimeList.value),
(pubTimeList.value || []).map(x => x.id)
(pubTimeList.value || []).map((x) => x.id)
);
const params = {
pageNum: surveyCurrentPage.value,
......@@ -1953,7 +1839,7 @@ const handleGetThinkTankSurvey = async () => {
sortFun: surveySort.value === true,
domainIds: (() => {
const areas = stripAllAreaForRequest(surveySelectedAreaList.value);
const allAreaIds = (areaList.value || []).map(a => a.id);
const allAreaIds = (areaList.value || []).map((a) => a.id);
if (isSelectionCoveringAllOptions(areas, allAreaIds)) {
return "";
}
......@@ -2000,162 +1886,31 @@ const handlePolicyCurrentChange = page => {
};
const handleGetThinkTankPolicyAdvice = async () => {
const mockPolicyAdviceList = () => [
const mockPolicyAdviceList = () => ([
{
id: 23702,
content: "研究未来AI数据中心电力需求与供应",
imageUrl:
"https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg",
imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg",
name: "指数级增长下AI的电力需求:外推AI数据中心的电力需求并评估其对美国竞争力的潜在影响",
reportId: "Rand_RRA3572-1",
tagList: ["新能源", "人工智能"],
thinkTankName: null,
times: "2025-12-28"
},
{
id: 23703,
content: "构建可信任的AI治理框架:监管与创新的平衡",
imageUrl:
"https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg",
name: "AI治理路线图:从风险评估到合规落地的实践建议",
reportId: "Rand_RRA3572-2",
tagList: ["人工智能", "网络安全"],
thinkTankName: null,
times: "2025-12-21"
},
{
id: 23704,
content: "先进制造供应链韧性评估与关键节点识别",
imageUrl:
"https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg",
name: "供应链韧性:关键材料、关键设备与关键人才的系统性策略",
reportId: "Rand_RRA3572-3",
tagList: ["先进制造", "新材料"],
thinkTankName: null,
times: "2025-12-14"
},
{
id: 23705,
content: "半导体出口管制对产业生态的中长期影响",
imageUrl:
"https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg",
name: "出口管制与产业政策:如何降低对关键环节的外部依赖",
reportId: "Rand_RRA3572-4",
tagList: ["集成电路", "先进制造"],
thinkTankName: null,
times: "2025-12-07"
},
{
id: 23706,
content: "量子信息技术发展态势与应用落地路径",
imageUrl:
"https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg",
name: "量子科技:从基础研究到产业化的阶段性里程碑",
reportId: "Rand_RRA3572-5",
tagList: ["量子科技", "前沿基础"],
thinkTankName: null,
times: "2025-11-30"
},
{
id: 23707,
content: "网络安全威胁图谱:关键基础设施的攻击面",
imageUrl:
"https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg",
name: "关键基础设施安全:供应链、身份与数据的三重防护",
reportId: "Rand_RRA3572-6",
tagList: ["网络安全", "数据安全"],
thinkTankName: null,
times: "2025-11-23"
},
{
id: 23708,
content: "生物技术与医疗创新的监管协同机制",
imageUrl:
"https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg",
name: "生物科技创新:试验、审批与产业化的全流程政策工具箱",
reportId: "Rand_RRA3572-7",
tagList: ["生物科技", "医疗健康"],
thinkTankName: null,
times: "2025-11-16"
},
{
id: 23709,
content: "清洁能源转型下的电网规划与储能配置",
imageUrl:
"https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg",
name: "能源系统转型:电网升级、储能布局与成本测算",
reportId: "Rand_RRA3572-8",
tagList: ["新能源", "储能"],
thinkTankName: null,
times: "2025-11-09"
},
{
id: 23710,
content: "新材料在国防与先进制造中的应用瓶颈",
imageUrl:
"https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg",
name: "关键新材料:验证体系、规模化与供应链安全",
reportId: "Rand_RRA3572-9",
tagList: ["新材料", "先进制造"],
thinkTankName: null,
times: "2025-11-02"
},
{
id: 23711,
content: "通信网络演进:6G 与卫星互联网的融合",
imageUrl:
"https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg",
name: "下一代通信:频谱、标准与产业联盟策略",
reportId: "Rand_RRA3572-10",
tagList: ["通信网络", "卫星互联网"],
thinkTankName: null,
times: "2025-10-26"
},
{
id: 23712,
content: "数据要素市场建设与跨境数据合规路径",
imageUrl:
"https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg",
name: "数据治理与合规:分类分级、出境评估与执法协同",
reportId: "Rand_RRA3572-11",
tagList: ["数据安全", "数字治理"],
thinkTankName: null,
times: "2025-10-19"
},
{
id: 23713,
content: "AI 研发人才供需缺口与教育体系对接",
imageUrl:
"https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg",
name: "AI 人才战略:培养、引进与留用的组合政策",
reportId: "Rand_RRA3572-12",
tagList: ["人工智能", "人才政策"],
thinkTankName: null,
times: "2025-10-12"
},
{
id: 23714,
content: "自动驾驶安全监管与测试评价体系",
imageUrl:
"https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg",
name: "自动驾驶:安全标准、责任划分与道路试点机制",
reportId: "Rand_RRA3572-13",
tagList: ["智能网联", "交通出行"],
thinkTankName: null,
times: "2025-10-05"
},
{
id: 23715,
content: "关键基础设施数字化升级的投融资机制",
imageUrl:
"https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg",
name: "基础设施升级:公共资金撬动与绩效评估体系",
reportId: "Rand_RRA3572-14",
tagList: ["数字化转型", "基础设施"],
thinkTankName: null,
times: "2025-09-28"
}
];
{ id: 23703, content: "构建可信任的AI治理框架:监管与创新的平衡", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "AI治理路线图:从风险评估到合规落地的实践建议", reportId: "Rand_RRA3572-2", tagList: ["人工智能", "网络安全"], thinkTankName: null, times: "2025-12-21" },
{ id: 23704, content: "先进制造供应链韧性评估与关键节点识别", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "供应链韧性:关键材料、关键设备与关键人才的系统性策略", reportId: "Rand_RRA3572-3", tagList: ["先进制造", "新材料"], thinkTankName: null, times: "2025-12-14" },
{ id: 23705, content: "半导体出口管制对产业生态的中长期影响", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "出口管制与产业政策:如何降低对关键环节的外部依赖", reportId: "Rand_RRA3572-4", tagList: ["集成电路", "先进制造"], thinkTankName: null, times: "2025-12-07" },
{ id: 23706, content: "量子信息技术发展态势与应用落地路径", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "量子科技:从基础研究到产业化的阶段性里程碑", reportId: "Rand_RRA3572-5", tagList: ["量子科技", "前沿基础"], thinkTankName: null, times: "2025-11-30" },
{ id: 23707, content: "网络安全威胁图谱:关键基础设施的攻击面", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "关键基础设施安全:供应链、身份与数据的三重防护", reportId: "Rand_RRA3572-6", tagList: ["网络安全", "数据安全"], thinkTankName: null, times: "2025-11-23" },
{ id: 23708, content: "生物技术与医疗创新的监管协同机制", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "生物科技创新:试验、审批与产业化的全流程政策工具箱", reportId: "Rand_RRA3572-7", tagList: ["生物科技", "医疗健康"], thinkTankName: null, times: "2025-11-16" },
{ id: 23709, content: "清洁能源转型下的电网规划与储能配置", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "能源系统转型:电网升级、储能布局与成本测算", reportId: "Rand_RRA3572-8", tagList: ["新能源", "储能"], thinkTankName: null, times: "2025-11-09" },
{ id: 23710, content: "新材料在国防与先进制造中的应用瓶颈", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "关键新材料:验证体系、规模化与供应链安全", reportId: "Rand_RRA3572-9", tagList: ["新材料", "先进制造"], thinkTankName: null, times: "2025-11-02" },
{ id: 23711, content: "通信网络演进:6G 与卫星互联网的融合", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "下一代通信:频谱、标准与产业联盟策略", reportId: "Rand_RRA3572-10", tagList: ["通信网络", "卫星互联网"], thinkTankName: null, times: "2025-10-26" },
{ id: 23712, content: "数据要素市场建设与跨境数据合规路径", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "数据治理与合规:分类分级、出境评估与执法协同", reportId: "Rand_RRA3572-11", tagList: ["数据安全", "数字治理"], thinkTankName: null, times: "2025-10-19" },
{ id: 23713, content: "AI 研发人才供需缺口与教育体系对接", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "AI 人才战略:培养、引进与留用的组合政策", reportId: "Rand_RRA3572-12", tagList: ["人工智能", "人才政策"], thinkTankName: null, times: "2025-10-12" },
{ id: 23714, content: "自动驾驶安全监管与测试评价体系", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "自动驾驶:安全标准、责任划分与道路试点机制", reportId: "Rand_RRA3572-13", tagList: ["智能网联", "交通出行"], thinkTankName: null, times: "2025-10-05" },
{ id: 23715, content: "关键基础设施数字化升级的投融资机制", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "基础设施升级:公共资金撬动与绩效评估体系", reportId: "Rand_RRA3572-14", tagList: ["数字化转型", "基础设施"], thinkTankName: null, times: "2025-09-28" }
]);
const applyMockPolicyAdvice = () => {
const mock = mockPolicyAdviceList();
policyTotal.value = mock.length;
......@@ -2166,14 +1921,16 @@ const handleGetThinkTankPolicyAdvice = async () => {
};
const strippedPolicyYears = stripAllTimeForRequest(policySelectedYearIds.value);
const allPubTimeIds = (pubTimeList.value || []).map(x => x.id);
const allPubTimeIds = (pubTimeList.value || []).map((x) => x.id);
/** 与智库报告一致:仅「全部时间」或选满所有具体年份 → 不按 years 狭义过滤 */
const isPolicyAllTime =
strippedPolicyYears.length === 0 ||
(allPubTimeIds.length > 0 && isSelectionCoveringAllOptions(strippedPolicyYears, allPubTimeIds));
const typeIdsForApi = stripAllAreaForRequest(policySelectedTypeIds.value);
// 领域:未选具体领域(仅「全部领域」)时传全量 id 串
const effectiveDomainIds = typeIdsForApi.length ? typeIdsForApi : (areaList.value || []).map(obj => obj.id);
const effectiveDomainIds = typeIdsForApi.length
? typeIdsForApi
: (areaList.value || []).map(obj => obj.id);
const domainIdsStr = arrayToString(effectiveDomainIds);
const params = {
currentPage: policyCurrentPage.value - 1,
......@@ -2243,7 +2000,7 @@ function arrayToString(arr) {
const handleGetetThinkTankReport = async () => {
const { startDate, endDate } = getResourceLibraryReportDateRangeFromTimeSelection(
stripAllTimeForRequest(selectedPubTimeList.value),
(pubTimeList.value || []).map(x => x.id)
(pubTimeList.value || []).map((x) => x.id)
);
const params = {
pageNum: currentPage.value,
......@@ -2251,7 +2008,7 @@ const handleGetetThinkTankReport = async () => {
sortFun: sort.value === true,
domainIds: (() => {
const areas = stripAllAreaForRequest(selectedAreaList.value);
const allAreaIds = (areaList.value || []).map(a => a.id);
const allAreaIds = (areaList.value || []).map((a) => a.id);
if (isSelectionCoveringAllOptions(areas, allAreaIds)) {
return "";
}
......@@ -2350,7 +2107,7 @@ const handleClickPerson = async item => {
ElMessage.warning("找不到当前人员的类型值!");
return;
}
} catch (error) {}
} catch (error) { }
};
// 点击新闻条目,跳转到新闻分析页
......@@ -2389,7 +2146,7 @@ const handleSearch = () => {
onMounted(async () => {
handleGetThinkTankList();
handleGetAllThinkTankList();
handleGetAllThinkTankList()
await getStatCountInfo();
// 定义一个定时器,每隔2秒轮播一次
setInterval(() => {
......@@ -2723,6 +2480,7 @@ onMounted(async () => {
cursor: pointer;
position: relative; // 让 red-info 按当前 card 自身定位
&:hover {
transform: translateY(-3px);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
......@@ -2789,6 +2547,9 @@ onMounted(async () => {
color: rgb(5, 95, 194);
}
}
}
.card-title {
......@@ -2799,6 +2560,7 @@ onMounted(async () => {
justify-content: space-between;
.title-left {
height: 24px;
color: rgba(59, 65, 75, 1);
font-family: "Source Han Sans CN";
......@@ -2950,6 +2712,7 @@ onMounted(async () => {
}
.home-main-center {
.center-top {
height: 450px;
display: flex;
......@@ -3027,6 +2790,7 @@ onMounted(async () => {
align-items: center;
justify-content: center;
.title {
color: rgb(255, 255, 255);
font-family: "Source Han Sans CN";
......@@ -3037,6 +2801,7 @@ onMounted(async () => {
letter-spacing: 0;
width: 80px;
height: 26px;
}
}
}
......@@ -3119,6 +2884,7 @@ onMounted(async () => {
.name {
display: flex;
height: 24px;
margin-top: 22px;
justify-content: space-between;
......@@ -3128,6 +2894,7 @@ onMounted(async () => {
height: 24px;
width: 211px;
.logo {
width: 16px;
height: 16px;
......@@ -3135,9 +2902,11 @@ onMounted(async () => {
flex: 0 0 16px;
margin-right: 6px;
img {
width: 100%;
height: 100%;
}
}
......@@ -3152,6 +2921,9 @@ onMounted(async () => {
}
}
.time {
height: 24px;
color: rgb(59, 65, 75);
......@@ -3162,6 +2934,7 @@ onMounted(async () => {
letter-spacing: 0px;
text-align: left;
}
}
.content {
......@@ -3180,6 +2953,7 @@ onMounted(async () => {
font-weight: 400;
letter-spacing: 0px;
text-align: left;
}
}
}
......@@ -3698,6 +3472,7 @@ onMounted(async () => {
}
.center-footer {
height: 460px;
display: flex;
justify-content: center;
......@@ -3798,6 +3573,7 @@ onMounted(async () => {
}
.source {
position: absolute;
bottom: 21px;
left: 50%;
......@@ -3817,7 +3593,10 @@ onMounted(async () => {
img {
width: 100%;
height: 100%;
}
}
.text {
......@@ -3847,6 +3626,7 @@ onMounted(async () => {
position: absolute;
right: 0;
bottom: -18px;
}
}
}
......@@ -3900,7 +3680,7 @@ onMounted(async () => {
top: 12px;
right: 25px;
display: flex;
gap: 2px;
gap: 2px
}
}
......@@ -3933,6 +3713,7 @@ onMounted(async () => {
}
.source {
position: absolute;
bottom: 21px;
left: 50%;
......@@ -3953,7 +3734,10 @@ onMounted(async () => {
img {
width: 100%;
height: 100%;
}
}
.text {
......@@ -3983,9 +3767,12 @@ onMounted(async () => {
position: absolute;
right: 0;
bottom: -18px;
}
}
}
}
}
......@@ -4105,6 +3892,7 @@ onMounted(async () => {
}
.source {
position: absolute;
bottom: 21px;
left: 50%;
......@@ -4124,7 +3912,10 @@ onMounted(async () => {
img {
width: 100%;
height: 100%;
}
}
.text {
......@@ -4154,6 +3945,7 @@ onMounted(async () => {
position: absolute;
right: 0;
bottom: -18px;
}
}
}
......@@ -4214,6 +4006,7 @@ onMounted(async () => {
}
.box8-main {
height: 412px;
.box8-main-item {
......@@ -4262,7 +4055,7 @@ onMounted(async () => {
width: 92px;
text-align: right;
font-family: "Source Han Sans CN";
color: rgb(95, 101, 108);
color: rgb(95, 101, 108)
}
.itemBold1 {
......@@ -4314,6 +4107,7 @@ onMounted(async () => {
justify-content: space-between;
.btn-box {
display: flex;
gap: 24px;
......@@ -4587,6 +4381,8 @@ onMounted(async () => {
/* 仅作用于智库概览页资源库下四个组件的选择框样式 */
.resource-library-content {
:deep(.el-checkbox__label) {
font-family: "Source Han Sans CN";
font-size: 16px;
......
# 交互消息类
## 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
# 交互消息类
## 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;
// 是否只看中国实体
private Boolean isCn;
}
```
## 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;
// 50%规则子企业列表
@Transient
private List<Organization> ruleOrgList;
}
```
## OrgInfo
```java
public class OrgInfo {
// 机构id
private String id;
// 机构名称
private String orgName;
// 机构中文名称
private String orgNameZh;
// 相关制裁措施列表
private List<String> sanTypeList;
// 机构职责
private String orgDuty;
// 机构图片
private String imageUrl;
// 人员列表
private List<PersonInfo> personList;
// 领域列表
private List<String> domainList;
// 市值
private Double marketValue;
// 市值变化(-1:降低;0:持平:1:上升)
private Integer marketChange;
// 地址
private String address;
// 类型
private String orgType;
// 行业
private List<String> industryList;
// 科研仪器数
private Integer instrumentNum;
}
```
## PersonInfo
```java
public class PersonInfo {
// id
private String id;
// 人物类别
private Integer type;
// 姓名
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;
}
```
## AnnualDomainQuery
```java
public class AnnualDomainQuery {
// 开始年份
private Integer startYear;
// 结束年份
private Integer endYear;
// 是否考虑50%规则
private Boolean isRule;
}
```
## AnnualDomainCount
```java
public class AnnualDomainCount {
// 年度领域统计
private List<DomainCount> yearDomainCount;
// 所有领域
private List<BaseCount> domians;
}
```
## SanctionTypeBean
```java
public class SanctionTypeBean extends BaseBean {
@Id
@Column(name = "ID", nullable = false)
private Integer id;
@Column(name = "NAME")
private String name;
@Column(name = "NAME_ZH")
private String nameZh;
@Column(name = "NAME_ABBR")
private String nameAbbr;
@Column(name = "DESCRIPTION")
private String description;
// 发布国家
@Column(name = "POST_COUNTRY_ID")
private String postCountryId;
// 发布机构
@Column(name = "POST_ORG_ID")
private String postOrgId;
// 是否出口管制 1:是 0:否
@Column(name = "IS_EXPORT_CONTROL")
private String isExportControl;
// 总发布次数
@Transient
private Integer postCount;
}
```
## Organization
```java
public class Organization extends BaseBean {
// 机构id
@Id
@Column(name = "id", nullable = false)
private String id;
// 机构名称
@Column(name = "org_name", nullable = false)
private String orgName;
// 组织机构代码
@Column(name = "uscc")
private String uscc;
// 机构简称
@Column(name = "org_abb")
private String orgAbb;
// 机构英文名称
@Column(name = "org_name_en")
private String orgNameEn;
// 机构英文简称
@Column(name = "org_abb_en")
private String orgAbbEn;
// 机构别名
@Column(name = "org_alias")
private String orgAlias;
// 机构曾用名
@Column(name = "org_former_name")
private String orgFormerName;
// 机构类型id
@Column(name = "org_type_id")
private Long orgTypeId;
// 机构简介
@Column(name = "org_introduction")
private String orgIntroduction;
// 营业范围
@Column(name = "business_scope")
private String businessScope;
// 行业id
@Column(name = "domain_ids")
private String domainIds;
// 行业代码
@Column(name = "economic_industry_code")
private String economicIndustryCode;
// 经济行业名称
@Column(name = "economic_industry_name")
private String economicIndustryName;
// 国家id
@Column(name = "country_id")
private String countryId;
// 省份
@Column(name = "province")
private String province;
// 城市
@Column(name = "city")
private String city;
// 区县
@Column(name = "county")
private String county;
// 详细地址
@Column(name = "address")
private String address;
// 成立时间
@Column(name = "establishment_date")
private LocalDate establishmentDate;
// 变更时间
@Column(name = "issuing_date")
private String issuingDate;
// 营业期限自
@Column(name = "operation_period_from")
private String operationPeriodFrom;
// 营业期限至
@Column(name = "operation_period_until")
private String operationPeriodUntil;
// 营业状态
@Column(name = "business_status")
private String businessStatus;
// 法人id
@Column(name = "legal_representative_id")
private String legalRepresentativeId;
/// 法人
@Column(name = "legal_representative")
private String legalRepresentative;
// 联系电话
@Column(name = "telephone")
private String telephone;
// 邮箱
@Column(name = "email")
private String email;
// 邮政编码
@Column(name = "postcode")
private String postcode;
// 网址
@Column(name = "url")
private String url;
// 员工人数
@Column(name = "number_of_employees")
private String numberOfEmployees;
// 注册资金
@Column(name = "registered_capital")
private String registeredCapital;
// LOGO链接
@Column(name = "logo_url")
private String logoUrl;
@Column(name = "create_by")
private String createBy;
@Column(name = "update_by")
private String updateBy;
@Column(name = "p_org_id")
private String pOrgId;
}
```
## EventInfo
```java
public class EventInfo extends BaseBean {
@Id
@Column(name = "id")
@ApiModelProperty(value = "唯一标识")
private String id;
@Column(name = "title")
@ApiModelProperty(value = "标题")
private String title;
@Column(name = "event_time")
@ApiModelProperty(value = "事件时间")
@JsonFormat(pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date eventTime;
@Column(name = "summary")
@ApiModelProperty(value = "摘要")
private String summary;
@Column(name = "summary_zh")
@ApiModelProperty(value = "摘要译文")
private String summaryZh;
@Column(name = "event_type")
@ApiModelProperty(value = "事件类别")
private String eventType;
@Column(name = "CONTENT")
@ApiModelProperty(value = "主要内容")
private String content;
@Column(name = "title_zh")
@ApiModelProperty(value = "标题译文")
private String titleZh;
@Column(name = "content_zh")
@ApiModelProperty(value = "主要内容译文")
private String contentZh;
@Column(name = "type")
@ApiModelProperty(value = "事件类别")
private String type;
@Column(name = "LOCATION")
@ApiModelProperty(value = "事件地点")
private String location;
@Column(name = "country")
@ApiModelProperty(value = "国家")
private String country;
}
```
## RegionCount
```java
public class RegionCount {
// 名称
private String name;
// 数量
private Integer count;
// 经度
private Double lon;
// 纬度
private Double lat;
}
```
## EventQuery
```java
public class EventQuery extends BasePageQuery {
// 制裁记录ID (暂时无作用,后续根据ID查)
private Integer sanctionId;
// 制裁时间
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
private Date sanctionDate;
}
```
## RuleEntityCount
```JAVA
public class RuleEntityCount {
// 总数
private Integer totalCount;
// 50%规则关联数
private Integer ruleCount;
}
```
## RiskSignalVO
```java
public class RiskSignalVO {
@ApiModelProperty("风险信号id")
private Long signalId;
@ApiModelProperty("风险信号标题")
private String signalTitle;
@ApiModelProperty("风险信号时间")
private LocalDate signalTime;
@ApiModelProperty("风险信号等级")
private String signalLevel;
@ApiModelProperty("风险信号关联法案id")
private String billId;
@ApiModelProperty("风险信号关联政令id")
private Long orderId;
@ApiModelProperty("风险信号关联报告id")
private String reportId;
@ApiModelProperty("风险信号关联制裁id")
private Integer sanId;
}
```
## NewsVO
```java
public class NewsVO {
@ApiModelProperty(value = "新闻id")
private String newsId;
@ApiModelProperty(value = "新闻时间")
private LocalDate newsDate;
@ApiModelProperty(value = "新闻内容")
private String newsContent;
@ApiModelProperty(value = "新闻标题")
private String newsTitle;
@ApiModelProperty(value = "新闻机构")
private String newsOrg;
@ApiModelProperty(value = "新闻图片")
private String newsImage;
}
```
## RemarksVO
```java
public class RemarksVO {
@ApiModelProperty(value = "人物id")
private String personId;
@ApiModelProperty(value = "人物图像")
private String personImage;
@ApiModelProperty(value = "人物名称")
private String personName;
@ApiModelProperty(value = "言论ID")
private Long remarksId;
@ApiModelProperty(value = "人物言论")
private String remarks;
@ApiModelProperty(value = "时间")
private LocalDateTime time;
@ApiModelProperty(value = "言论平台名称")
private String orgName;
}
```
# 字典
## 领域类别(id:name)
1:人工智能、2:生物科技、3:新一代信息技术、4:量子科技、5:新能源、6:集成电路、7:海洋、8:先进制造、9:新材料、10:航空航天、11:深海、12:极地、13:太空、14:核
## 实体类别(id:name)
1:人物、2:机构、7:地址
## 人物类别(待定)
1:政府官员、2:科技领袖、3:顶级科学家、4:国会议员
# 出口管制
## **获取出口管制类清单统计信息**
请求地址:/sanctionList/export/getTotalInfo
请求类型:GET
输入参数:
​ 参数:无输入
​ 请求头:携带token,内容为:
```
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkYXRhLWNlbnRlciIsImF1ZCI6IndlYiIsImlzcyI6ImRhdGEtY2VudGVyIiwiZXhwIjozODI1ODM1NTkxLCJpYXQiOjE2NzgzNTE5NTMsImp0aSI6IjI4YmY1NTZjMTc0MDQ3YjJiNTExNWM3NzVhYjhlNWRmIiwidXNlcm5hbWUiOiJzdXBlcl91c2VyIn0.zHyVzsleX2lEqjDBYRpwluu_wy2nZKGl0dw3IUGnKNw
```
输出结果:ApiResult<List<SanctionTypeBean>>
## 最新出口管制政策(4条)
请求地址:/entitiesDataInfo/getLatestInfo
请求类型:GET
输入参数:
​ 参数:无输入
​ 请求头:携带token,内容为:
```
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkYXRhLWNlbnRlciIsImF1ZCI6IndlYiIsImlzcyI6ImRhdGEtY2VudGVyIiwiZXhwIjozODI1ODM1NTkxLCJpYXQiOjE2NzgzNTE5NTMsImp0aSI6IjI4YmY1NTZjMTc0MDQ3YjJiNTExNWM3NzVhYjhlNWRmIiwidXNlcm5hbWUiOiJzdXBlcl91c2VyIn0.zHyVzsleX2lEqjDBYRpwluu_wy2nZKGl0dw3IUGnKNw
```
输出结果:ApiResult<LatestExportControlInfo>
## 发布(更新)频度
请求地址:/entitiesDataCount/getAnnualCount
请求类型:GET
输入参数:
​ 参数:Integer sanTypeId(制裁类别)
​ 实体清单发布频度:1;CCL发布频度:13
​ 请求头:携带token,内容为:
```
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkYXRhLWNlbnRlciIsImF1ZCI6IndlYiIsImlzcyI6ImRhdGEtY2VudGVyIiwiZXhwIjozODI1ODM1NTkxLCJpYXQiOjE2NzgzNTE5NTMsImp0aSI6IjI4YmY1NTZjMTc0MDQ3YjJiNTExNWM3NzVhYjhlNWRmIiwidXNlcm5hbWUiOiJzdXBlcl91c2VyIn0.zHyVzsleX2lEqjDBYRpwluu_wy2nZKGl0dw3IUGnKNw
```
输出结果:ApiResult<List<AnnualCount>>
## **制裁领域分析**(20251215)
请求地址:/entitiesDataCount/getSanDomainCount
请求类型:GET
输入参数:
​ 参数:Boolean rule(是否勾选50%规则)
​ 请求头:携带token,内容为:
```
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkYXRhLWNlbnRlciIsImF1ZCI6IndlYiIsImlzcyI6ImRhdGEtY2VudGVyIiwiZXhwIjozODI1ODM1NTkxLCJpYXQiOjE2NzgzNTE5NTMsImp0aSI6IjI4YmY1NTZjMTc0MDQ3YjJiNTExNWM3NzVhYjhlNWRmIiwidXNlcm5hbWUiOiJzdXBlcl91c2VyIn0.zHyVzsleX2lEqjDBYRpwluu_wy2nZKGl0dw3IUGnKNw
```
输出结果:ApiResult<List<DomainCount>>
## **历次制裁过程**
请求地址:/entitiesDataCount/getSanctionProcess
请求类型:POST
输入参数:
​ 参数:ExportPageQuery exportPageQuery
​ 请求头:携带token,内容为:
```
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkYXRhLWNlbnRlciIsImF1ZCI6IndlYiIsImlzcyI6ImRhdGEtY2VudGVyIiwiZXhwIjozODI1ODM1NTkxLCJpYXQiOjE2NzgzNTE5NTMsImp0aSI6IjI4YmY1NTZjMTc0MDQ3YjJiNTExNWM3NzVhYjhlNWRmIiwidXNlcm5hbWUiOiJzdXBlcl91c2VyIn0.zHyVzsleX2lEqjDBYRpwluu_wy2nZKGl0dw3IUGnKNw
```
输出结果:ApiResult<Page<SanctionProcess>>
## **制裁实体清单**列表(20251215)
请求地址:/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/getRegionDistribution
请求类型:GET
输入参数:
​ 参数:String sanctionDate (制裁时间)
​ 请求头:携带token
输出结果:ApiResult<List<RegionCount>>
## **制裁理由查询**
请求地址:/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(必需),String searchText(非必需,检索文本)
​ 请求头:携带token
输出结果:ApiResult<List<OrgInfo>>
## **历次制裁涉及领域数查询**
请求地址:/entitiesDataInfo/getPreviousDomian
请求类型:GET
输入参数:
​ 参数:无
​ 请求头:携带token
输出结果:ApiResult<List<BaseCount>>
## **具体领域的制裁实体数统计**
请求地址:/entitiesDataInfo/getDomianAnnual
请求类型:GET
输入参数:
​ 参数:String domainId
​ 请求头:携带token
输出结果:ApiResult<List<AnnualCount>>
## **具体实体类型的制裁实体数统计**
请求地址:/entitiesDataInfo/getEntityTypeAnnual
请求类型:GET
输入参数:
​ 参数:Integer entityTypeId
​ 请求头:携带token
输出结果:ApiResult<List<AnnualCount>>
## **产业链结构查询**
请求地址:/chain/getChainTree
请求类型:GET
输入参数:
​ 参数:Integer chainId,非必需
​ 请求头:携带token
输出结果:ApiResult<List<Chain>>
## **根据领域获取产业链信息**
请求地址:/chain/getChainInfo
请求类型:GET
输入参数:
​ 参数:Integer domainId,领域ID
​ 请求头:携带token
输出结果:ApiResult<List<Chain>>
## **产业链鱼骨图信息查询**
请求地址:/chain/getChainFishbone
请求类型:GET
输入参数:
​ 参数:Integer chainId
​ 请求头:携带token
输出结果:ApiResult<FishboneResp>
## **产业链中国企业实体信息查询**
请求地址:/chain/getChainEntityStat
请求类型:GET
输入参数:
​ 参数:Integer chainId
​ 请求头:携带token
输出结果:ApiResult<AreasStreamResp>
## **实体列表查询**
请求地址:/entitiesDataInfo/getEntityList
请求类型:GET
输入参数:
​ 参数:String sanctionDate(制裁时间),String domainId(领域ID)
​ 请求头:携带token
输出结果:ApiResult<List<OrgInfo>>
## **历年制裁领域统计**
请求地址:/entitiesDataCount/getAnnualSanDomain
请求类型:POST
输入参数:
​ 参数:AnnualDomainQuery annualDomainQuery
​ 请求头:携带token
输出结果:ApiResult<List<AnnualDomainCount>>
## **新增实体数量增长趋势**
请求地址:/entitiesDataInfo/yoyComparison
请求类型:GET
输入参数:
​ 参数:无输入
​ 请求头:携带token
输出结果:ApiResult<List<AnnualCount>>
## **获取机构的详情信息**
请求地址:/organization/getDetail/{id}
请求类型:GET
输入参数:
​ 参数:机构ID
​ 请求头:携带token
输出结果:ApiResult<Organization>
## **获取美国前序事件**
请求地址:/entitiesDataInfo/precedingEvents
请求类型:POST
输入参数:
​ 参数:EventQuery eventQuery
​ 请求头:携带token
输出结果:ApiResult<Page<EventInfo>>
## **新增科研机构列表**
请求地址:/entitiesDataInfo/scientificImpact/entityList
请求类型:GET
输入参数:
​ 参数:String sanctionDate
​ 请求头:携带token
输出结果:ApiResult<List<BaseCount>>
## **各类别仪器对美依赖情况**
请求地址:/instrument/getDependencyUS
请求类型:GET
输入参数:
​ 参数:List<String> orgIds 机构公司ID列表
​ 请求头:携带token
输出结果:ApiResult<List<BaseCount>>
## **仪器对美依赖度升高风险分析**
请求地址:/instrument/getDependencyUSRisk
请求类型:GET
输入参数:
​ 参数:无
​ 请求头:携带token
输出结果:ApiResult<List<BaseCount>>
## **仪器进口国可替代性分析**
请求地址:/instrument/getOriginCount
请求类型:GET
输入参数:
​ 参数:List<String> orgIds 机构公司ID列表
​ 请求头:携带token
输出结果:ApiResult<List<BaseCount>>
## **仪器国产化降低风险分析**
请求地址:/instrument/getLocalizationRisk
请求类型:GET
输入参数:
​ 参数:无
​ 请求头:携带token
输出结果:ApiResult<List<BaseCount>>
## **制裁实体清单50%规则实体数**
请求地址:/sanctionList/getRuleCount
请求类型:POST
输入参数:
​ 参数:ExportPageQuery exportPageQuery
​ 请求头:携带token
输出结果:ApiResult<RuleEntityCount>
## **科研院所类实体历史制裁情况**
请求地址:/entitiesDataInfo/annual/researchInstitute
请求类型:GET
输入参数:
​ 参数:无
​ 请求头:携带token
输出结果:ApiResult<List<AnnualCount>>
## **企业类实体历史制裁情况**
请求地址:/entitiesDataInfo/annual/enterprise
请求类型:GET
输入参数:
​ 参数:无
​ 请求头:携带token
输出结果:ApiResult<List<AnnualCount>>
## **风险信号**
请求地址:/commonFeature/riskSignal/{moduleId}
请求类型:GET
输入参数:
​ 参数:moduleId
​ 请求头:携带token
输出结果:ApiResult<List<RiskSignalVO>>
## **新闻资讯**
请求地址:/commonFeature/news/{moduleId}
请求类型:GET
输入参数:
​ 参数:moduleId
​ 请求头:携带token
输出结果:ApiResult<List<NewsVO>>
## **社交媒体**
请求地址:/commonFeature/remarks/{moduleId}
请求类型:GET
输入参数:
​ 参数:moduleId
​ 请求头:携带token
输出结果:ApiResult<List<RemarksVO>>
\ 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;
// 是否只看中国实体
private Boolean isCn;
}
```
## 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;
}
```
## AnnualDomainQuery
```java
public class AnnualDomainQuery {
// 开始年份
private Integer startYear;
// 结束年份
private Integer endYear;
// 是否考虑50%规则
private Boolean isRule;
}
```
## AnnualDomainCount
```java
public class AnnualDomainCount {
// 年度领域统计
private List<DomainCount> yearDomainCount;
// 所有领域
private List<BaseCount> domians;
}
```
## SanctionTypeBean
```java
public class SanctionTypeBean extends BaseBean {
@Id
@Column(name = "ID", nullable = false)
private Integer id;
@Column(name = "NAME")
private String name;
@Column(name = "NAME_ZH")
private String nameZh;
@Column(name = "NAME_ABBR")
private String nameAbbr;
@Column(name = "DESCRIPTION")
private String description;
// 发布国家
@Column(name = "POST_COUNTRY_ID")
private String postCountryId;
// 发布机构
@Column(name = "POST_ORG_ID")
private String postOrgId;
// 是否出口管制 1:是 0:否
@Column(name = "IS_EXPORT_CONTROL")
private String isExportControl;
// 总发布次数
@Transient
private Integer postCount;
}
```
# 字典
## 领域类别(id:name)
1:人工智能、2:生物科技、3:新一代信息技术、4:量子科技、5:新能源、6:集成电路、7:海洋、8:先进制造、9:新材料、10:航空航天、11:深海、12:极地、13:太空、14:核
## 实体类别(id:name)
1:人物、2:机构
# 出口管制
## **获取出口管制类清单统计信息**
请求地址:/sanctionList/export/getTotalInfo
请求类型:GET
输入参数:
​ 参数:无输入
​ 请求头:携带token,内容为:
```
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkYXRhLWNlbnRlciIsImF1ZCI6IndlYiIsImlzcyI6ImRhdGEtY2VudGVyIiwiZXhwIjozODI1ODM1NTkxLCJpYXQiOjE2NzgzNTE5NTMsImp0aSI6IjI4YmY1NTZjMTc0MDQ3YjJiNTExNWM3NzVhYjhlNWRmIiwidXNlcm5hbWUiOiJzdXBlcl91c2VyIn0.zHyVzsleX2lEqjDBYRpwluu_wy2nZKGl0dw3IUGnKNw
```
输出结果:ApiResult<List<SanctionTypeBean>>
## 最新出口管制政策(4条)
请求地址: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
输入参数:
​ 参数:Integer sanTypeId(制裁类别)
​ 实体清单发布频度:1;CCL发布频度:X(待定,暂无数据)
​ 请求头:携带token,内容为:
```
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkYXRhLWNlbnRlciIsImF1ZCI6IndlYiIsImlzcyI6ImRhdGEtY2VudGVyIiwiZXhwIjozODI1ODM1NTkxLCJpYXQiOjE2NzgzNTE5NTMsImp0aSI6IjI4YmY1NTZjMTc0MDQ3YjJiNTExNWM3NzVhYjhlNWRmIiwidXNlcm5hbWUiOiJzdXBlcl91c2VyIn0.zHyVzsleX2lEqjDBYRpwluu_wy2nZKGl0dw3IUGnKNw
```
输出结果:ApiResult<List<AnnualCount>>
## **制裁领域分析**(20251215)
请求地址:http://8.140.26.4:9085/entitiesDataCount/getSanDomainCount
请求类型:GET
输入参数:
​ 参数:Boolean rule(是否勾选50%规则)
​ 请求头:携带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>>
## **制裁实体清单**列表(20251215)
请求地址: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/getRegionDistribution
请求类型: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(必需),String searchText(非必需,检索文本)
​ 请求头:携带token
输出结果:ApiResult<List<OrgInfo>>
## **历次制裁涉及领域数查询**
请求地址:/entitiesDataInfo/getPreviousDomian
请求类型:GET
输入参数:
​ 参数:无
​ 请求头:携带token
输出结果:ApiResult<List<BaseCount>>
## **具体领域的制裁实体数统计**
请求地址:/entitiesDataInfo/getDomianAnnual
请求类型:GET
输入参数:
​ 参数:String domainId
​ 请求头:携带token
输出结果:ApiResult<List<AnnualCount>>
## **具体实体类型的制裁实体数统计**
请求地址:/entitiesDataInfo/getEntityTypeAnnual
请求类型:GET
输入参数:
​ 参数:Integer entityTypeId
​ 请求头:携带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>
## **实体列表查询**
请求地址:/entitiesDataInfo/getEntityList
请求类型:GET
输入参数:
​ 参数:String sanctionDate(制裁时间),String domainId(领域ID)
​ 请求头:携带token
输出结果:ApiResult<List<OrgInfo>>
## **历年制裁领域统计**
请求地址:/entitiesDataCount/getAnnualSanDomain
请求类型:POST
输入参数:
​ 参数:AnnualDomainQuery annualDomainQuery
​ 请求头:携带token
输出结果:ApiResult<List<AnnualDomainCount>>
## **新增实体数量增长趋势**
请求地址:/entitiesDataInfo/yoyComparison
请求类型:GET
输入参数:
​ 参数:无输入
​ 请求头:携带token
输出结果:ApiResult<List<AnnualCount>>
\ 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;
// 是否只看中国实体
private Boolean isCn;
}
```
## 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;
// 50%规则子企业列表
@Transient
private List<Organization> ruleOrgList;
}
```
## 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 Integer type;
// 姓名
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;
}
```
## AnnualDomainQuery
```java
public class AnnualDomainQuery {
// 开始年份
private Integer startYear;
// 结束年份
private Integer endYear;
// 是否考虑50%规则
private Boolean isRule;
}
```
## AnnualDomainCount
```java
public class AnnualDomainCount {
// 年度领域统计
private List<DomainCount> yearDomainCount;
// 所有领域
private List<BaseCount> domians;
}
```
## SanctionTypeBean
```java
public class SanctionTypeBean extends BaseBean {
@Id
@Column(name = "ID", nullable = false)
private Integer id;
@Column(name = "NAME")
private String name;
@Column(name = "NAME_ZH")
private String nameZh;
@Column(name = "NAME_ABBR")
private String nameAbbr;
@Column(name = "DESCRIPTION")
private String description;
// 发布国家
@Column(name = "POST_COUNTRY_ID")
private String postCountryId;
// 发布机构
@Column(name = "POST_ORG_ID")
private String postOrgId;
// 是否出口管制 1:是 0:否
@Column(name = "IS_EXPORT_CONTROL")
private String isExportControl;
// 总发布次数
@Transient
private Integer postCount;
}
```
## Organization
```java
public class Organization extends BaseBean {
// 机构id
@Id
@Column(name = "id", nullable = false)
private String id;
// 机构名称
@Column(name = "org_name", nullable = false)
private String orgName;
// 组织机构代码
@Column(name = "uscc")
private String uscc;
// 机构简称
@Column(name = "org_abb")
private String orgAbb;
// 机构英文名称
@Column(name = "org_name_en")
private String orgNameEn;
// 机构英文简称
@Column(name = "org_abb_en")
private String orgAbbEn;
// 机构别名
@Column(name = "org_alias")
private String orgAlias;
// 机构曾用名
@Column(name = "org_former_name")
private String orgFormerName;
// 机构类型id
@Column(name = "org_type_id")
private Long orgTypeId;
// 机构简介
@Column(name = "org_introduction")
private String orgIntroduction;
// 营业范围
@Column(name = "business_scope")
private String businessScope;
// 行业id
@Column(name = "domain_ids")
private String domainIds;
// 行业代码
@Column(name = "economic_industry_code")
private String economicIndustryCode;
// 经济行业名称
@Column(name = "economic_industry_name")
private String economicIndustryName;
// 国家id
@Column(name = "country_id")
private String countryId;
// 省份
@Column(name = "province")
private String province;
// 城市
@Column(name = "city")
private String city;
// 区县
@Column(name = "county")
private String county;
// 详细地址
@Column(name = "address")
private String address;
// 成立时间
@Column(name = "establishment_date")
private LocalDate establishmentDate;
// 变更时间
@Column(name = "issuing_date")
private String issuingDate;
// 营业期限自
@Column(name = "operation_period_from")
private String operationPeriodFrom;
// 营业期限至
@Column(name = "operation_period_until")
private String operationPeriodUntil;
// 营业状态
@Column(name = "business_status")
private String businessStatus;
// 法人id
@Column(name = "legal_representative_id")
private String legalRepresentativeId;
/// 法人
@Column(name = "legal_representative")
private String legalRepresentative;
// 联系电话
@Column(name = "telephone")
private String telephone;
// 邮箱
@Column(name = "email")
private String email;
// 邮政编码
@Column(name = "postcode")
private String postcode;
// 网址
@Column(name = "url")
private String url;
// 员工人数
@Column(name = "number_of_employees")
private String numberOfEmployees;
// 注册资金
@Column(name = "registered_capital")
private String registeredCapital;
// LOGO链接
@Column(name = "logo_url")
private String logoUrl;
@Column(name = "create_by")
private String createBy;
@Column(name = "update_by")
private String updateBy;
@Column(name = "p_org_id")
private String pOrgId;
}
```
## EventInfo
```java
public class EventInfo extends BaseBean {
@Id
@Column(name = "id")
@ApiModelProperty(value = "唯一标识")
private String id;
@Column(name = "title")
@ApiModelProperty(value = "标题")
private String title;
@Column(name = "event_time")
@ApiModelProperty(value = "事件时间")
@JsonFormat(pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date eventTime;
@Column(name = "summary")
@ApiModelProperty(value = "摘要")
private String summary;
@Column(name = "summary_zh")
@ApiModelProperty(value = "摘要译文")
private String summaryZh;
@Column(name = "event_type")
@ApiModelProperty(value = "事件类别")
private String eventType;
@Column(name = "CONTENT")
@ApiModelProperty(value = "主要内容")
private String content;
@Column(name = "title_zh")
@ApiModelProperty(value = "标题译文")
private String titleZh;
@Column(name = "content_zh")
@ApiModelProperty(value = "主要内容译文")
private String contentZh;
@Column(name = "type")
@ApiModelProperty(value = "事件类别")
private String type;
@Column(name = "LOCATION")
@ApiModelProperty(value = "事件地点")
private String location;
@Column(name = "country")
@ApiModelProperty(value = "国家")
private String country;
}
```
# 字典
## 领域类别(id:name)
1:人工智能、2:生物科技、3:新一代信息技术、4:量子科技、5:新能源、6:集成电路、7:海洋、8:先进制造、9:新材料、10:航空航天、11:深海、12:极地、13:太空、14:核
## 实体类别(id:name)
1:人物、2:机构、7:地址
## 人物类别(待定)
1:政府官员、2:科技领袖、3:顶级科学家、4:国会议员
# 出口管制
## **获取出口管制类清单统计信息**
请求地址:/sanctionList/export/getTotalInfo
请求类型:GET
输入参数:
​ 参数:无输入
​ 请求头:携带token,内容为:
```
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkYXRhLWNlbnRlciIsImF1ZCI6IndlYiIsImlzcyI6ImRhdGEtY2VudGVyIiwiZXhwIjozODI1ODM1NTkxLCJpYXQiOjE2NzgzNTE5NTMsImp0aSI6IjI4YmY1NTZjMTc0MDQ3YjJiNTExNWM3NzVhYjhlNWRmIiwidXNlcm5hbWUiOiJzdXBlcl91c2VyIn0.zHyVzsleX2lEqjDBYRpwluu_wy2nZKGl0dw3IUGnKNw
```
输出结果:ApiResult<List<SanctionTypeBean>>
## 最新出口管制政策(4条)
请求地址: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
输入参数:
​ 参数:Integer sanTypeId(制裁类别)
​ 实体清单发布频度:1;CCL发布频度:X(待定,暂无数据)
​ 请求头:携带token,内容为:
```
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkYXRhLWNlbnRlciIsImF1ZCI6IndlYiIsImlzcyI6ImRhdGEtY2VudGVyIiwiZXhwIjozODI1ODM1NTkxLCJpYXQiOjE2NzgzNTE5NTMsImp0aSI6IjI4YmY1NTZjMTc0MDQ3YjJiNTExNWM3NzVhYjhlNWRmIiwidXNlcm5hbWUiOiJzdXBlcl91c2VyIn0.zHyVzsleX2lEqjDBYRpwluu_wy2nZKGl0dw3IUGnKNw
```
输出结果:ApiResult<List<AnnualCount>>
## **制裁领域分析**(20251215)
请求地址:http://8.140.26.4:9085/entitiesDataCount/getSanDomainCount
请求类型:GET
输入参数:
​ 参数:Boolean rule(是否勾选50%规则)
​ 请求头:携带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>>
## **制裁实体清单**列表(20251215)
请求地址:/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/getRegionDistribution
请求类型: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(必需),String searchText(非必需,检索文本)
​ 请求头:携带token
输出结果:ApiResult<List<OrgInfo>>
## **历次制裁涉及领域数查询**
请求地址:/entitiesDataInfo/getPreviousDomian
请求类型:GET
输入参数:
​ 参数:无
​ 请求头:携带token
输出结果:ApiResult<List<BaseCount>>
## **具体领域的制裁实体数统计**
请求地址:/entitiesDataInfo/getDomianAnnual
请求类型:GET
输入参数:
​ 参数:String domainId
​ 请求头:携带token
输出结果:ApiResult<List<AnnualCount>>
## **具体实体类型的制裁实体数统计**
请求地址:/entitiesDataInfo/getEntityTypeAnnual
请求类型:GET
输入参数:
​ 参数:Integer entityTypeId
​ 请求头:携带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>
## **实体列表查询**
请求地址:/entitiesDataInfo/getEntityList
请求类型:GET
输入参数:
​ 参数:String sanctionDate(制裁时间),String domainId(领域ID)
​ 请求头:携带token
输出结果:ApiResult<List<OrgInfo>>
## **历年制裁领域统计**
请求地址:/entitiesDataCount/getAnnualSanDomain
请求类型:POST
输入参数:
​ 参数:AnnualDomainQuery annualDomainQuery
​ 请求头:携带token
输出结果:ApiResult<List<AnnualDomainCount>>
## **新增实体数量增长趋势**
请求地址:/entitiesDataInfo/yoyComparison
请求类型:GET
输入参数:
​ 参数:无输入
​ 请求头:携带token
输出结果:ApiResult<List<AnnualCount>>
## **获取机构的详情信息**
请求地址:/organization/getDetail/{id}
请求类型:GET
输入参数:
​ 参数:机构ID
​ 请求头:携带token
输出结果:ApiResult<Organization>
## **获取5条美国前序事件**
请求地址:/entitiesDataInfo/precedingEvents
请求类型:GET
输入参数:
​ 参数:String sanctionDate 制裁时间
​ 请求头:携带token
输出结果:ApiResult<List<EventInfo>>
\ 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;
}
```
## LatestRiskUpdatesVO
```java
public class LatestRiskUpdatesVO {
@Data
public static class ItemVO {
//统计总数
private long total;
//增加数
private long dailyIncrement;
}
@Data
public static class HotspotVO {
//最热事件id
private String HotspotID;
//最热事件类型
private String HotspotType;
//最热事件日期
private String HotspotDate;
//最热事件标题
private String HotspotTitle;
}
}
```
## LatestRisksVO
```java
public class LatestRisksVO {
//风险信号列表
private List<RiskVO> riskVOS;
//风险关联事件列表
private List<HotspotVO> hotspotVOS;
//所有风险数
private Long RiskCount;
@Data
@NoArgsConstructor
public static class HotspotVO {
@ApiModelProperty("id")
private String HotspotID;
@ApiModelProperty("标题")
private String HotspotTitle;
@ApiModelProperty("描述")
private String HotspotDesc;
@ApiModelProperty("时间")
private Date HotspotDate;
@ApiModelProperty("图片")
private String HotspotPicture;
@ApiModelProperty("发布机构名称")
private String HotspotOrgName;
@ApiModelProperty("类型")
private String HotspotType;
@ApiModelProperty("领域列表")
private List<BaseInfo> DomainList;
}
}
@Data
public static class RiskVO {
@ApiModelProperty("风险信号id")
private Long signalId;
@ApiModelProperty("风险信号标题")
private String signalTitle;
@ApiModelProperty("风险信号时间")
private Date signalTime;
@ApiModelProperty("风险信号等级")
private String signalLevel;
}
}
```
## AllDomainCountVO
```
public class AllDomainCountVO {
@ApiModelProperty(value = "统计名称")
private String countName;
@ApiModelProperty(value = "统计数量")
private Long countNum;
}
```
## DomainContainmentRankingVO
```
public class DomainContainmentRankingVO {
@ApiModelProperty(value = "机构名称")
private String orgName;
@ApiModelProperty(value = "机构图片")
private String orgPicture;
@ApiModelProperty(value = "机构打压次数")
private Long orgCount;
}
```
## DomainContainmentTrendVO
```
public class DomainContainmentTrendVO {
@ApiModelProperty(value = "年度/月份")
private String YearOrMonth;
@ApiModelProperty(value = "领域列表")
private List<DomainVO> DomainList;
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class DomainVO {
@ApiModelProperty(value = "统计名称")
private String DomainName;
@ApiModelProperty(value = "统计数量")
private Long DomainNum;
}
}
```
## DomainContainmentTimelineVO
```
public class DomainContainmentTimelineVO {
@ApiModelProperty(value = "打压名称")
private String EventName;
@ApiModelProperty(value = "打压描述")
private String EventDesc;
@ApiModelProperty(value = "打压时间")
private Date EventDate;
@ApiModelProperty(value = "打压类别")
private String EventType;
@ApiModelProperty(value = "打压发起机构")
private String EventOrgName;
@ApiModelProperty(value = "打压事件id")
private String EventId;
@ApiModelProperty(value = "领域列表")
private List<DomainContainmentTimelineVO.DomainVO> EventDomainList;
@Data
@NoArgsConstructor
@AllArgsConstructor
public static class DomainVO {
@ApiModelProperty(value = "领域id")
private String DomainId;
@ApiModelProperty(value = "领域名称")
private String DomainName;
}
}
```
## TechnologyGameAnalysisVO
```
public class TechnologyGameAnalysisVO {
@ApiModelProperty(value = "事件id")
private String eventId;
@ApiModelProperty(value = "事件名称")
private String eventName;
@ApiModelProperty(value = "事件摘要")
private String eventDesc;
@ApiModelProperty(value = "事件发布机构")
private String eventOrg;
@ApiModelProperty(value = "事件时间")
private Date eventDate;
@ApiModelProperty(value = "事件策略")
private String eventStrategy;
@ApiModelProperty(value = "事件类型")
private String eventType;
@ApiModelProperty(value = "事件国旗图片")
private String eventCountryImg;
}
```
# 中美博弈概览
## **最新风险动态统计**
请求地址:/rivalryIndexV2/LatestRiskUpdates
请求类型:GET
输入参数:
​ 参数:无输入
```java
@ApiParam(value = "日期", defaultValue = "本周")
@RequestParam(value = "currentDate") String currentDate
```
​ 请求头:携带token,内容为:
```
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJkYXRhLWNlbnRlciIsImF1ZCI6IndlYiIsImlzcyI6ImRhdGEtY2VudGVyIiwiZXhwIjozODI1ODM1NTkxLCJpYXQiOjE2NzgzNTE5NTMsImp0aSI6IjI4YmY1NTZjMTc0MDQ3YjJiNTExNWM3NzVhYjhlNWRmIiwidXNlcm5hbWUiOiJzdXBlcl91c2VyIn0.zHyVzsleX2lEqjDBYRpwluu_wy2nZKGl0dw3IUGnKNw
```
输出结果:ApiResult<LatestRiskUpdatesVO>
```
"data": {
"bill": { -法案
"total": 167258,
"dailyIncrement": 91
},
"administrativeOrder": {-政令
"total": 215763,
"dailyIncrement": 27
},
"Entities": {-实体清单
"total": 141,
"dailyIncrement": 0
},
"CCL": {-ccl
"total": 3,
"dailyIncrement": 0
},
"SDN": {-sdn
"total": 3,
"dailyIncrement": 0
},
"militaryInvolvement": {-涉军企业
"total": 0,
"dailyIncrement": 0
},
"337Survey": {-337调查
"total": 2881,
"dailyIncrement": 1
},
"232Survey": {-232调查
"total": 35,
"dailyIncrement": 0
},
"301Survey": {-301调查
"total": 5,
"dailyIncrement": 0
},
"policiesRegulations": {-最热政策法规
"hotspotID": "119_HR_7065",
"hotspotDate": "2026-01-14",
"hotspotType": "法案",
"hotspotTitle": "塞尼卡民族执法效率法案 (Seneca Nation Law Enforcement Efficiency Act)"
},
"exportControl": {-最热出口管制
"hotspotID": "138",
"hotspotDate": "2025-10-08",
"hotspotType": "实体清单",
"hotspotTitle": "实体清单的增补与修订"
},
"investmentFinancingRestrictions": {-最热投融资限制
"hotspotID": "147",
"hotspotDate": "2025-06-30",
"hotspotType": "SDN",
"hotspotTitle": "《出口管理条例》修订:商业管制清单新增条目"
},
"marketAccess": {-最热市场准入
"hotspotID": "111",
"hotspotDate": "2026-01-01",
"hotspotType": "337",
"hotspotTitle": "外国制造的半导体器件及其下游产品和组件"
}
}
```
## **最新风险信号**
请求地址:/rivalryIndexV2/LatestRisks
请求类型:GET
输入参数:
​ 参数:无输入
​ 请求头:携带token
输出结果:ApiResult<LatestRisksVO>
## **全领域统计**
请求地址:/rivalryIndexV2/AllDomainCount
请求类型:GET
输入参数:
​ 参数:无输入
​ 请求头:携带token
输出结果:ApiResult<List<AllDomainCountVO>>
## 领域打压遏制排行
请求地址:/rivalryIndexV2/DomainContainmentRanking
请求类型:GET
输入参数:
​ 参数:
```java
@ApiParam(value = "对我打压机构", defaultValue = "对我打压机构")
@RequestParam(value = "ContainmentOrg") String ContainmentOrg,
@ApiParam(value = "领域", defaultValue = "")//传空值为查询全部领域
@RequestParam(value = "Domains",required = false) String Domain
```
请求头:携带token
输出结果:ApiResult<List<DomainContainmentRankingVO>>
## 美对华制裁措施数量趋势
请求地址:/rivalryIndexV2/DomainContainmentTrend
请求类型:GET
输入参数:
参数:required = false为非必传
```java
@ApiParam(value = "日期", defaultValue = "按月统计")
@RequestParam(value = "byYOrM") String byYOrM
```
请求头:携带token
输出结果:ApiResult<List<DomainContainmentTrendVO>>
## 领域打压遏制时间线
请求地址:/rivalryIndexV2/DomainContainmentTimeline
请求类型:GET
输入参数:
参数:required = false为非必传
```JAVA
//传空值为查询全部领域
@ApiParam(value = "领域", defaultValue = "1")
@RequestParam(value = "domain",required = false) String domain
```
请求头:携带token
输出结果: ApiResult<List<DomainContainmentTimelineVO>>
## 中美科技博弈分析
请求地址:/rivalryIndexV2/TechnologyGameAnalysis
请求类型:GET
输入参数:
参数:required = false为非必传
```java
//传空值为查询全部领域
@ApiParam(value = "领域", defaultValue = "1")
@RequestParam(value = "domain",required = false) String domain
```
输出结果:ApiResult<List<TechnologyGameAnalysisVO>>
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论