提交 13be0980 authored 作者: yanpeng's avatar yanpeng

bugfix-4 投融资限制

上级 a9c00d6f
...@@ -137,6 +137,16 @@ export function getReasonAndSan(sanRecordId) { ...@@ -137,6 +137,16 @@ export function getReasonAndSan(sanRecordId) {
return http.get(`/api/sanctionList/invFin/getReasonAndSan?sanRecordId=${sanRecordId}`); return http.get(`/api/sanctionList/invFin/getReasonAndSan?sanRecordId=${sanRecordId}`);
} }
/**
* 分页查询制裁实体清单
* url:/sanctionList/pageQuery
*/
export function getEntitiesList(params) {
return http.post("/api/sanctionList/pageQuery", params);
}
/** /**
* 制裁历程 * 制裁历程
* url:/entitiesDataCount/getSanRecord * url:/entitiesDataCount/getSanRecord
......
...@@ -117,9 +117,10 @@ ...@@ -117,9 +117,10 @@
</div> </div>
</el-tooltip> </el-tooltip>
<div class="dynamic-item-tags"> <div class="dynamic-item-tags">
<span v-for="(tag, tIndex) in item.tags" :key="tIndex" class="tag" :class="getTagClass(tag)"> <!-- <span v-for="(tag, tIndex) in item.tags" :key="tIndex" class="tag" :class="getTagClass(tag)">
{{ tag }} {{ tag }}
</span> </span> -->
<AreaTag v-for="(tag, tIndex) in item.tags" :key="tIndex" :tagName="tag" />
</div> </div>
</div> </div>
</div> </div>
...@@ -278,6 +279,7 @@ import { onMounted, ref, computed, inject, watch, onUnmounted } from "vue"; ...@@ -278,6 +279,7 @@ import { onMounted, ref, computed, inject, watch, onUnmounted } from "vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import Echarts from "@/components/Chart/index.vue"; import Echarts from "@/components/Chart/index.vue";
import SimplePagination from "@/components/SimplePagination.vue"; import SimplePagination from "@/components/SimplePagination.vue";
import AreaTag from "@/components/base/AreaTag/index.vue";
import * as echarts from "echarts"; import * as echarts from "echarts";
import defaultIcon from "../../assets/defaultIcon.png"; import defaultIcon from "../../assets/defaultIcon.png";
import leftBtn from "../../assets/left-btn.png"; import leftBtn from "../../assets/left-btn.png";
......
...@@ -708,10 +708,10 @@ import { useGotoCompanyPages } from "@/router/modules/company"; ...@@ -708,10 +708,10 @@ import { useGotoCompanyPages } from "@/router/modules/company";
import { useGotoNewsDetail } from "@/router/modules/news"; import { useGotoNewsDetail } from "@/router/modules/news";
const gotoCompanyPages = useGotoCompanyPages(); const gotoCompanyPages = useGotoCompanyPages();
const gotoNewsDetail = useGotoNewsDetail(); const gotoNewsDetail = useGotoNewsDetail();
const trendChart = useChartInterpretation(); // const trendChart = useChartInterpretation();
const radarChart = useChartInterpretation(); // const radarChart = useChartInterpretation();
const entityListReleaseFreqChart = useChartInterpretation(); // const entityListReleaseFreqChart = useChartInterpretation();
const commerceControlListReleaseFreqChart = useChartInterpretation(); // const commerceControlListReleaseFreqChart = useChartInterpretation();
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { navigateToViewRiskSignal } from "@/utils/riskSignalOverviewNavigate"; import { navigateToViewRiskSignal } from "@/utils/riskSignalOverviewNavigate";
......
...@@ -49,8 +49,8 @@ ...@@ -49,8 +49,8 @@
:class="{ active: currentSanctionId === item.id }" :class="{ active: currentSanctionId === item.id }"
@click="handleSanctionSelect(item.id)" @click="handleSanctionSelect(item.id)"
> >
<!-- <div class="item-left">{{ item.date }}-{{ item.title }}</div> --> <div class="item-left">{{ item.date }}-{{ item.title }}</div>
<div class="item-left">{{ item.date }}-实体清单更新</div> <!-- <div class="item-left">{{ item.date }}-实体清单更新</div> -->
<div class="item-right">{{ item.count }}{{ item.unit }}</div> <div class="item-right">{{ item.count }}{{ item.unit }}</div>
</div> </div>
</div> </div>
......
...@@ -29,55 +29,20 @@ ...@@ -29,55 +29,20 @@
</AnalysisBox> </AnalysisBox>
</div> </div>
<div class="left-bottom"> <div class="left-bottom">
<!-- <div class="title">
<div class="box"></div>
<div class="text">实体清单更新历史</div>
<div class="filters">
<el-select v-model="selectedDomain" placeholder="Select"
style="width: 150px; height: 32px; margin-right: 16px">
<el-option v-for="item in domainOptions" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
<el-checkbox v-model="onlyChina">只看涉华动态</el-checkbox>
</div>
<div class="btn">
<img src="../../../../assets/下载按钮.png" alt="" />
<img src="../../../../assets/收藏按钮.png" alt="" />
</div>
</div>
<div class="left-bottom-main">
<div class="sanction-list" v-for="item in sanctionList" :key="item.id">
<div class="time">
<div class="year">{{ item.year }}</div>
<div class="date">{{ item.date }}</div>
</div>
<img :src="item.icon || title" alt="" />
<div class="main">
<div class="main-title" @click="handleClick(item)">{{ item.name }}</div>
<el-tooltip effect="dark" :content="item.summary" popper-class="common-prompt-popper" placement="top"
:show-after="500">
<div class="main-desc">{{ item.summary }}</div>
</el-tooltip>
<div class="tag-box">
<div v-for="tag in item.techDomainList" :key="tag" class="tag-item">{{ tag }}</div>
</div>
<div :class="{ 'count-tag': item.cnEntityCount }">
{{ item.cnEntityCount ? `${item.cnEntityCount}家中国实体` : "" }}
</div>
</div>
</div>
</div>
<div class="left-footer">
<div class="total-count"> {{ totalAll }} </div>
<el-pagination v-model:current-page="currentPageAll" :page-size="pageSizeAll" :total="totalAll"
layout="prev, pager, next" background @current-change="handlePageChangeAll" />
</div> -->
<AnalysisBox title="实体清单更新历史" :showAllBtn="false"> <AnalysisBox title="实体清单更新历史" :showAllBtn="false">
<template #header-btn> <template #header-btn>
<div class="filters"> <div class="filters">
<el-select v-model="selectedDomain" placeholder="Select" <el-select
style="width: 150px; height: 32px; margin-right: 16px"> v-model="selectedDomain"
<el-option v-for="item in domainOptions" :key="item.value" :label="item.label" :value="item.value" /> placeholder="Select"
style="width: 150px; height: 32px; margin-right: 16px"
>
<el-option
v-for="item in domainOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select> </el-select>
<el-checkbox v-model="onlyChina">只看涉华动态</el-checkbox> <el-checkbox v-model="onlyChina">只看涉华动态</el-checkbox>
</div> </div>
...@@ -91,8 +56,13 @@ ...@@ -91,8 +56,13 @@
<img :src="item.icon || title" alt="" /> <img :src="item.icon || title" alt="" />
<div class="main"> <div class="main">
<div class="main-title" @click="handleClick(item)">{{ item.name }}</div> <div class="main-title" @click="handleClick(item)">{{ item.name }}</div>
<el-tooltip effect="dark" :content="item.summary" popper-class="common-prompt-popper" placement="top" <el-tooltip
:show-after="500"> effect="dark"
:content="item.summary"
popper-class="common-prompt-popper"
placement="top"
:show-after="500"
>
<div class="main-desc">{{ item.summary }}</div> <div class="main-desc">{{ item.summary }}</div>
</el-tooltip> </el-tooltip>
<div class="tag-box"> <div class="tag-box">
...@@ -107,14 +77,20 @@ ...@@ -107,14 +77,20 @@
</div> </div>
<div class="left-footer"> <div class="left-footer">
<div class="total-count">共 {{ totalAll }} 项</div> <div class="total-count">共 {{ totalAll }} 项</div>
<el-pagination v-model:current-page="currentPageAll" :page-size="pageSizeAll" :total="totalAll" <el-pagination
layout="prev, pager, next" background @current-change="handlePageChangeAll" /> v-model:current-page="currentPageAll"
:page-size="pageSizeAll"
:total="totalAll"
layout="prev, pager, next"
background
@current-change="handlePageChangeAll"
/>
</div> </div>
</AnalysisBox> </AnalysisBox>
</div> </div>
</div> </div>
<div class="right"> <div class="right">
<AnalysisBox title="发布机构" :showAllBtn="false"> <AnalysisBox title="发布机构" :showAllBtn="false" :height="auto">
<div class="right-main"> <div class="right-main">
<div class="right-main-title" @click="handleClickOrg(publishInfo)"> <div class="right-main-title" @click="handleClickOrg(publishInfo)">
<img :src="publishInfo.imageUrl" alt="" /> <img :src="publishInfo.imageUrl" alt="" />
...@@ -130,8 +106,12 @@ ...@@ -130,8 +106,12 @@
<span>关键人物</span> <span>关键人物</span>
</div> </div>
<div class="key-person-list"> <div class="key-person-list">
<div class="person-item" v-for="(item, index) in publishInfo.personList" :key="index" <div
@click="handlePerClick(item)"> class="person-item"
v-for="(item, index) in publishInfo.personList"
:key="index"
@click="handlePerClick(item)"
>
<img :src="item.imageUrl" alt="" /> <img :src="item.imageUrl" alt="" />
<div class="person-info"> <div class="person-info">
<CommonPrompt :content="item.name"> <CommonPrompt :content="item.name">
...@@ -160,11 +140,19 @@ ...@@ -160,11 +140,19 @@
</div> </div>
</div> </div>
</div> </div>
<div class="more-btn" v-if="publishOrgInfo.length < dynamicTotal" @click="handleLoadMoreDynamic"> <!-- <div class="more-btn" v-if="publishOrgInfo.length < dynamicTotal" @click="handleLoadMoreDynamic">
<span>查看更多</span> <span>查看更多</span>
<el-icon> <el-icon>
<ArrowDown /> <ArrowDown />
</el-icon> </el-icon>
</div> -->
<div class="dynamic-footer">
<simple-pagination
v-model:current-page="dynamicPage"
:page-size="dynamicPageSize"
:total="dynamicTotal"
@page-change="handleListPageChange"
/>
</div> </div>
</div> </div>
</div> </div>
...@@ -176,6 +164,7 @@ ...@@ -176,6 +164,7 @@
<script setup> <script setup>
import { ref, onMounted, watch } from "vue"; import { ref, onMounted, watch } from "vue";
import router from "@/router"; import router from "@/router";
import SimplePagination from "@/components/SimplePagination.vue";
import title from "../../../../assets/title.png"; import title from "../../../../assets/title.png";
import defaultIcon from "../../../../../assets/icons/default-avatar.png"; import defaultIcon from "../../../../../assets/icons/default-avatar.png";
import icon01 from "../../assets/icon01.png"; import icon01 from "../../assets/icon01.png";
...@@ -376,7 +365,10 @@ const getPublishOrgInfoFn = async (isLoadMore = false) => { ...@@ -376,7 +365,10 @@ const getPublishOrgInfoFn = async (isLoadMore = false) => {
console.error("获取发布机构动态失败:", error); console.error("获取发布机构动态失败:", error);
} }
}; };
const handleListPageChange = val => {
dynamicPage.value = val;
getPublishOrgInfoFn(false);
};
const handleLoadMoreDynamic = () => { const handleLoadMoreDynamic = () => {
dynamicPage.value++; dynamicPage.value++;
getPublishOrgInfoFn(true); getPublishOrgInfoFn(true);
...@@ -401,17 +393,16 @@ const getEntityInfoFn = async id => { ...@@ -401,17 +393,16 @@ const getEntityInfoFn = async id => {
const sanTypeId = ref(""); const sanTypeId = ref("");
// 跳转到数据资源库 // 跳转到数据资源库
const handleToDataLibrary = (item) => { const handleToDataLibrary = item => {
console.log('item', item); console.log("item", item);
let domainStr = domainOptions.filter(item => item.value === selectedDomain.value)[0].label let domainStr = domainOptions.filter(item => item.value === selectedDomain.value)[0].label;
let params let params;
if (domainStr === '全部领域') { if (domainStr === "全部领域") {
params = { params = {
isCnEntityOnly: true, isCnEntityOnly: true,
selectedDate: JSON.stringify([item.postDate, item.postDate]) selectedDate: JSON.stringify([item.postDate, item.postDate])
} };
} else { } else {
params = { params = {
isCnEntityOnly: true, isCnEntityOnly: true,
...@@ -424,8 +415,7 @@ const handleToDataLibrary = (item) => { ...@@ -424,8 +415,7 @@ const handleToDataLibrary = (item) => {
query: params query: params
}); });
window.open(route.href, "_blank"); window.open(route.href, "_blank");
} };
onMounted(() => { onMounted(() => {
sanTypeId.value = route.query.sanTypeId; sanTypeId.value = route.query.sanTypeId;
...@@ -616,7 +606,7 @@ onMounted(() => { ...@@ -616,7 +606,7 @@ onMounted(() => {
border-radius: 20px; border-radius: 20px;
background-color: rgba(206, 79, 81, 0.1); background-color: rgba(206, 79, 81, 0.1);
cursor: pointer; cursor: pointer;
&:hover{ &:hover {
text-decoration: underline; text-decoration: underline;
} }
} }
...@@ -646,11 +636,13 @@ onMounted(() => { ...@@ -646,11 +636,13 @@ onMounted(() => {
.right { .right {
width: 520px; width: 520px;
height: 1020px; height: auto;
// min-height: 900px;
max-height: 1280px;
.right-main { .right-main {
padding: 7px 24px 20px 23px; padding: 7px 24px 20px 23px;
height: 100%;
.right-main-title { .right-main-title {
cursor: pointer; cursor: pointer;
width: 473px; width: 473px;
...@@ -767,7 +759,12 @@ onMounted(() => { ...@@ -767,7 +759,12 @@ onMounted(() => {
.right-main-dynamic { .right-main-dynamic {
width: 100%; width: 100%;
height: 900px;
display: flex;
flex-direction: column;
// justify-content: space-between;
// height: auto;
position: relative;
.dynamic-title { .dynamic-title {
display: flex; display: flex;
align-items: center; align-items: center;
...@@ -788,8 +785,9 @@ onMounted(() => { ...@@ -788,8 +785,9 @@ onMounted(() => {
} }
.dynamic-list { .dynamic-list {
max-height: 500px; // max-height: 500px;
overflow-y: auto; height: auto;
// overflow-y: auto;
padding-right: 10px; padding-right: 10px;
/* 滚动条样式 */ /* 滚动条样式 */
...@@ -880,6 +878,11 @@ onMounted(() => { ...@@ -880,6 +878,11 @@ onMounted(() => {
margin-right: 4px; margin-right: 4px;
} }
} }
.dynamic-footer {
position: absolute;
bottom: 50px;
left: 180px;
}
} }
} }
} }
......
...@@ -5,9 +5,10 @@ ...@@ -5,9 +5,10 @@
<el-input v-model="searchKeyword" class="search-input" placeholder="搜索实体" :suffix-icon="Search" /> <el-input v-model="searchKeyword" class="search-input" placeholder="搜索实体" :suffix-icon="Search" />
<div class="filters"> <div class="filters">
<el-checkbox v-model="onlyChina" label="只看中国实体" /> <el-checkbox v-model="onlyChina" label="只看中国实体" />
<el-select v-model="order" placeholder="请选择排序方式" style="width: 160px"> <!-- <el-select v-model="order" placeholder="请选择排序方式" style="width: 160px">
<el-option v-for="item in orderOptions" :value="item.value" :key="item.value" :label="item.name" /> <el-option v-for="item in orderOptions" :value="item.value" :key="item.value" :label="item.name" />
</el-select> </el-select> -->
<TimeSortSelectBox @handle-px-change="handleTimePx" />
</div> </div>
</div> </div>
<div class="main"> <div class="main">
...@@ -62,70 +63,6 @@ ...@@ -62,70 +63,6 @@
</div> </div>
</div> </div>
<div class="right"> <div class="right">
<!-- <div class="title">
<div class="left-wrapper">
<div class="box"></div>
<div class="text">实体清单</div>
</div>
<div class="right-wrapper">
<div class="stats">
<div class="dot"></div>
<div class="count-text"><span class="highlight">{{ ruleCount.totalCount }}</span></div>
<div class="rule-text">(50%规则涉及<span class="highlight">{{ ruleCount.ruleCount }}</span>家)</div>
</div>
<div class="btn">
<img src="../../../../assets/下载按钮.png" alt="" />
<img src="../../../../assets/收藏按钮.png" alt="" />
</div>
</div>
</div> -->
<!-- <div class="right-table">
<el-table :data="entityRows" table-layout="fixed" :row-class-name="tableRowClassName"
:header-cell-style="{ background: '#fff' }">
<el-table-column label="实体名称" min-width="200">
<template #default="{ row }">
<div class="entity-name-cell" @click="handleCompClick(row)">
<el-image v-if="row.img" class="avatar" :src="row.img" alt=""></el-image>
<div v-else class="avatar-undefined">
{{
(row.entityNameZh || row.entityName)?.match(
/[\u4e00-\u9fa5a-zA-Z0-9]/
)?.[0]
}}
</div>
<CommonPrompt :content="row.entityNameZh || row.entityName" style="flex: 1; overflow: hidden" />
</div>
</template>
</el-table-column>
<el-table-column label="涉及领域" min-width="150">
<template #default="{ row }">
<div class="domain-cell">
<el-tag v-for="tag in row.techDomains" :key="tag" class="domain-tag" effect="plain"
:disable-transitions="true" :style="getTagStyle(tag)">
{{ tag }}
</el-tag>
</div>
</template>
</el-table-column>
<el-table-column prop="startTime" label="制裁时间" width="140" show-overflow-tooltip align="center" />
<el-table-column label="50%规则子企业" min-width="280" show-overflow-tooltip align="right">
<template #default="{ row }">
<div class="rule-cell" v-if="row.ruleOrgCount > 0">
<div class="rule-text" :title="row.ruleOrgList?.[0]?.orgName || ''">
{{ row.ruleOrgList?.[0]?.orgName || '' }}...等
</div>
<el-link class="rule-link" type="primary" :underline="false" @click="handleRuleClick(row)">{{
row.ruleOrgCount }}家 ></el-link>
</div>
</template>
</el-table-column>
</el-table>
</div>
<div class="tight-footer">
<div class="total-text">共 {{ total }} 项</div>
<el-pagination :current-page="currentPage" v-model:page-size="pageSize" :total="total" layout="prev, pager, next"
prev-text="<" next-text=">" @current-change="handleCurrentChange" />
</div> -->
<AnalysisBox title="实体清单" :showAllBtn="false"> <AnalysisBox title="实体清单" :showAllBtn="false">
<template #header-btn> <template #header-btn>
<div class="stats"> <div class="stats">
...@@ -147,7 +84,11 @@ ...@@ -147,7 +84,11 @@
table-layout="fixed" table-layout="fixed"
:row-class-name="tableRowClassName" :row-class-name="tableRowClassName"
:header-cell-style="{ background: '#fff' }" :header-cell-style="{ background: '#fff' }"
v-loading="tableLoading"
> >
<template #empty>
<el-empty description="暂无数据" />
</template>
<el-table-column label="实体名称" min-width="200"> <el-table-column label="实体名称" min-width="200">
<template #default="{ row }"> <template #default="{ row }">
<div class="entity-name-cell" @click="handleCompClick(row)"> <div class="entity-name-cell" @click="handleCompClick(row)">
...@@ -162,10 +103,10 @@ ...@@ -162,10 +103,10 @@
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="涉及领域" min-width="150"> <el-table-column label="涉及领域" min-width="200">
<template #default="{ row }"> <template #default="{ row }">
<div class="domain-cell"> <div class="domain-cell">
<el-tag <!-- <el-tag
v-for="tag in row.techDomains" v-for="tag in row.techDomains"
:key="tag" :key="tag"
class="domain-tag" class="domain-tag"
...@@ -174,7 +115,12 @@ ...@@ -174,7 +115,12 @@
:style="getTagStyle(tag)" :style="getTagStyle(tag)"
> >
{{ tag }} {{ tag }}
</el-tag> </el-tag> -->
<AreaTag
v-for="(tag, index) in getDisplayTags(row.techDomains)"
:key="index"
:tagName="tag"
/>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
...@@ -241,16 +187,18 @@ import { useRouter } from "vue-router"; ...@@ -241,16 +187,18 @@ import { useRouter } from "vue-router";
import { Search } from "@element-plus/icons-vue"; import { Search } from "@element-plus/icons-vue";
import defaultIcon from "../../../../../assets/icons/default-avatar.png"; import defaultIcon from "../../../../../assets/icons/default-avatar.png";
import RuleSubsidiaryDialog from "./RuleSubsidiaryDialog.vue"; import RuleSubsidiaryDialog from "./RuleSubsidiaryDialog.vue";
import AreaTag from "@/components/base/AreaTag/index.vue";
import { getExportControlList, get50PercentEntityCount } from "@/api/exportControlV2.0.js"; import { getExportControlList, get50PercentEntityCount } from "@/api/exportControlV2.0.js";
import CommonPrompt from "@/views/exportControl/commonPrompt/index.vue"; import CommonPrompt from "@/views/exportControl/commonPrompt/index.vue";
import { useGotoCompanyPages } from "@/router/modules/company"; import { useGotoCompanyPages } from "@/router/modules/company";
import TimeSortSelectBox from "@/components/base/TimeSortSelectBox/index.vue";
const gotoCompanyPages = useGotoCompanyPages(); const gotoCompanyPages = useGotoCompanyPages();
const router = useRouter(); const router = useRouter();
const order = ref("asc"); const order = ref("asc");
const orderOptions = ref([ const orderOptions = ref([
{ name: "正序", value: "asc" }, { name: "倒序", value: "desc" },
{ name: "倒序", value: "desc" } { name: "正序", value: "asc" }
]); ]);
// 跳转公司详情页 // 跳转公司详情页
const handleCompClick = item => { const handleCompClick = item => {
...@@ -274,6 +222,7 @@ const currentPage = ref(1); ...@@ -274,6 +222,7 @@ const currentPage = ref(1);
const pageSize = ref(10); const pageSize = ref(10);
const total = ref(0); const total = ref(0);
const tableLoading = ref(false);
const entityRows = computed(() => mainList.value); const entityRows = computed(() => mainList.value);
const handleCurrentChange = val => { const handleCurrentChange = val => {
...@@ -282,6 +231,43 @@ const handleCurrentChange = val => { ...@@ -282,6 +231,43 @@ const handleCurrentChange = val => {
getExportControlListApi(); getExportControlListApi();
}; };
// 辅助函数:计算需要显示的标签
const getDisplayTags = domains => {
if (!domains || domains.length === 0) return [];
// 1. 获取当前用户选中的领域名称 (排除"全部")
const selectedValues = techFields.value.filter(item => item.checked && item.value !== "all").map(item => item.label); // 注意:techFields中存储的是 label 作为显示名称
// 如果没选中任何特定领域(即选中了“全部”或都没选),直接返回前3个
if (selectedValues.length === 0) {
return domains.slice(0, 3);
}
// 2. 分离 domains 中 "已选中" 和 "未选中" 的部分
const matched = [];
const others = [];
domains.forEach(tag => {
if (selectedValues.includes(tag)) {
matched.push(tag);
} else {
others.push(tag);
}
});
// 3. 组合结果:优先显示匹配的,不足的用其他的补齐,总数限制为3
const result = [...matched];
// 如果匹配的不足3个,从 others 中取剩余的配额
if (result.length < 3) {
const remainingCount = 3 - result.length;
result.push(...others.slice(0, remainingCount));
}
// 如果匹配的超过3个,只取前3个(虽然通常匹配不会这么多,但做个保护)
return result.slice(0, 3);
};
const getTagStyle = tag => { const getTagStyle = tag => {
// 预设颜色池 // 预设颜色池
const colorPool = [ const colorPool = [
...@@ -342,7 +328,7 @@ const sanctionTimes = ref([ ...@@ -342,7 +328,7 @@ const sanctionTimes = ref([
{ label: "2024年", value: "2024", checked: false }, { label: "2024年", value: "2024", checked: false },
{ label: "2023年", value: "2023", checked: false }, { label: "2023年", value: "2023", checked: false },
{ label: "2022年", value: "2022", checked: false }, { label: "2022年", value: "2022", checked: false },
{ label: "2021年", value: "2021", checked: false }, // { label: "2021年", value: "2021", checked: false },
{ label: "自定义", value: "custom", checked: false } { label: "自定义", value: "custom", checked: false }
]); ]);
...@@ -413,6 +399,7 @@ const ruleCount = ref(0); ...@@ -413,6 +399,7 @@ const ruleCount = ref(0);
let abortController = null; let abortController = null;
const getExportControlListApi = async () => { const getExportControlListApi = async () => {
tableLoading.value = true;
// 取消上一轮未完成的请求 // 取消上一轮未完成的请求
if (abortController) { if (abortController) {
try { try {
...@@ -478,8 +465,10 @@ const getExportControlListApi = async () => { ...@@ -478,8 +465,10 @@ const getExportControlListApi = async () => {
try { try {
const res = await getExportControlList(data, { signal: abortController.signal }); const res = await getExportControlList(data, { signal: abortController.signal });
tableLoading.value = false;
// 50%规则涉及实体数 // 50%规则涉及实体数
const countRes = await get50PercentEntityCount(data); const countRes = await get50PercentEntityCount(data);
if (countRes.code === 200) { if (countRes.code === 200) {
ruleCount.value = countRes.data; ruleCount.value = countRes.data;
} }
...@@ -491,9 +480,11 @@ const getExportControlListApi = async () => { ...@@ -491,9 +480,11 @@ const getExportControlListApi = async () => {
if (!error || (error.code !== "ERR_CANCELED" && error.name !== "CanceledError" && error.name !== "AbortError")) { if (!error || (error.code !== "ERR_CANCELED" && error.name !== "CanceledError" && error.name !== "AbortError")) {
console.error(error); console.error(error);
} }
tableLoading.value = false;
} finally { } finally {
isFetching.value = false; isFetching.value = false;
abortController = null; abortController = null;
tableLoading.value = false;
} }
}; };
...@@ -501,8 +492,13 @@ const getExportControlListApi = async () => { ...@@ -501,8 +492,13 @@ const getExportControlListApi = async () => {
// currentPage.value = 1; // currentPage.value = 1;
// getExportControlListApi(); // getExportControlListApi();
// }); // });
const handleTimePx = data => {
watch([onlyChina, order], () => { console.log("选择排序", data);
currentPage.value = 1;
order.value = orderOptions.value[data - 1].value;
getExportControlListApi();
};
watch([onlyChina], () => {
currentPage.value = 1; currentPage.value = 1;
getExportControlListApi(); getExportControlListApi();
}); });
......
...@@ -43,7 +43,7 @@ defineProps({ ...@@ -43,7 +43,7 @@ defineProps({
.title-text { .title-text {
color: rgba(10, 18, 30, 1); color: rgba(10, 18, 30, 1);
font-size: 32px; font-size: 32px;
font-family: "Microsoft YaHei"; font-family: "Source Han Sans CN";
font-weight: 700; font-weight: 700;
margin-left: 20px; margin-left: 20px;
white-space: nowrap; white-space: nowrap;
......
...@@ -50,8 +50,8 @@ ...@@ -50,8 +50,8 @@
:class="{ active: currentSanctionId === item.id }" :class="{ active: currentSanctionId === item.id }"
@click="handleSanctionSelect(item.id)" @click="handleSanctionSelect(item.id)"
> >
<!-- <div class="item-left">{{ item.date }}-{{ item.title }}</div> --> <div class="item-left">{{ item.date }}-{{ item.title }}</div>
<div class="item-left">{{ item.date }}-SDN清单更新</div> <!-- <div class="item-left">{{ item.date }}-SDN清单更新</div> -->
<div class="item-right">{{ item.count }}{{ item.unit }}</div> <div class="item-right">{{ item.count }}{{ item.unit }}</div>
</div> </div>
</div> </div>
...@@ -455,6 +455,7 @@ const stopAutoPlay = () => { ...@@ -455,6 +455,7 @@ const stopAutoPlay = () => {
// ✅ 自动下一个(支持循环) // ✅ 自动下一个(支持循环)
const handleNextClickAuto = () => { const handleNextClickAuto = () => {
const currentIndex = sanctionList.value.findIndex(item => item.id === currentSanctionId.value); const currentIndex = sanctionList.value.findIndex(item => item.id === currentSanctionId.value);
console.log("现在的currentIndex", currentIndex);
let nextItem; let nextItem;
if (currentIndex < sanctionList.value.length - 1) { if (currentIndex < sanctionList.value.length - 1) {
...@@ -473,6 +474,7 @@ const handlePrevClick = () => { ...@@ -473,6 +474,7 @@ const handlePrevClick = () => {
const currentIndex = sanctionList.value.findIndex(item => item.id === currentSanctionId.value); const currentIndex = sanctionList.value.findIndex(item => item.id === currentSanctionId.value);
if (currentIndex > 0) { if (currentIndex > 0) {
const prevItem = sanctionList.value[currentIndex - 1]; const prevItem = sanctionList.value[currentIndex - 1];
console.log("prevItem", prevItem);
handleSanctionSelect(prevItem.id); handleSanctionSelect(prevItem.id);
// startAutoPlay(); // startAutoPlay();
} }
...@@ -491,7 +493,7 @@ const handleSanctionSelect = id => { ...@@ -491,7 +493,7 @@ const handleSanctionSelect = id => {
currentSanctionId.value = id; currentSanctionId.value = id;
getFishboneData(); getFishboneData();
// getCnEntityOnChainData(); // getCnEntityOnChainData();
startAutoPlay(); // startAutoPlay();
}; };
const activeTab = ref(["制裁时序分析", "限制关联分析"]); const activeTab = ref(["制裁时序分析", "限制关联分析"]);
......
...@@ -75,9 +75,17 @@ ...@@ -75,9 +75,17 @@
<AnalysisBox title="实体清单更新历史" :showAllBtn="false"> <AnalysisBox title="实体清单更新历史" :showAllBtn="false">
<template #header-btn> <template #header-btn>
<div class="filters"> <div class="filters">
<el-select v-model="selectedDomain" placeholder="Select" <el-select
style="width: 150px; height: 32px; margin-right: 16px"> v-model="selectedDomain"
<el-option v-for="item in domainOptions" :key="item.value" :label="item.label" :value="item.value" /> placeholder="Select"
style="width: 150px; height: 32px; margin-right: 16px"
>
<el-option
v-for="item in domainOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select> </el-select>
<el-checkbox v-model="onlyChina">只看涉华动态</el-checkbox> <el-checkbox v-model="onlyChina">只看涉华动态</el-checkbox>
</div> </div>
...@@ -91,8 +99,13 @@ ...@@ -91,8 +99,13 @@
<img :src="item.icon || title" alt="" /> <img :src="item.icon || title" alt="" />
<div class="main"> <div class="main">
<div class="main-title" @click="handleClick(item)">{{ item.name }}</div> <div class="main-title" @click="handleClick(item)">{{ item.name }}</div>
<el-tooltip effect="dark" :content="item.summary" popper-class="common-prompt-popper" placement="top" <el-tooltip
:show-after="500"> effect="dark"
:content="item.summary"
popper-class="common-prompt-popper"
placement="top"
:show-after="500"
>
<div class="main-desc">{{ item.summary }}</div> <div class="main-desc">{{ item.summary }}</div>
</el-tooltip> </el-tooltip>
<div class="tag-box"> <div class="tag-box">
...@@ -107,8 +120,14 @@ ...@@ -107,8 +120,14 @@
</div> </div>
<div class="left-footer"> <div class="left-footer">
<div class="total-count"> {{ totalAll }} </div> <div class="total-count"> {{ totalAll }} </div>
<el-pagination v-model:current-page="currentPageAll" :page-size="pageSizeAll" :total="totalAll" <el-pagination
layout="prev, pager, next" background @current-change="handlePageChangeAll" /> v-model:current-page="currentPageAll"
:page-size="pageSizeAll"
:total="totalAll"
layout="prev, pager, next"
background
@current-change="handlePageChangeAll"
/>
</div> </div>
</AnalysisBox> </AnalysisBox>
</div> </div>
...@@ -130,8 +149,12 @@ ...@@ -130,8 +149,12 @@
<span>关键人物</span> <span>关键人物</span>
</div> </div>
<div class="key-person-list"> <div class="key-person-list">
<div class="person-item" v-for="(item, index) in publishInfo.personList" :key="index" <div
@click="handlePerClick(item)"> class="person-item"
v-for="(item, index) in publishInfo.personList"
:key="index"
@click="handlePerClick(item)"
>
<img :src="item.imageUrl" alt="" /> <img :src="item.imageUrl" alt="" />
<div class="person-info"> <div class="person-info">
<CommonPrompt :content="item.name"> <CommonPrompt :content="item.name">
...@@ -160,11 +183,19 @@ ...@@ -160,11 +183,19 @@
</div> </div>
</div> </div>
</div> </div>
<div class="more-btn" v-if="publishOrgInfo.length < dynamicTotal" @click="handleLoadMoreDynamic"> <!-- <div class="more-btn" v-if="publishOrgInfo.length < dynamicTotal" @click="handleLoadMoreDynamic">
<span>查看更多</span> <span>查看更多</span>
<el-icon> <el-icon>
<ArrowDown /> <ArrowDown />
</el-icon> </el-icon>
</div> -->
<div class="dynamic-footer">
<simple-pagination
v-model:current-page="dynamicPage"
:page-size="dynamicPageSize"
:total="dynamicTotal"
@page-change="handleListPageChange"
/>
</div> </div>
</div> </div>
</div> </div>
...@@ -177,7 +208,7 @@ ...@@ -177,7 +208,7 @@
import { ref, onMounted, watch } from "vue"; import { ref, onMounted, watch } from "vue";
import router from "@/router"; import router from "@/router";
import title from "../../../../assets/title.png"; import title from "../../../../assets/title.png";
import defaultIcon from "../../../../../assets/icons/default-avatar.png"; import SimplePagination from "@/components/SimplePagination.vue";
import icon01 from "../../assets/icon01.png"; import icon01 from "../../assets/icon01.png";
import icon02 from "../../assets/icon02.png"; import icon02 from "../../assets/icon02.png";
import { ArrowDown } from "@element-plus/icons-vue"; import { ArrowDown } from "@element-plus/icons-vue";
...@@ -376,6 +407,10 @@ const getPublishOrgInfoFn = async (isLoadMore = false) => { ...@@ -376,6 +407,10 @@ const getPublishOrgInfoFn = async (isLoadMore = false) => {
console.error("获取发布机构动态失败:", error); console.error("获取发布机构动态失败:", error);
} }
}; };
const handleListPageChange = val => {
dynamicPage.value = val;
getPublishOrgInfoFn(false);
};
const handleLoadMoreDynamic = () => { const handleLoadMoreDynamic = () => {
dynamicPage.value++; dynamicPage.value++;
...@@ -401,17 +436,16 @@ const getEntityInfoFn = async id => { ...@@ -401,17 +436,16 @@ const getEntityInfoFn = async id => {
const sanTypeId = ref(""); const sanTypeId = ref("");
// 跳转到数据资源库 // 跳转到数据资源库
const handleToDataLibrary = (item) => { const handleToDataLibrary = item => {
// console.log('item', item); // console.log('item', item);
let domainStr = domainOptions.filter(item => item.value === selectedDomain.value)[0].label;
let domainStr = domainOptions.filter(item => item.value === selectedDomain.value)[0].label let params;
let params if (domainStr === "全部领域") {
if (domainStr === '全部领域') {
params = { params = {
isCnEntityOnly: true, isCnEntityOnly: true,
selectedDate: JSON.stringify([item.postDate, item.postDate]) selectedDate: JSON.stringify([item.postDate, item.postDate])
} };
} else { } else {
params = { params = {
isCnEntityOnly: true, isCnEntityOnly: true,
...@@ -424,8 +458,7 @@ const handleToDataLibrary = (item) => { ...@@ -424,8 +458,7 @@ const handleToDataLibrary = (item) => {
query: params query: params
}); });
window.open(route.href, "_blank"); window.open(route.href, "_blank");
} };
onMounted(() => { onMounted(() => {
sanTypeId.value = route.query.sanTypeId; sanTypeId.value = route.query.sanTypeId;
...@@ -647,11 +680,13 @@ onMounted(() => { ...@@ -647,11 +680,13 @@ onMounted(() => {
.right { .right {
width: 520px; width: 520px;
height: 1020px; height: auto;
// min-height: 900px;
max-height: 1200px;
.right-main { .right-main {
padding: 7px 24px 20px 23px; padding: 7px 24px 20px 23px;
height: 100%;
.right-main-title { .right-main-title {
cursor: pointer; cursor: pointer;
width: 473px; width: 473px;
...@@ -768,6 +803,10 @@ onMounted(() => { ...@@ -768,6 +803,10 @@ onMounted(() => {
.right-main-dynamic { .right-main-dynamic {
width: 100%; width: 100%;
height: 900px;
display: flex;
flex-direction: column;
position: relative;
.dynamic-title { .dynamic-title {
display: flex; display: flex;
...@@ -789,8 +828,8 @@ onMounted(() => { ...@@ -789,8 +828,8 @@ onMounted(() => {
} }
.dynamic-list { .dynamic-list {
max-height: 500px; // max-height: 500px;
overflow-y: auto; // overflow-y: auto;
padding-right: 10px; padding-right: 10px;
/* 滚动条样式 */ /* 滚动条样式 */
...@@ -867,6 +906,12 @@ onMounted(() => { ...@@ -867,6 +906,12 @@ onMounted(() => {
} }
} }
.dynamic-footer {
position: absolute;
bottom: 50px;
left: 180px;
}
.more-btn { .more-btn {
width: 100%; width: 100%;
display: flex; display: flex;
......
...@@ -5,9 +5,10 @@ ...@@ -5,9 +5,10 @@
<el-input v-model="searchKeyword" class="search-input" placeholder="搜索实体" :suffix-icon="Search" /> <el-input v-model="searchKeyword" class="search-input" placeholder="搜索实体" :suffix-icon="Search" />
<div class="filters"> <div class="filters">
<el-checkbox v-model="onlyChina" label="只看中国实体" /> <el-checkbox v-model="onlyChina" label="只看中国实体" />
<el-select v-model="order" placeholder="请选择排序方式" style="width: 160px"> <!-- <el-select v-model="order" placeholder="请选择排序方式" style="width: 160px">
<el-option v-for="item in orderOptions" :value="item.value" :key="item.value" :label="item.name" /> <el-option v-for="item in orderOptions" :value="item.value" :key="item.value" :label="item.name" />
</el-select> </el-select> -->
<TimeSortSelectBox @handle-px-change="handleTimePx" />
</div> </div>
</div> </div>
<div class="main"> <div class="main">
...@@ -62,70 +63,6 @@ ...@@ -62,70 +63,6 @@
</div> </div>
</div> </div>
<div class="right"> <div class="right">
<!-- <div class="title">
<div class="left-wrapper">
<div class="box"></div>
<div class="text">实体清单</div>
</div>
<div class="right-wrapper">
<div class="stats">
<div class="dot"></div>
<div class="count-text"><span class="highlight">{{ ruleCount.totalCount }}</span></div>
<div class="rule-text">(50%规则涉及<span class="highlight">{{ ruleCount.ruleCount }}</span>家)</div>
</div>
<div class="btn">
<img src="../../../../assets/下载按钮.png" alt="" />
<img src="../../../../assets/收藏按钮.png" alt="" />
</div>
</div>
</div> -->
<!-- <div class="right-table">
<el-table :data="entityRows" table-layout="fixed" :row-class-name="tableRowClassName"
:header-cell-style="{ background: '#fff' }">
<el-table-column label="实体名称" min-width="200">
<template #default="{ row }">
<div class="entity-name-cell" @click="handleCompClick(row)">
<el-image v-if="row.img" class="avatar" :src="row.img" alt=""></el-image>
<div v-else class="avatar-undefined">
{{
(row.entityNameZh || row.entityName)?.match(
/[\u4e00-\u9fa5a-zA-Z0-9]/
)?.[0]
}}
</div>
<CommonPrompt :content="row.entityNameZh || row.entityName" style="flex: 1; overflow: hidden" />
</div>
</template>
</el-table-column>
<el-table-column label="涉及领域" min-width="150">
<template #default="{ row }">
<div class="domain-cell">
<el-tag v-for="tag in row.techDomains" :key="tag" class="domain-tag" effect="plain"
:disable-transitions="true" :style="getTagStyle(tag)">
{{ tag }}
</el-tag>
</div>
</template>
</el-table-column>
<el-table-column prop="startTime" label="制裁时间" width="140" show-overflow-tooltip align="center" />
<el-table-column label="50%规则子企业" min-width="280" show-overflow-tooltip align="right">
<template #default="{ row }">
<div class="rule-cell" v-if="row.ruleOrgCount > 0">
<div class="rule-text" :title="row.ruleOrgList?.[0]?.orgName || ''">
{{ row.ruleOrgList?.[0]?.orgName || '' }}...等
</div>
<el-link class="rule-link" type="primary" :underline="false" @click="handleRuleClick(row)">{{
row.ruleOrgCount }}家 ></el-link>
</div>
</template>
</el-table-column>
</el-table>
</div>
<div class="tight-footer">
<div class="total-text">共 {{ total }} 项</div>
<el-pagination :current-page="currentPage" v-model:page-size="pageSize" :total="total" layout="prev, pager, next"
prev-text="<" next-text=">" @current-change="handleCurrentChange" />
</div> -->
<AnalysisBox title="实体清单" :showAllBtn="false"> <AnalysisBox title="实体清单" :showAllBtn="false">
<template #header-btn> <template #header-btn>
<div class="stats"> <div class="stats">
...@@ -134,7 +71,9 @@ ...@@ -134,7 +71,9 @@
<span class="highlight" @click="handlToDataLibrary">{{ ruleCount.totalCount }}</span> <span class="highlight" @click="handlToDataLibrary">{{ ruleCount.totalCount }}</span>
</div> </div>
<div class="rule-text"> <div class="rule-text">
(50%规则涉及<span class="highlight" @click="handlToDataLibrary1">{{ ruleCount.ruleCount }}</span (50%规则涉及<span class="highlight" @click="handlToDataLibrary1">{{
ruleCount.ruleCount
}}</span
>家) >家)
</div> </div>
</div> </div>
...@@ -145,7 +84,11 @@ ...@@ -145,7 +84,11 @@
table-layout="fixed" table-layout="fixed"
:row-class-name="tableRowClassName" :row-class-name="tableRowClassName"
:header-cell-style="{ background: '#fff' }" :header-cell-style="{ background: '#fff' }"
v-loading="tableLoading"
> >
<template #empty>
<el-empty />
</template>
<el-table-column label="实体名称" min-width="200"> <el-table-column label="实体名称" min-width="200">
<template #default="{ row }"> <template #default="{ row }">
<div class="entity-name-cell" @click="handleCompClick(row)"> <div class="entity-name-cell" @click="handleCompClick(row)">
...@@ -237,6 +180,7 @@ ...@@ -237,6 +180,7 @@
import { ref, computed, onMounted, watch } from "vue"; import { ref, computed, onMounted, watch } from "vue";
import { useRouter } from "vue-router"; import { useRouter } from "vue-router";
import { Search } from "@element-plus/icons-vue"; import { Search } from "@element-plus/icons-vue";
import TimeSortSelectBox from "@/components/base/TimeSortSelectBox/index.vue";
import defaultIcon from "../../../../../assets/icons/default-avatar.png"; import defaultIcon from "../../../../../assets/icons/default-avatar.png";
import RuleSubsidiaryDialog from "./RuleSubsidiaryDialog.vue"; import RuleSubsidiaryDialog from "./RuleSubsidiaryDialog.vue";
import { getExportControlList, get50PercentEntityCount } from "@/api/exportControlV2.0.js"; import { getExportControlList, get50PercentEntityCount } from "@/api/exportControlV2.0.js";
...@@ -245,10 +189,10 @@ import { useGotoCompanyPages } from "@/router/modules/company"; ...@@ -245,10 +189,10 @@ import { useGotoCompanyPages } from "@/router/modules/company";
const gotoCompanyPages = useGotoCompanyPages(); const gotoCompanyPages = useGotoCompanyPages();
const router = useRouter(); const router = useRouter();
const order = ref("asc"); const order = ref("desc");
const orderOptions = ref([ const orderOptions = ref([
{ name: "正序", value: "asc" }, { name: "倒序", value: "desc" },
{ name: "倒序", value: "desc" } { name: "正序", value: "asc" }
]); ]);
// 跳转公司详情页 // 跳转公司详情页
const handleCompClick = item => { const handleCompClick = item => {
...@@ -409,8 +353,14 @@ const mainList = ref([]); ...@@ -409,8 +353,14 @@ const mainList = ref([]);
const isFetching = ref(false); const isFetching = ref(false);
const ruleCount = ref(0); const ruleCount = ref(0);
const handleTimePx = val => {
console.log(val);
order.value = orderOptions.value[val - 1].value;
};
const tableLoading = ref(false);
let abortController = null; let abortController = null;
const getExportControlListApi = async () => { const getExportControlListApi = async () => {
tableLoading.value = true;
// 取消上一轮未完成的请求 // 取消上一轮未完成的请求
if (abortController) { if (abortController) {
try { try {
...@@ -475,6 +425,7 @@ const getExportControlListApi = async () => { ...@@ -475,6 +425,7 @@ const getExportControlListApi = async () => {
try { try {
const res = await getExportControlList(data, { signal: abortController.signal }); const res = await getExportControlList(data, { signal: abortController.signal });
tableLoading.value = false;
// 50%规则涉及实体数 // 50%规则涉及实体数
const countRes = await get50PercentEntityCount(data); const countRes = await get50PercentEntityCount(data);
if (countRes.code === 200) { if (countRes.code === 200) {
...@@ -488,9 +439,11 @@ const getExportControlListApi = async () => { ...@@ -488,9 +439,11 @@ const getExportControlListApi = async () => {
if (!error || (error.code !== "ERR_CANCELED" && error.name !== "CanceledError" && error.name !== "AbortError")) { if (!error || (error.code !== "ERR_CANCELED" && error.name !== "CanceledError" && error.name !== "AbortError")) {
console.error(error); console.error(error);
} }
tableLoading.value = false;
} finally { } finally {
isFetching.value = false; isFetching.value = false;
abortController = null; abortController = null;
tableLoading.value = false;
} }
}; };
...@@ -530,26 +483,25 @@ watch(customDateRange, () => { ...@@ -530,26 +483,25 @@ watch(customDateRange, () => {
// 跳转到数据资源库 // 跳转到数据资源库
const handlToDataLibrary = () => { const handlToDataLibrary = () => {
const params = { const params = {
isCnEntityOnly: true, isCnEntityOnly: true
}; };
const route = router.resolve({ const route = router.resolve({
path: "/dataLibrary/sDNList", path: "/dataLibrary/sDNList",
query: params query: params
}); });
window.open(route.href, "_blank"); window.open(route.href, "_blank");
} };
const handlToDataLibrary1 = () => { const handlToDataLibrary1 = () => {
const params = { const params = {
isCnEntityOnly: true, isCnEntityOnly: true,
isHalfRule: true, isHalfRule: true
}; };
const route = router.resolve({ const route = router.resolve({
path: "/dataLibrary/sDNList", path: "/dataLibrary/sDNList",
query: params query: params
}); });
window.open(route.href, "_blank"); window.open(route.href, "_blank");
} };
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
...@@ -587,7 +539,7 @@ const handlToDataLibrary1 = () => { ...@@ -587,7 +539,7 @@ const handlToDataLibrary1 = () => {
.filters { .filters {
display: flex; display: flex;
// align-items: center; align-items: center;
.el-checkbox { .el-checkbox {
margin-right: 20px; margin-right: 20px;
......
...@@ -29,7 +29,7 @@ import listPage from "./components/listPage/index.vue"; ...@@ -29,7 +29,7 @@ import listPage from "./components/listPage/index.vue";
const emit = defineEmits(["update-entity-info"]); const emit = defineEmits(["update-entity-info"]);
const activeTab = ref(["实体清单列表", "实体清单简介"]); const activeTab = ref(["SDN清单列表", "SDN清单简介"]);
const activeIndex = ref(0); const activeIndex = ref(0);
const handleClickTab = index => { const handleClickTab = index => {
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
<el-row :gutter="16" style="width: 1600px; margin: 0 auto; height: 528px; margin-top: 64px"> <el-row :gutter="16" style="width: 1600px; margin: 0 auto; height: 528px; margin-top: 64px">
<CustomTitle id="position1" title="最新动态" /> <CustomTitle id="position1" title="最新动态" />
<el-col :span="16" style="padding-left: 0"> <el-col :span="16" style="padding-left: 0">
<custom-container titleType="primary" title="最新出口管制政策" :titleIcon="houseIcon" height="450px"> <custom-container titleType="primary" title="最新投融资限制政策" :titleIcon="houseIcon" height="450px">
<template #header-right> <template #header-right>
<el-button type="primary" @click="handleToEntityList" link> <el-button type="primary" @click="handleToEntityList" link>
{{ "查看详情 >" }} {{ "查看详情 >" }}
...@@ -207,7 +207,7 @@ ...@@ -207,7 +207,7 @@
<el-table-column prop="year" label="年份" width="200" /> <el-table-column prop="year" label="年份" width="200" />
<el-table-column label="发布次数" width="300"> <el-table-column label="发布次数" width="300">
<template #default="scope"> <template #default="scope">
<div style="display: flex; align-items: center"> <div style="display: flex; align-items: center; cursor: pointer">
<span style="margin-right: 10px; width: 40px">{{ scope.row.num }}</span> <span style="margin-right: 10px; width: 40px">{{ scope.row.num }}</span>
<el-progress <el-progress
:percentage="scope.row.percent * 100" :percentage="scope.row.percent * 100"
...@@ -220,7 +220,12 @@ ...@@ -220,7 +220,12 @@
<el-table-column label="重点领域" width="220" align="center"> <el-table-column label="重点领域" width="220" align="center">
<template #default="scope"> <template #default="scope">
<div <div
style="display: flex; justify-content: center; align-items: center; gap: 5px" style="
display: flex;
justify-content: flex-start;
align-items: center;
gap: 5px;
"
> >
<AreaTag v-for="tag in scope.row.tags" :key="tag" :tagName="tag" /> <AreaTag v-for="tag in scope.row.tags" :key="tag" :tagName="tag" />
<!-- <el-tag v-for="tag in scope.row.tags" :key="tag" :type="getTagType(tag)">{{ <!-- <el-tag v-for="tag in scope.row.tags" :key="tag" :type="getTagType(tag)">{{
...@@ -258,7 +263,7 @@ ...@@ -258,7 +263,7 @@
<el-table-column prop="year" label="年份" width="200" /> <el-table-column prop="year" label="年份" width="200" />
<el-table-column label="发布次数" width="300"> <el-table-column label="发布次数" width="300">
<template #default="scope"> <template #default="scope">
<div style="display: flex; align-items: center"> <div style="display: flex; align-items: center; cursor: pointer">
<span style="margin-right: 10px; width: 40px">{{ scope.row.num }}</span> <span style="margin-right: 10px; width: 40px">{{ scope.row.num }}</span>
<el-progress <el-progress
:percentage="scope.row.percent * 100" :percentage="scope.row.percent * 100"
...@@ -271,7 +276,12 @@ ...@@ -271,7 +276,12 @@
<el-table-column label="重点领域" width="220" align="center"> <el-table-column label="重点领域" width="220" align="center">
<template #default="scope"> <template #default="scope">
<div <div
style="display: flex; justify-content: center; align-items: center; gap: 5px" style="
display: flex;
justify-content: flex-start;
align-items: center;
gap: 5px;
"
> >
<el-tag v-for="tag in scope.row.tags" :key="tag" :type="getTagType(tag)">{{ <el-tag v-for="tag in scope.row.tags" :key="tag" :type="getTagType(tag)">{{
tag tag
...@@ -397,7 +407,7 @@ ...@@ -397,7 +407,7 @@
</el-row> </el-row>
<el-row :gutter="16" style="width: 1600px; margin: 0 auto; margin-top: 39px; padding-bottom: 60px"> <el-row :gutter="16" style="width: 1600px; margin: 0 auto; margin-top: 39px; padding-bottom: 60px">
<CustomTitle id="position4" title="资源库" style="margin-top: 0px" /> <CustomTitle id="position4" title="投融资限制数据库" style="margin-top: 0px" />
<div class="resource-tabs"> <div class="resource-tabs">
<div <div
v-for="tab in resourceTabs" v-for="tab in resourceTabs"
...@@ -411,7 +421,7 @@ ...@@ -411,7 +421,7 @@
</div> </div>
<template v-if="activeResourceTab === 'entity'"> <template v-if="activeResourceTab === 'entity'">
<el-col :span="8" style="padding-left: 0"> <el-col :span="8" style="padding-left: 0">
<custom-container title="历次制裁过程" :titleIcon="listIcon" height="845px"> <custom-container title="制裁历程" :titleIcon="listIcon" height="auto">
<template #default> <template #default>
<div class="box4"> <div class="box4">
<div style="height: 90%; overflow-y: auto; padding-top: 10px"> <div style="height: 90%; overflow-y: auto; padding-top: 10px">
...@@ -424,23 +434,24 @@ ...@@ -424,23 +434,24 @@
></div> ></div>
</div> </div>
<div class="box4-item-right"> <div class="box4-item-right">
<div class="box4-item-right-header" @click="handleSanc(item)"> <!-- <div class="box4-item-right-header" @click="handleSanc(item)">
<span class="box4-item-right-header-title" <span class="box4-item-right-header-title"
>{{ item.postDate }}{{ item.title }}</span >{{ item.postDate }}{{ item.title }}</span
> >
<span class="box4-item-right-header-desc">{{ item.desc }}</span> <span class="box4-item-right-header-desc">{{ item.desc }}</span>
</div> -->
<div class="box4-item-right-header" @click="handleSanc(item)">
<div class="box4-item-right-header-top">
<span class="box4-item-right-header-title">{{ item.postDate }}</span>
<span class="box4-item-right-header-desc">{{ item.desc }}</span>
</div>
<div class="box4-item-right-header-bottom">
<span class="box4-item-right-header-title">{{ item.title }}</span>
</div>
</div> </div>
<el-tooltip
effect="dark"
:content="item.content"
popper-class="common-prompt-popper"
placement="top"
:show-after="500"
>
<div class="box4-item-right-content"> <div class="box4-item-right-content">
{{ item.content }} {{ item.content }}
</div> </div>
</el-tooltip>
</div> </div>
</div> </div>
</div> </div>
...@@ -448,24 +459,76 @@ ...@@ -448,24 +459,76 @@
class="box4-footer" class="box4-footer"
:style="{ marginTop: sanctionProcessList.length > 0 ? '0px' : 'auto' }" :style="{ marginTop: sanctionProcessList.length > 0 ? '0px' : 'auto' }"
> >
<el-button type="primary" link @click="handleGetMore" <simple-pagination
>查看更多 v-model:current-page="sanctionPage"
<el-icon> :page-size="listPageSize"
<DArrowRight /> :total="totalNum"
</el-icon> @page-change="handleListPageChange"
</el-button> />
</div> </div>
</div> </div>
</template> </template>
</custom-container> </custom-container>
</el-col> </el-col>
<el-col :span="16" style="padding-right: 0"> <el-col :span="16" style="padding-right: 0">
<custom-container title="制裁实体清单" :titleIcon="entityIcon" height="845px"> <custom-container title="清单列表" :titleIcon="entityIcon" height="880px">
<template #header-right> <template #header-right>
<div class="box5-header-right">{{ total }}家实体</div> <div class="box5-header-right">{{ total }}家实体</div>
</template> </template>
<template #default> <template #default>
<div class="box5"> <div class="box5">
<div class="filter">
<el-input
v-model="searchKeyword"
class="search-input"
placeholder="搜索实体"
:suffix-icon="Search"
@keyup.enter="handleEntitySearch"
/>
<div class="filter-right">
<el-select
v-model="filterDomain"
class="filter-select"
placeholder="涉及领域"
@change="handleFilterDomainChange"
>
<el-option
v-for="item in techOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<el-select
v-model="entityType"
class="filter-select"
placeholder="实体类型"
clearable
@change="handleEntityTypeChange"
>
<el-option
v-for="item in entityTypes"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
<!-- <el-select
v-model="year"
class="filter-select"
placeholder="选择时间"
@change="handleTimeChange"
>
<el-option
v-for="item in timeSelectOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select> -->
<TimeSortSelectBox @handle-px-change="handleTimePx" />
</div>
</div>
<el-table <el-table
:data="entitiesList" :data="entitiesList"
class="sanction-table" class="sanction-table"
...@@ -475,11 +538,9 @@ ...@@ -475,11 +538,9 @@
header-row-class-name="table-header" header-row-class-name="table-header"
row-class-name="table-row" row-class-name="table-row"
> >
<!-- <el-table-column prop="index" label="序号" width="80" align="center"> <template #empty>
<template #default="scope"> <el-empty />
{{ scope.$index + 1 + (currentPage - 1) * pageSize }}
</template> </template>
</el-table-column> -->
<el-table-column prop="name" label="实体名称" min-width="200"> <el-table-column prop="name" label="实体名称" min-width="200">
<template #default="scope"> <template #default="scope">
...@@ -521,25 +582,6 @@ ...@@ -521,25 +582,6 @@
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column prop="strength" label="制裁强度" width="120" align="center">
<template #default="scope">
<div class="sanction-strength">
<div :class="['strength-bar', `strength-${scope.row.strength}`]"></div>
<span>{{ strengthLabels[scope.row.strength] }}</span>
</div>
</template>
</el-table-column> -->
<!-- <el-table-column prop="revenue" label="营收(亿元)" width="140" align="right">
<template #default="scope">
<span
:class="['revenue-cell', scope.row.revenue === '无营收数据' ? 'no-revenue' : '']"
>
{{ scope.row.revenue }}
</span>
</template>
</el-table-column> -->
<el-table-column prop="revenue" label="50%规则子企业" width="280" align="right"> <el-table-column prop="revenue" label="50%规则子企业" width="280" align="right">
<template #default="scope"> <template #default="scope">
<div class="num-item" v-if="scope.row.ruleOrgCount > 0"> <div class="num-item" v-if="scope.row.ruleOrgCount > 0">
...@@ -607,20 +649,43 @@ ...@@ -607,20 +649,43 @@
<div class="text">制裁时间</div> <div class="text">制裁时间</div>
</div> </div>
<div class="left-main"> <div class="left-main">
<el-checkbox-group v-model="checkedTime"> <!-- <el-checkbox-group v-model="checkedTime">
<div class="checkbox-grid"> <div class="checkbox-grid">
<el-checkbox v-for="item in timeOptions" :key="item" :label="item">{{ <el-checkbox v-for="item in timeOptions" :key="item" :label="item">{{
item item
}}</el-checkbox> }}</el-checkbox>
</div> </div>
</el-checkbox-group> </el-checkbox-group> -->
<div class="checkbox-grid">
<el-checkbox
v-for="(item, index) in timeOptions"
:key="index"
v-model="item.checked"
:label="item.label"
@change="handleFilterChange(item, timeOptions, 'time')"
/>
<div
v-if="timeOptions.find(i => i.value === 'custom' && i.checked)"
class="custom-date-picker"
>
<el-date-picker
v-model="customDateRange"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
/>
</div>
</div>
</div> </div>
</div> </div>
<div class="right"> <div class="right">
<div class="right-title"> <div class="right-title">
<img :src="icon01" alt="" /> <img :src="icon01" alt="" />
<div>出口管制制裁措施</div> <div>投融资限制制裁措施</div>
</div> </div>
<div class="right-main-box" v-loading="sancLoading">
<div class="right-main-wrapper" v-if="sanctionList.length > 0">
<div class="right-main"> <div class="right-main">
<div class="sanction-list" v-for="item in sanctionList" :key="item.id"> <div class="sanction-list" v-for="item in sanctionList" :key="item.id">
<div class="time"> <div class="time">
...@@ -651,38 +716,14 @@ ...@@ -651,38 +716,14 @@
/> />
</div> </div>
</div> </div>
<el-empty v-else />
</div>
</div>
</div> </div>
</el-col> </el-col>
</template> </template>
</el-row> </el-row>
</div> </div>
<!-- <el-dialog v-model="dialogVisible" width="800" :before-close="handleClose">
<template #title>
<div class="dialog-title">50%规则子企业</div>
</template>
<div class="dialog-ett-wrpper">
<div
class="box1-bottom-content-item"
v-for="(ett, index) in currentOrgList"
:key="index"
@click="handleEntityClick(ett)"
>
<el-image v-if="ett.img" class="box1-bottom-content-item-img" :src="ett.img" alt=""></el-image>
<div v-else class="box1-bottom-content-item-imgUndefined">
{{ (ett.orgName || ett.enName)?.match(/[\u4e00-\u9fa5a-zA-Z0-9]/)?.[0] }}
</div>
<div class="box1-bottom-content-item-txt">
{{ ett.orgName || ett.orgNameZh }}
</div>
</div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="dialogVisible = false"> 确定 </el-button>
</div>
</template>
</el-dialog> -->
<RuleSubsidiaryDialog <RuleSubsidiaryDialog
v-model="dialogVisible" v-model="dialogVisible"
:company-name="currentRuleCompany" :company-name="currentRuleCompany"
...@@ -722,7 +763,7 @@ const homeMainRef = ref(null); ...@@ -722,7 +763,7 @@ const homeMainRef = ref(null);
const { isShow } = useContainerScroll(homeMainRef); const { isShow } = useContainerScroll(homeMainRef);
import * as echarts from "echarts"; import * as echarts from "echarts";
import setChart from "@/utils/setChart"; import setChart from "@/utils/setChart";
import { ElMessage, ElMessageBox } from "element-plus"; import TimeSortSelectBox from "@/components/base/TimeSortSelectBox/index.vue";
import { DArrowRight, Warning, Search } from "@element-plus/icons-vue"; import { DArrowRight, Warning, Search } from "@element-plus/icons-vue";
import EChart from "@/components/Chart/index.vue"; import EChart from "@/components/Chart/index.vue";
...@@ -757,23 +798,23 @@ import trumpAvatar from "@/assets/images/icon-trump.png"; ...@@ -757,23 +798,23 @@ import trumpAvatar from "@/assets/images/icon-trump.png";
import elongAvatar from "@/assets/images/icon-elong.png"; import elongAvatar from "@/assets/images/icon-elong.png";
import newsIcon from "@/assets/images/icon-news.png"; import newsIcon from "@/assets/images/icon-news.png";
import dialogIcon from "@/assets/images/icon-duihua.png"; import dialogIcon from "@/assets/images/icon-duihua.png";
import houseIcon from "@/assets/images/icon-house.png"; import houseIcon from "./assets/icons/icon-zc.png";
import dangerIcon from "./assets/images/box2-header-icon.png"; import dangerIcon from "./assets/images/box2-header-icon.png";
import box1Image from "./assets/images/box1-image.png"; import box1Image from "./assets/images/box1-image.png";
import box3Icon from "./assets/images/box1-header-icon.png"; import box3Icon from "./assets/icons/icon-pd.png";
import radarIcon from "./assets/images/icon-radar.png"; import radarIcon from "./assets/icons/icon-radar.png";
import qushiIcon from "./assets/images/icon-qushi.png"; import qushiIcon from "./assets/images/icon-qushi.png";
import listIcon from "./assets/images/icon-list.png"; import listIcon from "./assets/images/icon-list.png";
import dotIcon from "./assets/images/info2-icon.png"; import dotIcon from "./assets/images/info2-icon.png";
import entityIcon from "./assets/images/icon-entity.png"; import entityIcon from "./assets/icons/icon-pd.png";
import comTitle from "./assets/images/panel1_1.png"; import comTitle from "./assets/images/panel1_1.png";
import getMultiLineChart from "./utils/multiLineChart"; import getMultiLineChart from "./utils/multiLineChart";
import icon01 from "./assets/images/jianzhu.png"; import icon01 from "./assets/icons/icon-sanction.png";
import { import {
getEntitiesDataInfo, getEntitiesDataInfo,
getIndustryCountByYear, getIndustryCountByYear,
getCountDomainByYear, getCountDomainByYear,
getEntitiesList, // getEntitiesList,
getSanctionProcess, getSanctionProcess,
getSanDomainCount, getSanDomainCount,
// getRiskSignal, // getRiskSignal,
...@@ -790,7 +831,8 @@ import { ...@@ -790,7 +831,8 @@ import {
getSocialMediaInfo, getSocialMediaInfo,
getReleaseCount, getReleaseCount,
// getSanDomainCount, // getSanDomainCount,
getAnnualSanDomain getAnnualSanDomain,
getEntitiesList
// getSanctionProcess // getSanctionProcess
} from "@/api/finance"; } from "@/api/finance";
...@@ -838,9 +880,10 @@ const handleToRiskSignalDetail = item => { ...@@ -838,9 +880,10 @@ const handleToRiskSignalDetail = item => {
const handleToMoreRiskSignal = () => { const handleToMoreRiskSignal = () => {
navigateToViewRiskSignal(router); navigateToViewRiskSignal(router);
}; };
const sancLoading = ref(false);
const sanctionList = ref([]); const sanctionList = ref([]);
const filterDomain = ref(0);
const techOptions = [ const techOptions = [
{ label: "全部领域", value: 0 }, { label: "全部领域", value: 0 },
{ label: "人工智能", value: 1 }, { label: "人工智能", value: 1 },
...@@ -858,34 +901,16 @@ const techOptions = [ ...@@ -858,34 +901,16 @@ const techOptions = [
{ label: "太空", value: 13 }, { label: "太空", value: 13 },
{ label: "核", value: 14 } { label: "核", value: 14 }
]; ];
const timeOptions = [ const customDateRange = ref("");
"全部时间", const timeOptions = ref([
"2025年", { label: "全部时间", value: "all", checked: true },
"2024年", { label: "2026年", value: "2026", checked: false },
"2023年", { label: "2025年", value: "2025", checked: false },
"2022年", { label: "2024年", value: "2024", checked: false },
"2021年", { label: "2023年", value: "2023", checked: false },
"2020年", { label: "2022年", value: "2022", checked: false },
"2019年", { label: "自定义", value: "custom", checked: false }
"2018年", ]);
"2017年",
"2016年",
"2015年",
"2014年",
"2013年",
"2012年",
"2011年",
"2010年",
"2009年",
"2008年",
"2007年",
"2006年",
"2005年",
"2004年",
"2003年",
"2002年",
"2001年"
];
const checkedTech = ref([0]); const checkedTech = ref([0]);
const checkedTime = ref(["全部时间"]); const checkedTime = ref(["全部时间"]);
...@@ -905,7 +930,7 @@ const handleTitleClick = item => { ...@@ -905,7 +930,7 @@ const handleTitleClick = item => {
const handleCompClick = item => { const handleCompClick = item => {
// console.log("item", item); // console.log("item", item);
// if (item.entityType != 2) return; if (!item.entityId) return;
window.sessionStorage.setItem("curTabName", item.name); window.sessionStorage.setItem("curTabName", item.name);
gotoCompanyPages(item.entityId); gotoCompanyPages(item.entityId);
// const route = router.resolve({ // const route = router.resolve({
...@@ -960,6 +985,7 @@ const commerceControlListReleaseFreq = ref([]); ...@@ -960,6 +985,7 @@ const commerceControlListReleaseFreq = ref([]);
// 历次制裁过程 // 历次制裁过程
const sanctionProcessList = ref([]); const sanctionProcessList = ref([]);
const sanctionPage = ref(1); const sanctionPage = ref(1);
const totalNum = ref(0);
// 制裁实体清单 // 制裁实体清单
const entitiesList = ref([]); const entitiesList = ref([]);
// 风险信号 // 风险信号
...@@ -990,7 +1016,8 @@ const fetchTrendData = async () => { ...@@ -990,7 +1016,8 @@ const fetchTrendData = async () => {
}); });
if (res && res[0] && res[0].yearDomainCount) { if (res && res[0] && res[0].yearDomainCount) {
trendOption.value = processYearDomainCountData(res[0].yearDomainCount); trendOption.value = processYearDomainCountData(res[0].yearDomainCount);
trendChart.interpret({ type: "柱状图", name: "制裁清单数量增长趋势", data: res[0].yearDomainCount }); trendChartData.value = res[0].yearDomainCount;
// trendChart.interpret({ type: "柱状图", name: "制裁清单数量增长趋势", data: res[0].yearDomainCount });
} }
} catch (error) { } catch (error) {
console.error("获取趋势图数据失败:", error); console.error("获取趋势图数据失败:", error);
...@@ -1044,8 +1071,9 @@ const processYearDomainCountData = yearDomainCountData => { ...@@ -1044,8 +1071,9 @@ const processYearDomainCountData = yearDomainCountData => {
const handleEntityClick = item => { const handleEntityClick = item => {
console.log("item", item); console.log("item", item);
window.sessionStorage.setItem("curTabName", item.name || item.entityNameZh); if (!item.id) return;
gotoCompanyPages(item.entityId); window.sessionStorage.setItem("curTabName", item.orgName || item.orgNameZh);
gotoCompanyPages(item.id);
// const route = router.resolve({ // const route = router.resolve({
// name: "companyPages", // name: "companyPages",
// params: { // params: {
...@@ -1312,18 +1340,85 @@ const currentPageAll = ref(1); ...@@ -1312,18 +1340,85 @@ const currentPageAll = ref(1);
const pageSizeAll = ref(10); const pageSizeAll = ref(10);
const totalAll = ref(0); const totalAll = ref(0);
// 筛选逻辑处理
const handleFilterChange = (item, list, type) => {
debugger;
// 如果点击的是"全部"
if (item.value === "all") {
if (item.checked) {
// 选中全部,取消其他所有
list.forEach(i => {
if (i.value !== "all") i.checked = false;
});
} else {
// 取消全部(通常不允许全部取消,至少得选一个,这里如果取消全部,就默认为全部选中)
item.checked = true;
}
} else {
// 点击的是具体项
if (item.checked) {
// 选中具体项,取消"全部"
const allItem = list.find(i => i.value === "all");
if (allItem) allItem.checked = false;
// 特殊处理制裁时间的自定义和其他年份互斥
if (type === "time") {
if (item.value === "custom") {
list.forEach(i => {
if (i.value !== "custom" && i.value !== "all") i.checked = false;
});
} else {
const customItem = list.find(i => i.value === "custom");
if (customItem) customItem.checked = false;
}
}
} else {
// 取消具体项,检查是否还有选中的
const anyChecked = list.some(i => i.checked);
if (!anyChecked) {
const allItem = list.find(i => i.value === "all");
if (allItem) allItem.checked = true;
}
}
}
// 重置页码并查询
currentPageAll.value = 1;
fetchSanctionList();
};
watch(customDateRange, () => {
if (timeOptions.value.find(item => item.value === "custom" && item.checked)) {
currentPageAll.value = 1;
fetchSanctionList();
}
});
const fetchSanctionList = async () => { const fetchSanctionList = async () => {
try { try {
const techDomains = checkedTech.value.includes(0) ? null : checkedTech.value.map(String); const techDomains = checkedTech.value.includes(0) ? null : checkedTech.value.map(String);
let years = null; let years = null;
if (!checkedTime.value.includes("全部时间")) { let startDate = undefined;
years = checkedTime.value let endDate = undefined;
.map(t => { const allTime = timeOptions.value.find(item => item.value === "all");
const match = t.match(/(\d{4})/); console.log("allTime", allTime);
return match ? parseInt(match[1]) : null; if (!allTime || !allTime.checked) {
}) years = timeOptions.value
.filter(y => y !== null); .filter(item => item.checked && item.value !== "all" && item.value !== "custom")
if (years.length === 0) years = null; .map(item => Number(item.value));
const customTime = timeOptions.value.find(item => item.value === "custom");
if (customTime && customTime.checked && customDateRange.value && customDateRange.value.length === 2) {
const start = new Date(customDateRange.value[0]);
const end = new Date(customDateRange.value[1]);
startDate = `${start.getFullYear()}-${String(start.getMonth() + 1).padStart(2, "0")}-${String(
start.getDate()
).padStart(2, "0")}`;
endDate = `${end.getFullYear()}-${String(end.getMonth() + 1).padStart(2, "0")}-${String(end.getDate()).padStart(
2,
"0"
)}`;
}
} }
const params = { const params = {
...@@ -1333,7 +1428,9 @@ const fetchSanctionList = async () => { ...@@ -1333,7 +1428,9 @@ const fetchSanctionList = async () => {
years: years, years: years,
isCn: false, isCn: false,
// typeName: "实体清单" // typeName: "实体清单"
sanTypeIds: allSanTypeIds.value sanTypeIds: allSanTypeIds.value,
startDate: startDate,
endDate: endDate
}; };
const res = await getExportControlList(params); const res = await getExportControlList(params);
...@@ -1439,12 +1536,66 @@ watch( ...@@ -1439,12 +1536,66 @@ watch(
}, },
{ deep: true } { deep: true }
); );
const timeSelectOptions = [
{ label: "全部时间", value: "all" },
{ label: "2026年", value: "2026" },
{ label: "2025年", value: "2025" },
{ label: "2024年", value: "2024" },
{ label: "2023年", value: "2023" },
{ label: "2022年", value: "2022" }
];
const searchKeyword = ref("");
const sortOrder = ref("desc");
const entityType = ref("all");
const year = ref("all");
const entityTypes = ref([
{ label: "全部类型", value: "all" },
{ label: "科研院校", value: "2" },
{ label: "高校", value: "3" },
{ label: "企业", value: "4" }
]);
const handleEntitySearch = val => {
console.log("关键词", val);
// searchKeyword.value = val;
fetchEntitiesList(1, 10);
};
const handleTimePx = val => {
console.log("val", val);
sortOrder.value = val == 1 ? "desc" : "asc";
fetchEntitiesList(1, 10);
};
const handleTimeChange = val => {
console.log(val);
fetchEntitiesList(1, 10);
};
const handleEntityTypeChange = val => {
console.log(val);
fetchEntitiesList(1, 10);
};
const handleFilterDomainChange = val => {
console.log("val", val);
fetchEntitiesList(1, 10);
};
// 获取实体清单数据 // 获取实体清单数据
const fetchEntitiesList = async (page = 1, size = 10) => { const fetchEntitiesList = async (page = 1, size = 10) => {
try { try {
console.log("activeResourceTabItem.value.id", activeResourceTabItem.value.id); console.log("activeResourceTabItem.value.id", activeResourceTabItem.value.id);
const res = await getEntitiesList(activeResourceTabItem.value.id.join(","), page, size); const params = {
keyword: searchKeyword.value,
sortOrder: sortOrder.value,
entityTypes: entityType.value == "all" ? [] : [entityType.value],
techDomains: filterDomain.value == 0 ? [] : [filterDomain.value],
sanTypeId: activeResourceTabItem.value.id.join(","),
pageNum: page,
pageSize: size,
sanctionDate: "",
isCn: false
};
const res = await getEntitiesList(params);
if (res) { if (res) {
entitiesList.value = res.content.map(item => ({ entitiesList.value = res.content.map(item => ({
...item, ...item,
...@@ -1461,6 +1612,13 @@ const fetchEntitiesList = async (page = 1, size = 10) => { ...@@ -1461,6 +1612,13 @@ const fetchEntitiesList = async (page = 1, size = 10) => {
} }
}; };
const listPageSize = ref(5);
const handleListPageChange = async page => {
console.log("页面修改 =>", page);
sanctionPage.value = page;
fetchSanctionProcess(page, listPageSize.value);
};
const handleGetMore = async () => { const handleGetMore = async () => {
sanctionPage.value++; sanctionPage.value++;
try { try {
...@@ -1488,7 +1646,7 @@ const handleGetMore = async () => { ...@@ -1488,7 +1646,7 @@ const handleGetMore = async () => {
}; };
// 获取历次制裁过程数据 // 获取历次制裁过程数据
const fetchSanctionProcess = async (page = 1, size = 10) => { const fetchSanctionProcess = async (page = 1, size = listPageSize.value) => {
console.log("制裁数据请求 =>"); console.log("制裁数据请求 =>");
try { try {
const res = await getSanctionProcess( const res = await getSanctionProcess(
...@@ -1506,6 +1664,7 @@ const fetchSanctionProcess = async (page = 1, size = 10) => { ...@@ -1506,6 +1664,7 @@ const fetchSanctionProcess = async (page = 1, size = 10) => {
item.summary || item.summary ||
"2025年3月25日,美国商务部工业与安全局以从事有悖于美国国家安全和外交政策利益的活动为由,宣布将来自中国的54家实体新增至“实体清单”。" "2025年3月25日,美国商务部工业与安全局以从事有悖于美国国家安全和外交政策利益的活动为由,宣布将来自中国的54家实体新增至“实体清单”。"
})); }));
totalNum.value = res.totalElements;
} }
} catch (err) { } catch (err) {
console.error(err); console.error(err);
...@@ -1518,8 +1677,6 @@ const handlePageChange = page => { ...@@ -1518,8 +1677,6 @@ const handlePageChange = page => {
fetchEntitiesList(page, pageSize.value); fetchEntitiesList(page, pageSize.value);
}; };
const searchKeyword = ref("");
// 资源库 Tab 数据 // 资源库 Tab 数据
const resourceTabs = ref([ const resourceTabs = ref([
// { label: "全部制裁", value: "all", disabled: false }, // { label: "全部制裁", value: "all", disabled: false },
...@@ -1963,9 +2120,6 @@ const handleHideAiPane = key => { ...@@ -1963,9 +2120,6 @@ const handleHideAiPane = key => {
onMounted(async () => { onMounted(async () => {
console.log("finance 页面 mounted"); console.log("finance 页面 mounted");
try { try {
// 获取趋势图数据
fetchTrendData();
fetchRiskSignals("0109"); fetchRiskSignals("0109");
// 获取社交媒体信息 // 获取社交媒体信息
fetchSocialMediaInfo(); fetchSocialMediaInfo();
...@@ -1995,11 +2149,10 @@ onMounted(async () => { ...@@ -1995,11 +2149,10 @@ onMounted(async () => {
resourceTabs.value.unshift({ label: "全部制裁", value: "all", id: allSanTypeIds.value, disabled: false }); resourceTabs.value.unshift({ label: "全部制裁", value: "all", id: allSanTypeIds.value, disabled: false });
activeResourceTabItem.value = resourceTabs.value[0]; activeResourceTabItem.value = resourceTabs.value[0];
console.log("返回的数据结构 infoList =》", infoList.value); console.log("返回的数据结构 infoList =》", infoList.value);
console.log("返回的数据结构 resourceTabs =》", resourceTabs.value); console.log("返回的数据结构 entitiesDataInfo =》", entitiesDataInfo);
const entityList = _.map(entitiesDataInfo?.sanEntities ?? [], ({ entityNameZh, entityName }) => {
return { name: entityNameZh, enName: entityName };
});
entitiesDataInfoList.value = entitiesDataInfo || []; entitiesDataInfoList.value = entitiesDataInfo || [];
console.log("返回的数据结构 entitiesDataInfoList =》", entitiesDataInfoList.value);
const list = _.chain(industryCountByYear).filter("year").orderBy("year", "desc").value().slice(0, 5); const list = _.chain(industryCountByYear).filter("year").orderBy("year", "desc").value().slice(0, 5);
const cclList1 = _.chain(cclList).filter("year").orderBy("year", "desc").value().slice(0, 5); const cclList1 = _.chain(cclList).filter("year").orderBy("year", "desc").value().slice(0, 5);
const total = _.sumBy(list, "count"); const total = _.sumBy(list, "count");
...@@ -2022,6 +2175,8 @@ onMounted(async () => { ...@@ -2022,6 +2175,8 @@ onMounted(async () => {
await fetchRadarData(domainChecked.value); await fetchRadarData(domainChecked.value);
// 获取出口管制制裁措施 // 获取出口管制制裁措施
await fetchSanctionList(); await fetchSanctionList();
// 获取趋势图数据
fetchTrendData();
entityListReleaseFreqChartData.value = entityListReleaseFreq.value; entityListReleaseFreqChartData.value = entityListReleaseFreq.value;
// entityListReleaseFreqChart.interpret({ // entityListReleaseFreqChart.interpret({
// type: "柱状图", // type: "柱状图",
...@@ -2464,7 +2619,7 @@ const handleMediaClick = item => { ...@@ -2464,7 +2619,7 @@ const handleMediaClick = item => {
} }
.box4 { .box4 {
height: 786px; // min-height: 980px;
overflow: auto; overflow: auto;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
...@@ -2504,18 +2659,27 @@ const handleMediaClick = item => { ...@@ -2504,18 +2659,27 @@ const handleMediaClick = item => {
.box4-item-right-header { .box4-item-right-header {
display: flex; display: flex;
flex-direction: column;
justify-content: space-between; justify-content: space-between;
align-items: center; // align-items: center;
border-bottom: 1px solid rgba(234, 236, 238, 1); border-bottom: 1px solid rgba(234, 236, 238, 1);
position: relative; position: relative;
top: -7.5px; top: -7.5px;
padding-bottom: 8px; padding-bottom: 8px;
cursor: pointer; cursor: pointer;
&-top {
display: flex;
justify-content: space-between;
margin-bottom: 5px;
}
&-title { &-title {
font-size: 18px; font-size: 18px;
color: $base-color; color: $base-color;
font-weight: 700; font-weight: 700;
&:hover {
text-decoration: underline;
background: var(--color-primary-2);
}
} }
&-desc { &-desc {
...@@ -2540,8 +2704,6 @@ const handleMediaClick = item => { ...@@ -2540,8 +2704,6 @@ const handleMediaClick = item => {
} }
.box4-footer { .box4-footer {
position: absolute;
// margin-top: auto;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
...@@ -2553,11 +2715,51 @@ const handleMediaClick = item => { ...@@ -2553,11 +2715,51 @@ const handleMediaClick = item => {
} }
.box5 { .box5 {
height: 115%; height: 120%;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
.filter {
display: flex;
align-items: center;
justify-content: space-between;
height: 50px;
gap: 20px;
width: 100%;
.search-input {
width: 180px;
height: 32px;
:deep(.el-input__wrapper) {
padding: 0 11px;
border: 1px solid rgba(170, 173, 177, 1);
background-color: #fff;
border-radius: 3px;
border: 1px solid #ddd;
border-radius: 4px;
height: 32px;
}
:deep(.el-input__inner) {
font-size: 14px;
font-weight: 400;
font-family: "Microsoft YaHei";
line-height: 24px;
color: rgb(95, 101, 108);
}
}
.filter-right {
display: flex;
align-items: center;
gap: 15px;
// width: 100%;
// margin-left: auto;
.filter-select {
width: 150px;
}
}
}
} }
:deep(.table-header) { :deep(.table-header) {
...@@ -3561,6 +3763,47 @@ const handleMediaClick = item => { ...@@ -3561,6 +3763,47 @@ const handleMediaClick = item => {
color: #666666; color: #666666;
font-weight: 400; font-weight: 400;
} }
.custom-date-picker {
width: 100%;
margin-top: 8px;
padding-right: 24px;
box-sizing: border-box;
grid-column: 1 / -1;
:deep(.el-date-editor) {
width: 100%;
height: 32px;
box-shadow: none;
border: 1px solid #dcdfe6;
border-radius: 4px;
padding: 0 10px;
&:hover {
border-color: #c0c4cc;
}
&.is-active {
border-color: #409eff;
}
.el-range-input {
font-size: 14px;
font-family: "Microsoft YaHei";
color: rgb(95, 101, 108);
}
.el-range-separator {
color: rgb(95, 101, 108);
line-height: 30px;
}
.el-input__icon {
line-height: 32px;
color: rgb(95, 101, 108);
}
}
}
} }
} }
...@@ -3571,7 +3814,19 @@ const handleMediaClick = item => { ...@@ -3571,7 +3814,19 @@ const handleMediaClick = item => {
border-radius: 4px; border-radius: 4px;
border-radius: 10px; border-radius: 10px;
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1); box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
display: flex;
flex-direction: column;
.right-main-box {
flex: 1;
display: flex;
justify-content: center;
}
.right-main-wrapper {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
}
.right-title { .right-title {
width: 100%; width: 100%;
height: 48px; height: 48px;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论