提交 101ef632 authored 作者: yanpeng's avatar yanpeng

总体修改

上级 0762600f
......@@ -189,7 +189,8 @@ export function getDeepMiningSelect(data) {
export function getDeepMiningIndustry(params) {
return request({
method: "GET",
url: `/api/chain/getChainInfo`,
// url: `/api/chain/getChainInfo`,
url: `/api/chain/getAllChain`,
params
});
}
......@@ -204,7 +205,7 @@ export function getDeepMiningIndustry(params) {
export function getDeepMiningIndustryFishbone(params) {
return request({
method: "GET",
url: `/api/chain/getChainFishbone`,
url: `/api/chain/getChainNodes`,
params
});
}
......
差异被折叠。
......@@ -18,7 +18,12 @@ import RelationChart from '@/components/base/RelationChart/index.vue'
</el-radio-group>
</div>
<div class="chart-box">
<RelationChart @line-click="handleClickLine" @node-click="handleClickNode" :is-vertical-chart="isVerticalChart" :graph-data="graphData" />
<RelationChart
@line-click="handleClickLine"
@node-click="handleClickNode"
:is-vertical-chart="isVerticalChart"
:graph-data="graphData"
/>
</div>
</el-col>
</el-row>
......@@ -149,7 +154,15 @@ const graphData = ref({
{ id: "e2-9", text: "e2-9" }
],
lines: [
{ from: "a", to: "b", text: '从属', fontColor: 'var(--color-orange-100)', color: 'orange', textOffset_x: -20, lineWidth: 5},
{
from: "a",
to: "b",
text: "从属",
fontColor: "var(--color-orange-100)",
color: "orange",
textOffset_x: -20,
lineWidth: 5
},
{ from: "b", to: "b1" },
{ from: "b1", to: "b1-1" },
{ from: "b1", to: "b1-2" },
......@@ -254,18 +267,15 @@ const graphData = ref({
]
});
const handleClickNode = (value) => {
console.log('value', value);
alert('我点击了node-'+ value.text)
}
const handleClickLine = (value) => {
console.log('value', value);
alert('我点击了line-'+ value.text)
}
const handleClickNode = value => {
console.log("value", value);
alert("我点击了node-" + value.text);
};
const handleClickLine = value => {
console.log("value", value);
alert("我点击了line-" + value.text);
};
</script>
<style lang="scss" scoped>
......
......@@ -670,7 +670,9 @@
</el-col>
</template>
<template v-if="activeResourceTab === 'commerce'">
<div class="commerce-wrapper" :style="{ minHeight: '500px' }">
<listPage />
</div>
</template>
</el-row>
</div>
......@@ -1970,7 +1972,7 @@ const handleMediaClick = item => {
position: absolute;
width: 240px;
height: 89px;
top: 30px;
top: 12px;
right: -24px;
display: flex;
flex-direction: column;
......
......@@ -390,6 +390,9 @@ onMounted(async () => {
background-color: #fff;
border-radius: 4px;
box-shadow: 0 0 0 1px var(--el-input-border-color, var(--el-border-color)) inset;
&:hover {
box-shadow: 0 0 0 1px var(--el-input-border-color, var(--el-border-color)) inset !important;
}
}
:deep(.el-input__inner) {
......@@ -462,6 +465,11 @@ onMounted(async () => {
height: 24px;
color: rgb(95, 101, 108);
}
:deep(.el-checkbox__label) {
font-size: 16px;
color: #666666;
font-weight: 400;
}
.custom-date-picker {
width: 100%;
......
......@@ -110,7 +110,9 @@
<div class="data-origin-icon">
<img :src="tipsIcon" alt="" />
</div>
<div class="data-origin-text">进入实体清单的中国实体数量变化趋势,数据来源:美国商务部官网</div>
<div class="data-origin-text">
进入SDN清单的中国实体数量变化趋势,数据来源:美国财政部海外资产管理办公室官网
</div>
</div>
<div class="ai-pane">
<AiButton />
......@@ -169,7 +171,9 @@
<div class="data-origin-icon">
<img :src="tipsIcon" alt="" />
</div>
<div class="data-origin-text">进入实体清单的中国实体领域分布情况,数据来源:美国商务部官网</div>
<div class="data-origin-text">
进入SDN清单的中国实体领域分布情况,数据来源:美国财政部海外资产管理办公室官网
</div>
</div>
<div class="ai-pane">
<AiButton />
......@@ -208,7 +212,9 @@
<div class="data-origin-icon">
<img :src="tipsIcon" alt="" />
</div>
<div class="data-origin-text">进入实体清单的中国实体领域分布情况,数据来源:美国商务部官网</div>
<div class="data-origin-text">
进入SDN清单的中国实体领域分布情况,数据来源:美国财政部海外资产管理办公室官网
</div>
</div>
<div class="ai-pane">
<AiButton />
......@@ -240,7 +246,9 @@
<div class="data-origin-icon">
<img :src="tipsIcon" alt="" />
</div>
<div class="data-origin-text">进入实体清单的中国实体类型分布情况,数据来源:美国商务部官网</div>
<div class="data-origin-text">
进入SDN清单的中国实体类型分布情况,数据来源:美国财政部海外资产管理办公室官网
</div>
</div>
<div class="ai-pane">
<AiButton />
......
......@@ -45,7 +45,7 @@
<div class="right">
<AnalysisBox title="投融资限制举措关系图">
<div class="right-main">
<div class="relation-empty" v-if="selectedSanctionIds.length == 0">
<div class="relation-empty" v-if="emptyOfRelation">
<el-empty :image="emptyImg" :image-size="200">
<template #description>
<div class="empty">请在左侧勾选多次投融资限制制裁后点击“开始分析”查看结果</div>
......@@ -139,7 +139,24 @@
<div class="icon2"></div>
</div>
</div>
<!-- <div class="relation-content">
<RelationChart :is-vertical-chart="true" :graph-data="graphData" />
</div> -->
<div class="relation-charts-container">
<div v-for="(graphData, index) in graphDataList" :key="index" class="single-relation-chart-wrapper">
<!-- 可选:显示当前小图的标题,例如制裁名称 -->
<!-- <div class="chart-title" v-if="graphData.originalItem?.vertex?.name">
{{ graphData.originalItem.vertex.name }}
</div> -->
<div class="relation-content-item">
<RelationChart :is-vertical-chart="true" :graph-data="graphData" />
</div>
</div>
<!-- 空状态提示 -->
<div v-if="graphDataList.length === 0" class="empty-chart-tip">暂无关联详情数据</div>
</div>
</div>
</el-dialog>
</div>
......@@ -383,13 +400,16 @@ const fetchRecordRelation = async () => {
recordRelation.value = { noRelationVertices: [], relationVoList: [] };
}
};
const emptyOfRelation = computed(
() => recordRelation.value.noRelationVertices.length == 0 || recordRelation.value.relationVoList.length == 0
);
const vertexInfo = ref({});
const curNode = ref({});
const curLink = ref({});
const nodeVisible = ref(false);
const relationVisible = ref(false);
const tipsInfo = ref("");
const graphData = ref({});
const graphDataList = ref([]);
const getTipsInfo = (relationType, reason) => {
switch (relationType) {
case "继承":
......@@ -400,6 +420,8 @@ const getTipsInfo = (relationType, reason) => {
return `${dayjs(curLink.value.data.originInfo.fromVertex.date).format("YYYY年MM月DD日")}-SDN清单更新与${dayjs(curLink.value.data.originInfo.toVertex.date).format("YYYY年MM月DD日")}-SDN清单更新存在相同${reason},属于相似关系。`;
}
};
// 在 constrainedAssociation.vue 的 script setup 中
const handleClickNode = node => {
console.log("节点点击", node);
if (node.dataType == "node") {
......@@ -418,24 +440,125 @@ const handleClickNode = node => {
relationVisible.value = true;
curLink.value = node;
const relationType = node.data.relationType;
// 继承 - 2025年10月1日-SDN清单更新依托于2024年2月08日-SDN清单更新,两次制裁存在继承关系。
// 冲突 - 2025年2月19日-SDN清单更新中制裁的实体在2024年2月08日-SDN清单更新中被移除,属于冲突关系。
// 相似 - 2025年2月19日-SDN清单更新与2024年2月08日-SDN清单更新存在相同制裁原因,属于相似关系。
// 相似 - 2025年2月19日-SDN清单更新与2024年2月08日-SDN清单更新存在同领域制裁实体,属于相似关系。
// 相似 - 2025年2月19日-SDN清单更新与2024年2月08日-SDN清单更新存在相同依托文件,属于相似关系。
getEdgeInfo(node.data.edgeInfo.key).then(res => {
if (!!res) {
// recordRelation.value = res;
// 获取边详情数据
getEdgeInfo(node.data.edgeInfo.key)
.then(res => {
if (!!res && Array.isArray(res)) {
console.log("制裁之间的关系 =>", res);
// 【核心修改】遍历 res,为每一项生成独立的图表数据
const list = [];
res.forEach((item, index) => {
const vertex = item.vertex;
if (!vertex || !vertex.id) return;
const nodes = [];
const lines = [];
const nodeMap = new Map();
// 辅助函数:添加节点
const addNode = (id, text, type = "vertex") => {
if (nodeMap.has(id)) return;
const newNode = {
id: id,
text: text,
// 样式:顶点用主题色,细节用白色
color: type === "vertex" ? "var(--color-primary-50)" : "#ffffff",
fontColor: type === "vertex" ? "var(--text-primary-90-color)" : "#333333",
customFontSize: type === "vertex" ? "14px" : "12px"
};
nodes.push(newNode);
nodeMap.set(id, newNode);
};
// 辅助函数:添加连线
const addLine = (fromId, toId, relationText) => {
lines.push({
from: fromId,
to: toId,
text: relationText,
color: "var(--color-primary-50)",
fontColor: "#666"
});
};
// 1. 添加出发点 (Vertex)
// addNode(vertex.id, vertex.name, "vertex");
// 1. 添加出发点 (Vertex)
// 【修改点】:根据 originInfo 中的 fromVertex 或 toVertex 动态生成名称
let vertexName = vertex.name; // 默认 fallback
// 尝试从 curLink (即 node) 中获取 originInfo
const originInfo = node.data?.originInfo;
if (originInfo) {
// 判断当前 vertex.id 是 from 还是 to,从而决定取哪个日期
// 通常 item.vertex 对应的是边的起点或终点之一,这里假设 item.vertex 就是我们要展示的核心节点
// 如果业务逻辑中 item.vertex 始终对应 fromVertex 或 toVertex 中的一个,我们可以这样判断:
let sourceDate = null;
if (originInfo.fromVertex && originInfo.fromVertex.id === vertex.id) {
sourceDate = originInfo.fromVertex.date;
} else if (originInfo.toVertex && originInfo.toVertex.id === vertex.id) {
sourceDate = originInfo.toVertex.date;
}
// 如果找到了对应的日期,则格式化;否则保持原名或使用默认逻辑
if (sourceDate) {
vertexName = dayjs(sourceDate).format("YYYY年MM月DD日") + " SDN清单更新";
}
}
addNode(vertex.id, vertexName, "vertex");
// 2. 处理 edgeReasonList -> reasonDetail
if (item.edgeReasonList && item.edgeReasonList.length > 0) {
item.edgeReasonList.forEach(reasonItem => {
const relationName = reasonItem.reason; // 例如: "依托文件"
if (reasonItem.reasonDetail && reasonItem.reasonDetail.length > 0) {
reasonItem.reasonDetail.forEach(detailItem => {
// 使用 detailItem.name 作为唯一 ID
// 注意:在这个独立的小图中,ID 只要不重复即可。
// 如果不同项之间有相同的 detailItem.name,它们在不同图中是隔离的,所以没问题。
const detailId = detailItem.name;
addNode(detailId, detailItem.name, "detail");
addLine(vertex.id, detailId, relationName);
});
}
});
}
// 只有当有连线时才加入列表,或者即使只有顶点也加入(视需求而定)
if (nodes.length > 0) {
list.push({
rootId: vertex.id,
nodes: nodes,
lines: lines,
// 可以保留原始数据用于调试或额外展示
originalItem: item
});
}
});
graphDataList.value = list;
// 处理提示文案 (取第一个或根据业务逻辑组合)
let reason = "";
if (relationType == "相似") {
if (relationType == "相似" && res[0]?.edgeReasonList?.[0]?.reason) {
reason = res[0].edgeReasonList[0].reason;
}
tipsInfo.value = getTipsInfo(relationType, reason);
} else {
// recordRelation.value = { noRelationVertices: [], relationVoList: [] };
graphDataList.value = [];
}
})
.catch(err => {
console.error("获取边信息失败", err);
graphDataList.value = [];
});
}
};
......@@ -481,10 +604,6 @@ const formatChangeSummary = (addList, delList) => {
return `${item.value}${unit}${noun}`;
});
// 拼接:移除 + item1 + , + item2 ...
// 注意:题目要求“删除”,但之前代码用的是“移除”,这里统一使用“移除”或“删除”。
// 根据题目描述“展示样本为:新增12个实体,3名个人,移除1个实体”,这里使用“移除”更贴切上下文,
// 如果必须用“删除”,请将下面的 '移除' 改为 '删除'。
parts.push(`移除${delItems.join(",")}`);
}
......@@ -708,6 +827,57 @@ onMounted(() => {
flex-direction: column;
gap: 16px;
border-top: 1px solid rgb(238, 238, 238);
// 【新增】关系图容器样式
.relation-charts-container {
display: flex;
flex-direction: column;
gap: 20px;
height: 400px;
overflow-y: auto;
padding-right: 10px; // 给滚动条留空间
// 自定义滚动条样式
&::-webkit-scrollbar {
width: 6px;
}
&::-webkit-scrollbar-thumb {
background: #ccc;
border-radius: 3px;
}
}
.single-relation-chart-wrapper {
border: 1px solid #eee;
border-radius: 8px;
padding: 10px;
background-color: #fafafa;
height: 400px;
.chart-title {
font-size: 14px;
font-weight: bold;
color: #333;
margin-bottom: 10px;
padding-left: 5px;
border-left: 3px solid var(--color-primary-50);
}
.relation-content-item {
height: 400px; // 每个小图的高度,可根据需要调整
// width: 100%;
// 确保 RelationChart 内部能正确填充
:deep(.relation-graph) {
width: 100%;
height: 100%;
}
}
}
.empty-chart-tip {
text-align: center;
color: #999;
padding: 20px;
}
.hintWrap {
display: flex;
align-items: center;
......@@ -753,6 +923,10 @@ onMounted(() => {
}
}
}
.relation-content {
height: 400px;
width: 100%;
}
.info-btn {
position: absolute;
top: 20px;
......
......@@ -45,7 +45,7 @@
<div class="right">
<AnalysisBox title="投融资限制举措关系图">
<div class="right-main">
<div class="relation-empty" v-if="selectedSanctionIds.length == 0">
<div class="relation-empty" v-if="emptyOfRelation">
<el-empty :image="emptyImg" :image-size="200">
<template #description>
<div class="empty">请在左侧勾选多次投融资限制制裁后点击“开始分析”查看结果</div>
......@@ -145,12 +145,16 @@
<div class="relation-charts-container">
<div v-for="(graphData, index) in graphDataList" :key="index" class="single-relation-chart-wrapper">
<!-- 可选:显示当前小图的标题,例如制裁名称 -->
<div class="chart-title" v-if="graphData.originalItem?.vertex?.name">
<!-- <div class="chart-title" v-if="graphData.originalItem?.vertex?.name">
{{ graphData.originalItem.vertex.name }}
</div>
</div> -->
<div class="relation-content-item">
<RelationChart :is-vertical-chart="true" :graph-data="graphData" />
<RelationChart
:is-vertical-chart="true"
:graph-data="graphData"
:is-reversed="graphData.isReversed"
/>
</div>
</div>
......@@ -400,6 +404,9 @@ const fetchRecordRelation = async () => {
recordRelation.value = { noRelationVertices: [], relationVoList: [] };
}
};
const emptyOfRelation = computed(
() => recordRelation.value.noRelationVertices.length == 0 || recordRelation.value.relationVoList.length == 0
);
const vertexInfo = ref({});
const curNode = ref({});
const curLink = ref({});
......@@ -434,6 +441,11 @@ const handleClickNode = node => {
}
});
} else {
handleLink(node);
}
};
const handleLink = node => {
relationVisible.value = true;
curLink.value = node;
const relationType = node.data.relationType;
......@@ -456,15 +468,86 @@ const handleClickNode = node => {
const nodeMap = new Map();
// 辅助函数:添加节点
const addNode = (id, text, type = "vertex") => {
const addNode = (id, text, type = "vertex", highlight = false) => {
if (nodeMap.has(id)) return;
// 【修改】根据 type 定义不同的样式
let nodeStyle = {};
if (type === "vertex") {
nodeStyle = {
color: "rgb(185, 220, 255)", // 背景色
fontColor: "rgb(5, 95, 194)", // 文字颜色
customFontSize: "16px", // 文字大小
fontWeight: 700, // 加粗
// width: "120px", // 固定宽度,防止长文本换行难看
// height: "40px", // 固定高度
borderRadius: "20px", // 圆角
borderColor: "rgb(185, 220, 255)"
// border: "1px solid rgb(185, 220, 255)"
};
} else {
// 细节节点样式
// nodeStyle = {
// color: "#ffffff",
// fontColor: "#333333",
// customFontSize: "12px",
// // width: "100px",
// // height: "30px",
// borderRadius: "15px",
// borderColor: "rgb(230, 231, 232)"
// };
// 细节节点样式
if (highlight) {
// 【核心逻辑】根据 relationType 设置高亮样式
if (relationType === "冲突") {
nodeStyle = {
color: "rgba(255, 241, 240, 1)", // 背景
borderColor: "rgb(206, 79, 81)", // 边框
fontColor: "rgb(206, 79, 81)", // 字体
fontWeight: 700, // 加粗
customFontSize: "12px",
borderRadius: "15px"
};
} else if (relationType === "相似" || relationType === "继承") {
// 相似和继承使用相同的蓝色系高亮
nodeStyle = {
color: "rgb(185, 220, 255)", // 背景
borderColor: "rgb(5, 95, 194)", // 边框
fontColor: "rgb(5, 95, 194)", // 字体
fontWeight: 700, // 加粗
customFontSize: "12px",
borderRadius: "15px"
};
} else {
// 默认高亮样式(以防万一)
nodeStyle = {
color: "#e6f7ff",
borderColor: "#1890ff",
fontColor: "#1890ff",
fontWeight: 700,
customFontSize: "12px",
borderRadius: "15px"
};
}
} else {
// 非高亮细节节点默认样式
nodeStyle = {
color: "#ffffff",
borderColor: "rgb(230, 231, 232)",
fontColor: "#333333",
customFontSize: "12px",
borderRadius: "15px",
fontWeight: 400
};
}
}
const newNode = {
id: id,
text: text,
// 样式:顶点用主题色,细节用白色
color: type === "vertex" ? "var(--color-primary-50)" : "#ffffff",
fontColor: type === "vertex" ? "var(--text-primary-90-color)" : "#333333",
customFontSize: type === "vertex" ? "14px" : "12px"
// color: type === "vertex" ? "var(--color-primary-50)" : "#ffffff",
// fontColor: type === "vertex" ? "var(--text-primary-90-color)" : "#333333",
// customFontSize: type === "vertex" ? "14px" : "12px",
...nodeStyle
};
nodes.push(newNode);
nodeMap.set(id, newNode);
......@@ -482,7 +565,33 @@ const handleClickNode = node => {
};
// 1. 添加出发点 (Vertex)
addNode(vertex.id, vertex.name, "vertex");
// addNode(vertex.id, vertex.name, "vertex");
// 1. 添加出发点 (Vertex)
// 【修改点】:根据 originInfo 中的 fromVertex 或 toVertex 动态生成名称
let vertexName = vertex.name; // 默认 fallback
// 尝试从 curLink (即 node) 中获取 originInfo
const originInfo = node.data?.originInfo;
if (originInfo) {
// 判断当前 vertex.id 是 from 还是 to,从而决定取哪个日期
// 通常 item.vertex 对应的是边的起点或终点之一,这里假设 item.vertex 就是我们要展示的核心节点
// 如果业务逻辑中 item.vertex 始终对应 fromVertex 或 toVertex 中的一个,我们可以这样判断:
let sourceDate = null;
if (originInfo.fromVertex && originInfo.fromVertex.id === vertex.id) {
sourceDate = originInfo.fromVertex.date;
} else if (originInfo.toVertex && originInfo.toVertex.id === vertex.id) {
sourceDate = originInfo.toVertex.date;
}
// 如果找到了对应的日期,则格式化;否则保持原名或使用默认逻辑
if (sourceDate) {
vertexName = dayjs(sourceDate).format("YYYY年MM月DD日") + " SDN清单更新";
}
}
addNode(vertex.id, vertexName, "vertex");
// 2. 处理 edgeReasonList -> reasonDetail
if (item.edgeReasonList && item.edgeReasonList.length > 0) {
......@@ -496,7 +605,12 @@ const handleClickNode = node => {
// 如果不同项之间有相同的 detailItem.name,它们在不同图中是隔离的,所以没问题。
const detailId = detailItem.name;
addNode(detailId, detailItem.name, "detail");
addNode(
detailId,
detailItem.name,
"detail",
addNode(detailId, detailItem.name, "detail", !!detailItem.highlight)
);
addLine(vertex.id, detailId, relationName);
});
}
......@@ -510,7 +624,8 @@ const handleClickNode = node => {
nodes: nodes,
lines: lines,
// 可以保留原始数据用于调试或额外展示
originalItem: item
originalItem: item,
isReversed: index % 2 !== 0
});
}
});
......@@ -531,7 +646,6 @@ const handleClickNode = node => {
console.error("获取边信息失败", err);
graphDataList.value = [];
});
}
};
// 【新增/修改】格式化变动 summary 的函数
......@@ -575,10 +689,6 @@ const formatChangeSummary = (addList, delList) => {
return `${item.value}${unit}${noun}`;
});
// 拼接:移除 + item1 + , + item2 ...
// 注意:题目要求“删除”,但之前代码用的是“移除”,这里统一使用“移除”或“删除”。
// 根据题目描述“展示样本为:新增12个实体,3名个人,移除1个实体”,这里使用“移除”更贴切上下文,
// 如果必须用“删除”,请将下面的 '移除' 改为 '删除'。
parts.push(`移除${delItems.join(",")}`);
}
......@@ -805,10 +915,10 @@ onMounted(() => {
// 【新增】关系图容器样式
.relation-charts-container {
display: flex;
flex-direction: column;
flex-direction: row;
gap: 20px;
max-height: 60vh; // 限制最大高度,超出滚动
overflow-y: auto;
height: 400px;
overflow-x: auto;
padding-right: 10px; // 给滚动条留空间
// 自定义滚动条样式
......@@ -822,11 +932,14 @@ onMounted(() => {
}
.single-relation-chart-wrapper {
border: 1px solid #eee;
border-radius: 8px;
flex: 1;
min-width: 400px; /* 保证每个图表有最小宽度 */
// border: 1px solid #eee;
// border-radius: 8px;
padding: 10px;
background-color: #fafafa;
// background-color: #fafafa;
display: flex;
flex-direction: column;
.chart-title {
font-size: 14px;
font-weight: bold;
......@@ -837,8 +950,10 @@ onMounted(() => {
}
.relation-content-item {
height: 200px; // 每个小图的高度,可根据需要调整
flex: 1;
position: relative;
width: 100%;
height: 100%;
// 确保 RelationChart 内部能正确填充
:deep(.relation-graph) {
......
......@@ -155,15 +155,8 @@ const getTagStyle = tag => {
// 跳转公司详情页
const handleCompClick = item => {
console.log("item", item);
window.sessionStorage.setItem("curTabName", item.entityNameZh || item.entityName);
window.sessionStorage.setItem("curTabName", item.name || item.orgName);
gotoCompanyPages(item.id);
// const route = router.resolve({
// name: "companyPages",
// params: {
// id: item.id
// }
// });
// window.open(route.href, "_blank");
};
</script>
......
......@@ -253,7 +253,7 @@ const handleCompClick = item => {
// }
// });
// window.open(route.href, "_blank");
gotoCompanyPages(item.entityId);
gotoCompanyPages(item.id);
};
const searchKeyword = ref("");
......
......@@ -226,7 +226,9 @@
<div class="data-origin-icon">
<img :src="tipsIcon" alt="" />
</div>
<div class="data-origin-text">美国商务部发布实体清单的频次,数据来源:美国商务部官网</div>
<div class="data-origin-text">
美国商务部发布实体清单的频次,数据来源:美国财政部海外资产管理办公室官网
</div>
</div>
<div class="ai-pane">
<AiButton />
......@@ -270,7 +272,7 @@
<img :src="tipsIcon" alt="" />
</div>
<div class="data-origin-text">
美国商务部发布商业管制清单的频次,数据来源:美国商务部官网
美国商务部发布商业管制清单的频次,数据来源:美国财政部海外资产管理办公室官网
</div>
</div>
<div class="ai-pane">
......@@ -323,7 +325,9 @@
<div class="data-origin-icon">
<img :src="tipsIcon" alt="" />
</div>
<div class="data-origin-text">进入实体清单的中国实体领域分布情况,数据来源:美国商务部官网</div>
<div class="data-origin-text">
进入SDN清单的中国实体领域分布情况,数据来源:美国财政部海外资产管理办公室官网
</div>
</div>
<div class="ai-pane">
<AiButton />
......@@ -348,7 +352,9 @@
<div class="data-origin-icon">
<img :src="tipsIcon" alt="" />
</div>
<div class="data-origin-text">进入实体清单的中国实体数量变化趋势,数据来源:美国商务部官网</div>
<div class="data-origin-text">
进入SDN清单的中国实体数量变化趋势,数据来源:美国财政部海外资产管理办公室官网
</div>
</div>
<div class="ai-pane">
<AiButton />
......@@ -373,7 +379,7 @@
</div>
</div>
<template v-if="activeResourceTab === 'entity'">
<el-col :span="8" style="padding: 0">
<el-col :span="8" style="padding-left: 0">
<custom-container title="历次制裁过程" :titleIcon="listIcon" height="845px">
<template #default>
<div class="box4">
......@@ -422,7 +428,7 @@
</template>
</custom-container>
</el-col>
<el-col :span="16" style="padding: 0">
<el-col :span="16" style="padding-right: 0">
<custom-container title="制裁实体清单" :titleIcon="entityIcon" height="845px">
<template #header-right>
<div class="box5-header-right">{{ total }}家实体</div>
......@@ -1830,15 +1836,6 @@ const handleMediaClick = item => {
</script>
<style lang="scss" scoped>
// * {
// margin: 0;
// padding: 0;
// }
:deep(.el-input__wrapper) {
// box-shadow: none;
}
.home-header {
height: 64px;
background: url("@/assets/images/nav-bg.png");
......@@ -1907,7 +1904,7 @@ const handleMediaClick = item => {
position: absolute;
width: 240px;
height: 89px;
top: 30px;
top: 12px;
right: -24px;
display: flex;
flex-direction: column;
......@@ -3218,7 +3215,7 @@ const handleMediaClick = item => {
align-items: center;
margin-top: 6px;
margin-bottom: 36px;
padding-left: 10px;
// padding-left: 10px;
.resource-tab-item {
margin-right: 12px;
......@@ -3287,7 +3284,7 @@ const handleMediaClick = item => {
}
.text {
font-size: 20px;
font-size: 16px;
font-weight: 700;
font-family: "Microsoft YaHei";
line-height: 26px;
......
......@@ -59,7 +59,9 @@
<div class="data-origin-icon">
<img :src="tipsIcon" alt="" />
</div>
<div class="data-origin-text">进入本次实体清单的中国实体领域分布情况,数据来源:美国商务部官网</div>
<div class="data-origin-text">
进入本次SDN清单的中国实体领域分布情况,数据来源:美国财政部海外资产管理办公室官网
</div>
</div>
<div class="ai-pane">
<AiButton />
......@@ -109,7 +111,9 @@
<div class="data-origin-icon">
<img :src="tipsIcon" alt="" />
</div>
<div class="data-origin-text">进入本次实体清单的中国实体类型分布情况,数据来源:美国商务部官网</div>
<div class="data-origin-text">
进入本次SDN清单的中国实体类型分布情况,数据来源:美国财政部海外资产管理办公室官网
</div>
</div>
<div class="ai-pane">
<AiButton />
......@@ -150,7 +154,9 @@
<div class="data-origin-icon">
<img :src="tipsIcon" alt="" />
</div>
<div class="data-origin-text">进入本次实体清单的实体国家地区分布情况,数据来源:美国商务部官网</div>
<div class="data-origin-text">
进入本次SDN清单的实体国家地区分布情况,数据来源:美国财政部海外资产管理办公室官网
</div>
</div>
<div class="ai-pane">
<AiButton />
......@@ -194,7 +200,9 @@
<div class="data-origin-icon">
<img :src="tipsIcon" alt="" />
</div>
<div class="data-origin-text">进入本次实体清单的中国实体各省分布情况,数据来源:美国商务部官网</div>
<div class="data-origin-text">
进入本次SDN清单的中国实体各省分布情况,数据来源:美国财政部海外资产管理办公室官网
</div>
</div>
<div class="ai-pane">
<AiButton />
......@@ -845,11 +853,6 @@ onMounted(() => {
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.data-statistics {
width: 1601px;
margin: 0 auto;
......
......@@ -540,11 +540,6 @@ onMounted(async () => {
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.deepMiningChartmode {
height: calc(100vh - 220px) !important;
// overflow: hidden;
......
......@@ -990,11 +990,6 @@ onMounted(async () => {
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.industrial-impact {
width: 100%;
padding-top: 16px;
......
......@@ -1118,11 +1118,6 @@ onBeforeUnmount(() => {
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.industrial-impact {
width: 100%;
padding-top: 16px;
......
......@@ -29,10 +29,6 @@ const activeIndex = ref(0);
</script>
<style scoped lang="scss">
* {
margin: 0;
padding: 0;
}
.impact-analysis {
width: 1601px;
margin: 0 auto;
......
......@@ -95,7 +95,7 @@
</div>
</div>
<div class="right" v-loading="isLoading">
<AnalysisBox title="制裁清单" :showAllBtn="false">
<AnalysisBox title="制裁清单" :showAllBtn="false" style="height: auto">
<div class="right-title">
<div class="filter-row">
<div class="filter-left">
......@@ -234,7 +234,31 @@
</div>
</AnalysisBox>
<div :style="{ height: '20px' }"></div>
<AnalysisBox title="制裁原因及相关历史制裁" :showAllBtn="false"></AnalysisBox>
<AnalysisBox title="制裁原因及相关历史制裁" :showAllBtn="false" style="height: auto">
<div class="reason-history">
<div class="reason-history-item" v-for="(item, index) in reasonHistoryList" :key="item.id">
<div class="item-header">
<div class="item-header-title">
<div class="item-header-title-idx">{{ index + 1 }}</div>
<div class="item-header-title-text">{{ item.sanReason }}</div>
</div>
<div class="item-header-domain">
<AreaTag v-for="(domain, index) in item.techDomains" :key="index" :tagName="domain" />
</div>
</div>
<div class="item-content" v-for="(record, index) in item.relateSanRecords" :key="index">
<div class="item-content-record">
<div class="item-content-record-header">
{{ record.postDate + " " + record.title }}
</div>
<div class="item-content-record-content">
{{ record.content }}
</div>
</div>
</div>
</div>
</div>
</AnalysisBox>
</div>
</div>
<!-- 50%规则子企业弹框 -->
......@@ -252,7 +276,6 @@ import { ref, defineProps, computed, onMounted, watch } from "vue";
import { useRouter } from "vue-router";
import { ElMessage } from "element-plus";
import AreaTag from "@/components/base/AreaTag/index.vue";
import { DArrowRight, Search } from "@element-plus/icons-vue";
import { debounce } from "lodash";
import title from "../../assets/title.png";
import defaultTitle from "../../assets/default-icon1.png";
......@@ -265,6 +288,7 @@ import {
} from "@/api/exportControlV2.0";
import { getRelateNews } from "@/api/finance";
import RuleSubsidiaryDialog from "../../../entityList/components/sanctionsOverview/components/listPage/RuleSubsidiaryDialog.vue";
import { getReasonAndSan } from "@/api/finance";
import { useRoute } from "vue-router";
import { useGotoCompanyPages } from "@/router/modules/company";
......@@ -365,7 +389,7 @@ const getSanctionOverviewList = async () => {
// 单次制裁-制裁概况-制裁背景
const timelinePage = ref(1);
const timelinePageSize = ref(3);
const timelinePageSize = ref(5);
const hasMore = ref(true);
const getSanctionBackground = async (isLoadMore = false) => {
......@@ -594,6 +618,18 @@ const entityDistribution = ref([
gradient: "linear-gradient(270deg, rgba(5,95,194,1) 0%, rgba(255,255,255,0) 100%)"
}
]);
const reasonHistoryList = ref([]);
const getReasonHistoryList = async () => {
try {
const res = await getReasonAndSan(sanRecordId.value);
console.log("制裁原因及相关历史制裁", res);
reasonHistoryList.value = res;
} catch (error) {
console.log(error);
}
};
const sanTypeId = ref("");
onMounted(() => {
// 获取路由参数中的sanTypeId
......@@ -609,6 +645,8 @@ onMounted(() => {
getSanctionBackground();
// 单次制裁-制裁概况-制裁清单
getSanctionOverviewList();
// 单次制裁-制裁概况-制裁原因及相关历史制裁
getReasonHistoryList();
});
</script>
......@@ -828,7 +866,7 @@ onMounted(() => {
.left-bottom-content {
padding: 20px 25px 0 25px;
height: calc(100% - 45px); // 减去标题高度
height: calc(100% - 20px); // 减去标题高度
display: flex;
flex-direction: column;
......@@ -836,7 +874,7 @@ onMounted(() => {
display: flex;
flex-direction: column;
gap: 24px;
margin-bottom: 24px;
margin-bottom: 5px;
overflow-y: auto; // 允许垂直滚动
flex: 1; // 占据剩余空间
padding-right: 10px; // 防止滚动条遮挡内容
......@@ -1183,6 +1221,95 @@ onMounted(() => {
}
}
}
.reason-history {
display: flex;
flex-direction: column;
gap: 16px;
padding: 5px 24px;
min-height: 500px;
max-height: 1000px;
margin-bottom: 15px;
.reason-history-item {
.item-header {
border-top: 1px solid #ddd;
border-bottom: 1px solid #ddd;
padding: 15px;
display: flex;
justify-content: space-between;
align-items: center;
.item-header-title {
display: flex;
align-items: center;
width: 85%;
.item-header-title-idx {
width: 24px;
height: 24px;
border-radius: 50%;
background-color: rgb(231, 243, 255);
font-size: 12px;
line-height: 24px;
text-align: center;
}
.item-header-title-text {
margin-left: 13px;
font-size: 16px;
font-weight: 700;
line-height: 28px;
font-family: "Source Han Sans CN";
color: rgb(59, 65, 75);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.item-header-domain {
// min-width: 100px;
}
}
.item-content {
padding: 10px 20px;
border-radius: 4px;
.item-content-record {
position: relative;
margin-top: 20px;
// border-left: 3px solid rgb(5, 95, 194);
background-color: rgb(247, 248, 249);
padding: 10px 0;
border-radius: 4px;
&::before {
content: "";
position: absolute;
left: 0;
top: 10px;
bottom: 10px;
width: 4px;
background-color: rgb(5, 95, 194);
}
.item-content-record-header {
padding: 0px 15px;
font-size: 16px;
font-weight: 700;
height: 30px;
line-height: 30px;
color: rgb(5, 95, 194);
font-family: "Source Han Sans CN";
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.item-content-record-content {
padding: 5px 15px;
font-size: 16px;
font-family: "Source Han Sans CN";
color: rgb(59, 65, 75);
line-height: 30px;
}
}
}
}
}
}
}
}
......
......@@ -108,7 +108,7 @@ import router from "@/router";
// 处理点击实体清单原文按钮
const handleClickOriginalText = () => {
// 打开新标签页
window.open(`/exportControl/origin?id=${sanRecordId.value}`, "_blank");
window.open(`/finance/origin?id=${sanRecordId.value}`, "_blank");
};
// 获取URL参数
......@@ -241,7 +241,6 @@ const handlePageChange = async newPage => {
await fetchSanctionData();
};
// ========== 选择某项 ==========
const selectSanction = async item => {
selectedSanctionId.value = item.id;
router.replace({
......@@ -254,6 +253,7 @@ const selectSanction = async item => {
sanctionModalVisible.value = false;
console.log("跳转URL:", window.location.href);
// 根据最新URL参数刷新当前页面
window.sessionStorage.setItem("curTabName", item.postDate + " 《实体清单新增条目》");
window.open(`${window.location.pathname}?id=${item.id}&sanTypeId=${item.sanTypeId}`, "_self");
};
......
......@@ -15,26 +15,21 @@
<div class="header-right">
<!-- 中英文切换开关 -->
<div class="toggle-group">
<span :class="{ active: !showChinese }">英文</span>
<el-switch
v-model="showChinese"
active-text="中"
inactive-text="英"
:inline-prompt="true"
@change="handleToggleChange"
/>
<span :class="{ active: showChinese }">中文</span>
<!-- <span :class="{ active: !showChinese }">英文</span> -->
<el-switch v-model="showChinese" @change="handleToggleChange" />
<img :src="transIcon" alt="" />
<span :class="{ active: showChinese }">显示原文</span>
</div>
<!-- 下载按钮 -->
<el-button type="primary" :icon="Download" @click="handleDownload"> 下载 </el-button>
<el-button plain :icon="Download" @click="handleDownload"> 下载 </el-button>
</div>
</div>
<!-- 外层滚动容器,统一控制两侧滚动 -->
<div class="report-box" ref="reportBoxRef">
<div class="pdf-pane-wrap" :class="{ 'center-mode': !showChinese }">
<div class="pdf-pane-wrap" v-if="showChinese" :class="{ 'center-mode': !showChinese }">
<pdf ref="leftPdfRef" :pdfUrl="headerTitle.srcUrl" class="pdf-pane-inner" />
</div>
<div class="pdf-pane-wrap" v-if="showChinese">
<div class="pdf-pane-wrap">
<pdf ref="rightPdfRef" :pdfUrl="headerTitle.transUrl" class="pdf-pane-inner" />
</div>
</div>
......@@ -47,6 +42,7 @@ import { ref, onMounted, watch, computed } from "vue";
import { Download } from "@element-plus/icons-vue";
import { getSingleSanctionOverview } from "@/api/exportControlV2.0.js";
import title from "../assets/title.png";
import transIcon from "../assets/icon-translation.png";
import pdf from "./pdf.vue";
const leftPdfRef = ref(null);
......@@ -299,15 +295,15 @@ onMounted(() => {
}
}
:deep(.el-button) {
--el-button-bg-color: #055fc2;
--el-button-border-color: #055fc2;
--el-button-hover-bg-color: #044c9b;
--el-button-hover-border-color: #044c9b;
// :deep(.el-button) {
// --el-button-bg-color: #055fc2;
// --el-button-border-color: #055fc2;
// --el-button-hover-bg-color: #044c9b;
// --el-button-hover-border-color: #044c9b;
font-size: 14px;
padding: 10px 20px;
}
// font-size: 14px;
// padding: 10px 20px;
// }
}
}
......@@ -318,6 +314,8 @@ onMounted(() => {
display: flex;
overflow-y: auto;
overflow-x: hidden;
// ✅ 添加居中对齐
justify-content: center;
}
.pdf-pane-wrap {
......@@ -330,6 +328,8 @@ onMounted(() => {
&.center-mode {
flex: 0 0 100%;
max-width: 100%;
// ✅ 添加居中样式
width: 728px; // 约一半宽度,保持单栏时美观
margin: 0 auto;
}
}
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论