提交 a37f484f authored 作者: 朱政's avatar 朱政

Merge branch 'pre' into zz-dev

流水线 #603 已通过 于阶段
in 1 分 30 秒
...@@ -147,7 +147,7 @@ const router = createRouter({ ...@@ -147,7 +147,7 @@ const router = createRouter({
// 2)登录成功回跳带 ?token=:先 setToken 并同步 bootId,再去掉 URL 中的 token(须先于 clearTokenIfNewDevBoot,避免误清刚写入的登录态) // 2)登录成功回跳带 ?token=:先 setToken 并同步 bootId,再去掉 URL 中的 token(须先于 clearTokenIfNewDevBoot,避免误清刚写入的登录态)
// 3)已有本地 token:正常走前端路由 // 3)已有本地 token:正常走前端路由
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
// 【新增】在每次路由跳转开始前,取消上一个页面所有未完成的请求 // 在每次路由跳转开始前,取消上一个页面所有未完成的请求
// 这能防止旧页面的数据回来覆盖新页面,也能减少服务器压力 // 这能防止旧页面的数据回来覆盖新页面,也能减少服务器压力
cancelAllRequests(); cancelAllRequests();
if (import.meta.env.DEV) { if (import.meta.env.DEV) {
......
...@@ -380,7 +380,7 @@ export const goToSearch = (tabName, areaName, billSearchType) => { ...@@ -380,7 +380,7 @@ export const goToSearch = (tabName, areaName, billSearchType) => {
} }
// 跳转数据资源库 // 跳转数据资源库-国家法案
export const goToDataCountryBill = (selectParam) => { export const goToDataCountryBill = (selectParam) => {
// const codeParam = new URLSearchParams(selectParam) // const codeParam = new URLSearchParams(selectParam)
// JSON -> Base64 // JSON -> Base64
......
...@@ -151,7 +151,6 @@ const setChart = (option, chartId, allowClick, selectParam) => { ...@@ -151,7 +151,6 @@ const setChart = (option, chartId, allowClick, selectParam) => {
// 容器可能受布局/异步渲染影响,强制一次 resize 保证 canvas 与容器一致 // 容器可能受布局/异步渲染影响,强制一次 resize 保证 canvas 与容器一致
setTimeout(() => { setTimeout(() => {
chart.resize(); chart.resize();
}, 0); }, 0);
return chart; return chart;
}; };
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<div class="header-box"> <div class="header-box">
<div class="header-top"> <div class="header-top">
<SelectBox :placeholder-name="areaPlaceHolder" select-title="科技领域" :select-list="areaList" <SelectBox :placeholder-name="areaPlaceHolder" select-title="科技领域" :select-list="areaList"
:select-name="selectedArea" @update:select-text="handleSelectArea" /> :select-name="selectedArea" :is-multiple="true" @update:select-text="handleSelectArea" />
<SelectBox :placeholder-name="DatePlaceHolder" select-title="成立时间" :select-list="dateList" <SelectBox :placeholder-name="DatePlaceHolder" select-title="成立时间" :select-list="dateList"
:select-name="selectedDate" :custom-time="customTime" @update:select-text="handleSelectDate" :select-name="selectedDate" :custom-time="customTime" @update:select-text="handleSelectDate"
@update:custom-time="handleCustomDate" /> @update:custom-time="handleCustomDate" />
...@@ -388,11 +388,11 @@ const handleChangeTime = value => { ...@@ -388,11 +388,11 @@ const handleChangeTime = value => {
// 激活的标签列表 // 激活的标签列表
const activeTagList = computed(() => { const activeTagList = computed(() => {
const arr = [] const arr = []
if (selectedArea.value && selectedArea.value !== '全部领域') { if (selectedArea.value && selectedArea.value[0] !== '全部领域') {
arr.push( arr.push(
{ {
tag: '科技领域', tag: '科技领域',
name: selectedArea.value name: selectedArea.value.join('、')
} }
) )
} }
...@@ -439,7 +439,7 @@ const activeTagList = computed(() => { ...@@ -439,7 +439,7 @@ const activeTagList = computed(() => {
const handleCloseCurTag = (tag, index) => { const handleCloseCurTag = (tag, index) => {
switch (tag.tag) { switch (tag.tag) {
case '科技领域': case '科技领域':
selectedArea.value = '全部领域' selectedArea.value = ['全部领域']
break break
case '成立时间': case '成立时间':
selectedDate.value = '' selectedDate.value = ''
...@@ -493,7 +493,7 @@ const operationList = ref([ ...@@ -493,7 +493,7 @@ const operationList = ref([
// 科技领域 // 科技领域
const areaPlaceHolder = ref('请选择领域') const areaPlaceHolder = ref('请选择领域')
const selectedArea = ref('全部领域') const selectedArea = ref(['全部领域'])
const areaList = ref([ const areaList = ref([
{ {
name: '全部领域', name: '全部领域',
...@@ -561,7 +561,11 @@ const areaList = ref([ ...@@ -561,7 +561,11 @@ const areaList = ref([
}, },
]) ])
const handleSelectArea = (value) => { const handleSelectArea = (value) => {
selectedArea.value = value if (value[value.length - 1] === '全部领域') {
selectedArea.value = ['全部领域']
return
}
selectedArea.value = value.length > 1 && value.includes('全部领域') ? value.filter(item => item !== '全部领域') : value;
} }
// 提出时间 // 提出时间
...@@ -678,7 +682,7 @@ const isSanctioned = ref(false) ...@@ -678,7 +682,7 @@ const isSanctioned = ref(false)
// 清空条件 // 清空条件
const handleClear = () => { const handleClear = () => {
selectedArea.value = '全部领域' selectedArea.value = ['全部领域']
selectedDate.value = '' selectedDate.value = ''
customTime.value = [] customTime.value = []
selectedCountry.value = '全部国家地区' selectedCountry.value = '全部国家地区'
...@@ -739,7 +743,7 @@ const fetchTableData = async () => { ...@@ -739,7 +743,7 @@ const fetchTableData = async () => {
page: currentPage.value, page: currentPage.value,
size: pageSize.value, size: pageSize.value,
type: 5, // type 1= 法案 2= 政令 3 =智库 4=智库报告 5=实体清单【制裁记录】 6= 人物 7= 机构 8=新闻 9= 社媒 type: 5, // type 1= 法案 2= 政令 3 =智库 4=智库报告 5=实体清单【制裁记录】 6= 人物 7= 机构 8=新闻 9= 社媒
domains: selectedArea.value === '全部领域' ? null : [selectedArea.value], domains: selectedArea.value[0] === '全部领域' ? null : selectedArea.value,
proposedDateStart: customTime.value[0] ? customTime.value[0] : null, proposedDateStart: customTime.value[0] ? customTime.value[0] : null,
proposedDateEnd: customTime.value[1] ? customTime.value[1] : null, proposedDateEnd: customTime.value[1] ? customTime.value[1] : null,
countryId: selectedCountry.value === '全部国家地区' ? null : selectedCountry.value, countryId: selectedCountry.value === '全部国家地区' ? null : selectedCountry.value,
...@@ -852,7 +856,7 @@ const fetchAllData = async () => { ...@@ -852,7 +856,7 @@ const fetchAllData = async () => {
page: 1, page: 1,
size: 9999, size: 9999,
type: 5, // type 1= 法案 2= 政令 3 =智库 4=智库报告 5=实体清单【制裁记录】 6= 人物 7= 机构 8=新闻 9= 社媒 type: 5, // type 1= 法案 2= 政令 3 =智库 4=智库报告 5=实体清单【制裁记录】 6= 人物 7= 机构 8=新闻 9= 社媒
domains: selectedArea.value === '全部领域' ? null : [selectedArea.value], domains: selectedArea.value[0] === '全部领域' ? null : selectedArea.value,
proposedDateStart: customTime.value[0] ? customTime.value[0] : null, proposedDateStart: customTime.value[0] ? customTime.value[0] : null,
proposedDateEnd: customTime.value[1] ? customTime.value[1] : null, proposedDateEnd: customTime.value[1] ? customTime.value[1] : null,
countryId: selectedCountry.value === '全部国家地区' ? null : selectedCountry.value, countryId: selectedCountry.value === '全部国家地区' ? null : selectedCountry.value,
...@@ -1008,7 +1012,11 @@ const handleDownloadCurChartData = () => { ...@@ -1008,7 +1012,11 @@ const handleDownloadCurChartData = () => {
const initParam = () => { const initParam = () => {
const hasQuery = Object.keys(route.query).length > 0; const hasQuery = Object.keys(route.query).length > 0;
if (hasQuery) { if (hasQuery) {
selectedArea.value = route.query.domains ? route.query.domains : '全部领域' if (route.query.selectedAreaList) {
selectedArea.value = JSON.parse(route.query.selectedAreaList)
} else {
selectedArea.value = route.query.domains ? [route.query.domains] : ['全部领域']
}
if (route.query.selectedDate && Array.isArray(JSON.parse(route.query.selectedDate)) && JSON.parse(route.query.selectedDate).length) { if (route.query.selectedDate && Array.isArray(JSON.parse(route.query.selectedDate)) && JSON.parse(route.query.selectedDate).length) {
selectedDate.value = '自定义' selectedDate.value = '自定义'
...@@ -1027,7 +1035,11 @@ const initParam = () => { ...@@ -1027,7 +1035,11 @@ const initParam = () => {
} }
} else { } else {
const savedQuery = JSON.parse(sessionStorage.getItem('dataCompanyRouteQuery') || '{}'); const savedQuery = JSON.parse(sessionStorage.getItem('dataCompanyRouteQuery') || '{}');
selectedArea.value = savedQuery.domains ? savedQuery.domains : '全部领域' if (savedQuery.selectedAreaList) {
selectedArea.value = JSON.parse(savedQuery.selectedAreaList)
} else {
selectedArea.value = savedQuery.domains ? [savedQuery.domains] : ['全部领域']
}
if (savedQuery.selectedDate && Array.isArray(JSON.parse(savedQuery.selectedDate)) && JSON.parse(savedQuery.selectedDate).length) { if (savedQuery.selectedDate && Array.isArray(JSON.parse(savedQuery.selectedDate)) && JSON.parse(savedQuery.selectedDate).length) {
selectedDate.value = '自定义' selectedDate.value = '自定义'
customTime.value = JSON.parse(savedQuery.selectedDate) customTime.value = JSON.parse(savedQuery.selectedDate)
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<div class="header-box"> <div class="header-box">
<div class="header-top"> <div class="header-top">
<SelectBox :placeholder-name="areaPlaceHolder" select-title="科技领域" :select-list="areaList" <SelectBox :placeholder-name="areaPlaceHolder" select-title="科技领域" :select-list="areaList"
:select-name="selectedArea" @update:select-text="handleSelectArea" /> :select-name="selectedArea" :is-multiple="true" @update:select-text="handleSelectArea" />
<SelectBox :placeholder-name="DatePlaceHolder" select-title="发布时间" :select-list="dateList" <SelectBox :placeholder-name="DatePlaceHolder" select-title="发布时间" :select-list="dateList"
:select-name="selectedDate" :custom-time="customTime" @update:select-text="handleSelectDate" :select-name="selectedDate" :custom-time="customTime" @update:select-text="handleSelectDate"
@update:custom-time="handleCustomDate" /> @update:custom-time="handleCustomDate" />
...@@ -331,11 +331,11 @@ const handleChangeTime = value => { ...@@ -331,11 +331,11 @@ const handleChangeTime = value => {
// 激活的标签列表 // 激活的标签列表
const activeTagList = computed(() => { const activeTagList = computed(() => {
const arr = [] const arr = []
if (selectedArea.value && selectedArea.value !== '全部领域') { if (selectedArea.value && selectedArea.value[0] !== '全部领域') {
arr.push( arr.push(
{ {
tag: '科技领域', tag: '科技领域',
name: selectedArea.value name: selectedArea.value.join('、')
} }
) )
} }
...@@ -394,7 +394,7 @@ const activeTagList = computed(() => { ...@@ -394,7 +394,7 @@ const activeTagList = computed(() => {
const handleCloseCurTag = (tag, index) => { const handleCloseCurTag = (tag, index) => {
switch (tag.tag) { switch (tag.tag) {
case '科技领域': case '科技领域':
selectedArea.value = '全部领域' selectedArea.value = ['全部领域']
break break
case '发布时间': case '发布时间':
selectedDate.value = '' selectedDate.value = ''
...@@ -493,7 +493,7 @@ const operationList = ref([ ...@@ -493,7 +493,7 @@ const operationList = ref([
// 科技领域 // 科技领域
const areaPlaceHolder = ref('请选择领域') const areaPlaceHolder = ref('请选择领域')
const selectedArea = ref('全部领域') const selectedArea = ref(['全部领域'])
const areaList = ref([ const areaList = ref([
{ {
name: '全部领域', name: '全部领域',
...@@ -561,7 +561,11 @@ const areaList = ref([ ...@@ -561,7 +561,11 @@ const areaList = ref([
}, },
]) ])
const handleSelectArea = (value) => { const handleSelectArea = (value) => {
selectedArea.value = value if (value[value.length - 1] === '全部领域') {
selectedArea.value = ['全部领域']
return
}
selectedArea.value = value.length > 1 && value.includes('全部领域') ? value.filter(item => item !== '全部领域') : value;
} }
// 提出时间 // 提出时间
...@@ -668,7 +672,7 @@ const isInvolveTechnology = ref(false) ...@@ -668,7 +672,7 @@ const isInvolveTechnology = ref(false)
// 清空条件 // 清空条件
const handleClear = () => { const handleClear = () => {
selectedArea.value = '全部领域' selectedArea.value = ['全部领域']
selectedDate.value = '' selectedDate.value = ''
customTime.value = [] customTime.value = []
selectedIns.value = '全部机构' selectedIns.value = '全部机构'
...@@ -731,7 +735,7 @@ const fetchTableData = async () => { ...@@ -731,7 +735,7 @@ const fetchTableData = async () => {
size: pageSize.value, size: pageSize.value,
// keyword: '', // keyword: '',
type: 2, // type 1= 法案 2= 政令 3 =智库 4=智库报告 5=实体清单【制裁记录】 6= 人物 7= 机构 8=新闻 9= 社媒 type: 2, // type 1= 法案 2= 政令 3 =智库 4=智库报告 5=实体清单【制裁记录】 6= 人物 7= 机构 8=新闻 9= 社媒
domains: selectedArea.value === '全部领域' ? null : [selectedArea.value], domains: selectedArea.value[0] === '全部领域' ? null : selectedArea.value,
proposedDateStart: customTime.value[0] ? customTime.value[0] : null, proposedDateStart: customTime.value[0] ? customTime.value[0] : null,
proposedDateEnd: customTime.value[1] ? customTime.value[1] : null, proposedDateEnd: customTime.value[1] ? customTime.value[1] : null,
organizationName: selectedIns.value === '全部机构' ? null : selectedIns.value, organizationName: selectedIns.value === '全部机构' ? null : selectedIns.value,
...@@ -816,7 +820,7 @@ const fetchAllData = async () => { ...@@ -816,7 +820,7 @@ const fetchAllData = async () => {
size: 9999, size: 9999,
// keyword: '', // keyword: '',
type: 2, // type 1= 法案 2= 政令 3 =智库 4=智库报告 5=实体清单【制裁记录】 6= 人物 7= 机构 8=新闻 9= 社媒 type: 2, // type 1= 法案 2= 政令 3 =智库 4=智库报告 5=实体清单【制裁记录】 6= 人物 7= 机构 8=新闻 9= 社媒
domains: selectedArea.value === '全部领域' ? null : [selectedArea.value], domains: selectedArea.value[0] === '全部领域' ? null : selectedArea.value,
proposedDateStart: customTime.value[0], proposedDateStart: customTime.value[0],
proposedDateEnd: customTime.value[1], proposedDateEnd: customTime.value[1],
organizationName: selectedIns.value === '全部机构' ? null : selectedIns.value, organizationName: selectedIns.value === '全部机构' ? null : selectedIns.value,
...@@ -973,7 +977,11 @@ const handleDownloadCurChartData = () => { ...@@ -973,7 +977,11 @@ const handleDownloadCurChartData = () => {
const initParam = () => { const initParam = () => {
const hasQuery = Object.keys(route.query).length > 0; const hasQuery = Object.keys(route.query).length > 0;
if (hasQuery) { if (hasQuery) {
selectedArea.value = route.query.domains ? route.query.domains : '全部领域' if (route.query.selectedAreaList) {
selectedArea.value = JSON.parse(route.query.selectedAreaList)
} else {
selectedArea.value = route.query.domains ? [route.query.domains] : ['全部领域']
}
if (route.query.selectedDate && Array.isArray(JSON.parse(route.query.selectedDate)) && JSON.parse(route.query.selectedDate).length) { if (route.query.selectedDate && Array.isArray(JSON.parse(route.query.selectedDate)) && JSON.parse(route.query.selectedDate).length) {
selectedDate.value = '自定义' selectedDate.value = '自定义'
...@@ -994,7 +1002,11 @@ const initParam = () => { ...@@ -994,7 +1002,11 @@ const initParam = () => {
} }
} else { } else {
const savedQuery = JSON.parse(sessionStorage.getItem('decreeRouteQuery') || '{}'); const savedQuery = JSON.parse(sessionStorage.getItem('decreeRouteQuery') || '{}');
selectedArea.value = savedQuery.domains ? savedQuery.domains : '全部领域' if (savedQuery.selectedAreaList) {
selectedArea.value = JSON.parse(savedQuery.selectedAreaList)
} else {
selectedArea.value = savedQuery.domains ? [savedQuery.domains] : ['全部领域']
}
if (savedQuery.selectedDate && Array.isArray(JSON.parse(savedQuery.selectedDate)) && JSON.parse(savedQuery.selectedDate).length) { if (savedQuery.selectedDate && Array.isArray(JSON.parse(savedQuery.selectedDate)) && JSON.parse(savedQuery.selectedDate).length) {
selectedDate.value = '自定义' selectedDate.value = '自定义'
customTime.value = JSON.parse(savedQuery.selectedDate) customTime.value = JSON.parse(savedQuery.selectedDate)
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<div class="header-box"> <div class="header-box">
<div class="header-top"> <div class="header-top">
<SelectBox :placeholder-name="areaPlaceHolder" select-title="科技领域" :select-list="areaList" <SelectBox :placeholder-name="areaPlaceHolder" select-title="科技领域" :select-list="areaList"
:select-name="selectedArea" @update:select-text="handleSelectArea" /> :select-name="selectedArea" :is-multiple="true" @update:select-text="handleSelectArea" />
<SelectBox :placeholder-name="DatePlaceHolder" select-title="发布时间" :select-list="dateList" <SelectBox :placeholder-name="DatePlaceHolder" select-title="发布时间" :select-list="dateList"
:select-name="selectedDate" :custom-time="customTime" @update:select-text="handleSelectDate" :select-name="selectedDate" :custom-time="customTime" @update:select-text="handleSelectDate"
@update:custom-time="handleCustomDate" /> @update:custom-time="handleCustomDate" />
...@@ -322,10 +322,10 @@ const handleChangeTime = value => { ...@@ -322,10 +322,10 @@ const handleChangeTime = value => {
// 激活的标签列表 // 激活的标签列表
const activeTagList = computed(() => { const activeTagList = computed(() => {
const arr = []; const arr = [];
if (selectedArea.value && selectedArea.value !== "全部领域") { if (selectedArea.value && selectedArea.value[0] !== "全部领域") {
arr.push({ arr.push({
tag: "科技领域", tag: "科技领域",
name: selectedArea.value name: selectedArea.value.join('、')
}); });
} }
if (selectedDate.value === "自定义") { if (selectedDate.value === "自定义") {
...@@ -362,7 +362,7 @@ const activeTagList = computed(() => { ...@@ -362,7 +362,7 @@ const activeTagList = computed(() => {
const handleCloseCurTag = (tag, index) => { const handleCloseCurTag = (tag, index) => {
switch (tag.tag) { switch (tag.tag) {
case "科技领域": case "科技领域":
selectedArea.value = "全部领域"; selectedArea.value = ['全部领域']
break; break;
case "发布时间": case "发布时间":
selectedDate.value = ""; selectedDate.value = "";
...@@ -450,7 +450,7 @@ const operationList = ref([ ...@@ -450,7 +450,7 @@ const operationList = ref([
// 科技领域 // 科技领域
const areaPlaceHolder = ref("请选择领域"); const areaPlaceHolder = ref("请选择领域");
const selectedArea = ref("全部领域"); const selectedArea = ref(['全部领域']);
const areaList = ref([ const areaList = ref([
{ {
name: "全部领域", name: "全部领域",
...@@ -517,9 +517,13 @@ const areaList = ref([ ...@@ -517,9 +517,13 @@ const areaList = ref([
id: "其他" id: "其他"
} }
]); ]);
const handleSelectArea = value => { const handleSelectArea = (value) => {
selectedArea.value = value; if (value[value.length - 1] === '全部领域') {
}; selectedArea.value = ['全部领域']
return
}
selectedArea.value = value.length > 1 && value.includes('全部领域') ? value.filter(item => item !== '全部领域') : value;
}
// 提出时间 // 提出时间
const DatePlaceHolder = ref("请选择时间"); const DatePlaceHolder = ref("请选择时间");
...@@ -616,7 +620,7 @@ const isInvolveCn = ref(false); ...@@ -616,7 +620,7 @@ const isInvolveCn = ref(false);
// 清空条件 // 清空条件
const handleClear = () => { const handleClear = () => {
selectedArea.value = "全部领域"; selectedArea.value = ['全部领域']
selectedDate.value = ""; selectedDate.value = "";
customTime.value = []; customTime.value = [];
selectedThinkTank.value = "全部智库"; selectedThinkTank.value = "全部智库";
...@@ -676,7 +680,7 @@ const fetchTableData = async () => { ...@@ -676,7 +680,7 @@ const fetchTableData = async () => {
size: pageSize.value, size: pageSize.value,
// keyword: '', // keyword: '',
type: 4, // type 1= 法案 2= 政令 3 =智库 4=智库报告 5=实体清单 6= 人物 7= 机构 8=新闻 9= 社媒 type: 4, // type 1= 法案 2= 政令 3 =智库 4=智库报告 5=实体清单 6= 人物 7= 机构 8=新闻 9= 社媒
domains: selectedArea.value === "全部领域" ? null : [selectedArea.value], // 领域 domains: selectedArea.value[0] === '全部领域' ? null : selectedArea.value,
proposedDateStart: customTime.value[0] ? customTime.value[0] : null, // 开始日期 proposedDateStart: customTime.value[0] ? customTime.value[0] : null, // 开始日期
proposedDateEnd: customTime.value[1] ? customTime.value[1] : null, // 结束日期 proposedDateEnd: customTime.value[1] ? customTime.value[1] : null, // 结束日期
organizationName: selectedThinkTank.value === "全部智库" ? null : selectedThinkTank.value, // 智库名称 organizationName: selectedThinkTank.value === "全部智库" ? null : selectedThinkTank.value, // 智库名称
...@@ -758,7 +762,7 @@ const fetchAllData = async () => { ...@@ -758,7 +762,7 @@ const fetchAllData = async () => {
size: 9999, size: 9999,
// keyword: '', // keyword: '',
type: 4, // type 1= 法案 2= 政令 3 =智库 4=智库报告 5=实体清单【制裁记录】 6= 人物 7= 机构 8=新闻 9= 社媒 type: 4, // type 1= 法案 2= 政令 3 =智库 4=智库报告 5=实体清单【制裁记录】 6= 人物 7= 机构 8=新闻 9= 社媒
domains: selectedArea.value === "全部领域" ? null : [selectedArea.value], domains: selectedArea.value[0] === '全部领域' ? null : selectedArea.value,
proposedDateStart: customTime.value[0], proposedDateStart: customTime.value[0],
proposedDateEnd: customTime.value[1], proposedDateEnd: customTime.value[1],
organizationName: selectedThinkTank.value === "全部智库" ? null : selectedThinkTank.value, organizationName: selectedThinkTank.value === "全部智库" ? null : selectedThinkTank.value,
...@@ -908,7 +912,11 @@ const handleDownloadCurChartData = () => { ...@@ -908,7 +912,11 @@ const handleDownloadCurChartData = () => {
const initParam = () => { const initParam = () => {
const hasQuery = Object.keys(route.query).length > 0; const hasQuery = Object.keys(route.query).length > 0;
if (hasQuery) { if (hasQuery) {
selectedArea.value = route.query.domains ? route.query.domains : "全部领域"; if (route.query.selectedAreaList) {
selectedArea.value = JSON.parse(route.query.selectedAreaList)
} else {
selectedArea.value = route.query.domains ? [route.query.domains] : ['全部领域']
}
if ( if (
route.query.selectedDate && route.query.selectedDate &&
...@@ -931,7 +939,11 @@ const initParam = () => { ...@@ -931,7 +939,11 @@ const initParam = () => {
} }
} else { } else {
const savedQuery = JSON.parse(sessionStorage.getItem("thinktankRouteQuery") || "{}"); const savedQuery = JSON.parse(sessionStorage.getItem("thinktankRouteQuery") || "{}");
selectedArea.value = savedQuery.domains ? savedQuery.domains : "全部领域"; if (savedQuery.selectedAreaList) {
selectedArea.value = JSON.parse(savedQuery.selectedAreaList)
} else {
selectedArea.value = savedQuery.domains ? [savedQuery.domains] : ['全部领域']
}
if ( if (
savedQuery.selectedDate && savedQuery.selectedDate &&
Array.isArray(JSON.parse(savedQuery.selectedDate)) && Array.isArray(JSON.parse(savedQuery.selectedDate)) &&
......
<template>
<div class="chart-ai-analysis" @mouseenter="handleMouseEnter" @mouseleave="handleMouseLeave">
<!-- 触发按钮 -->
<div class="ai-button-wrapper">
<AiButton />
</div>
<!-- AI 内容面板 -->
<transition name="ai-fade">
<div v-if="isVisible" class="ai-pane-wrapper">
<div class="ai-pane-content">
<!-- 1. Loading 状态 -->
<div v-if="hookInstance.loading" class="ai-loading-text">智能总结生成中...</div>
<!-- 2. 错误状态 -->
<div v-else-if="hookInstance.error" class="ai-error-text">
{{ hookInstance.error }}
</div>
<!-- 3. 成功状态 -->
<div v-else-if="hookInstance.interpretation" class="ai-success-content">
<AiPane :aiContent="hookInstance.interpretation" />
</div>
<!-- 4. 初始空状态 (可选,防止闪烁) -->
<div v-else class="ai-empty-text">暂无数据</div>
</div>
</div>
</transition>
</div>
</template>
<script setup>
import { ref } from "vue";
import AiButton from "@/components/base/Ai/AiButton/index.vue";
import AiPane from "@/components/base/Ai/AiPane/index.vue";
const props = defineProps({
// 接收由 useChartInterpretation() 创建的实例对象
hookInstance: {
type: Object,
required: true
},
// 图表数据 Payload,用于首次请求
payload: {
type: Object,
required: true
}
});
const isVisible = ref(false);
const hasRequested = ref(false);
const handleMouseEnter = () => {
isVisible.value = true;
// 如果还没有请求过数据,则发起请求
if (!hasRequested.value && !props.hookInstance.loading) {
hasRequested.value = true;
// 调用 Hook 中的 interpret 方法
props.hookInstance.interpret(props.payload);
}
};
const handleMouseLeave = () => {
isVisible.value = false;
};
</script>
<style lang="scss" scoped>
.chart-ai-analysis {
position: absolute;
right: 0px;
bottom: 15px;
z-index: 999;
width: auto;
height: auto;
.ai-button-wrapper {
display: flex;
justify-content: flex-end;
}
.ai-pane-wrapper {
position: absolute;
bottom: 0;
right: 0;
width: 100%;
// 确保面板出现在按钮上方或覆盖区域,根据原有 CSS 调整
// 原有 .ai-pane:hover 逻辑是宽度变宽,这里我们直接显示完整面板
background: #fff;
border-radius: 4px;
box-shadow: 0 -2px 12px rgba(0, 0, 0, 0.1);
padding: 10px;
box-sizing: border-box;
.ai-pane-content {
min-height: 40px;
.ai-loading-text,
.ai-error-text,
.ai-empty-text {
font-size: 14px;
color: var(--text-primary-50-color);
display: flex;
align-items: center;
justify-content: center;
min-height: 40px;
}
.ai-error-text {
color: var(--color-red-100);
}
}
}
}
// 复用原有的淡入淡出动画
.ai-fade-enter-active,
.ai-fade-leave-active {
transition: opacity 0.3s ease;
}
.ai-fade-enter-from,
.ai-fade-leave-to {
opacity: 0;
}
</style>
...@@ -43,8 +43,8 @@ defineProps({ ...@@ -43,8 +43,8 @@ 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: $base-font-family; font-family: "Microsoft YaHei";
font-weight: bold; font-weight: 700;
margin-left: 20px; margin-left: 20px;
white-space: nowrap; white-space: nowrap;
} }
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
<div class="info-row"> <div class="info-row">
<div class="label">发布机构:</div> <div class="label">发布机构:</div>
<div class="value link"> <div class="value link">
<img :src="title" alt="" class="icon" /> <img :src="formattedData.postOrgLogoUrl || title" alt="" class="icon" />
<span @click="handleClickDp">{{ formattedData.postOrgName }} ></span> <span @click="handleClickDp">{{ formattedData.postOrgName }} ></span>
</div> </div>
</div> </div>
...@@ -45,15 +45,22 @@ ...@@ -45,15 +45,22 @@
<div class="left-top-content"> <div class="left-top-content">
<div class="content-title">制裁实体分布:</div> <div class="content-title">制裁实体分布:</div>
<div class="distribution-list"> <div class="distribution-list">
<div class="list-item" v-for="(item, index) in entityDistribution" :key="index" <div
@click="handleToDataLibrary(item)"> class="list-item"
v-for="(item, index) in entityDistribution"
:key="index"
@click="handleToDataLibrary(item)"
>
<img :src="item.imageUrl || flag" alt="" class="flag" /> <img :src="item.imageUrl || flag" alt="" class="flag" />
<div class="country-name">{{ item.name }}</div> <div class="country-name">{{ item.name }}</div>
<div class="progress-bar-container"> <div class="progress-bar-container">
<div class="progress-bar" :style="{ <div
class="progress-bar"
:style="{
width: item.width, width: item.width,
background: item.gradient background: item.gradient
}"></div> }"
></div>
</div> </div>
<div class="count" :class="{ highlight: index === 0 }">{{ item.count }}</div> <div class="count" :class="{ highlight: index === 0 }">{{ item.count }}</div>
</div> </div>
...@@ -96,13 +103,25 @@ ...@@ -96,13 +103,25 @@
</div> </div>
<div class="filter-right"> <div class="filter-right">
<el-checkbox v-model="onlyChina" label="只看中国实体" /> <el-checkbox v-model="onlyChina" label="只看中国实体" />
<el-select v-model="filterField" placeholder="选择领域" style="width: 150px; margin: 0 12px 0 16px"> <el-select
v-model="filterField"
placeholder="选择领域"
style="width: 150px; margin: 0 12px 0 16px"
>
<!-- <el-option label="全部领域" value="" /> --> <!-- <el-option label="全部领域" value="" /> -->
<el-option v-for="item in domainOptions" :key="item.value" :label="item.label" :value="item.value" /> <el-option
v-for="item in domainOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select> </el-select>
<el-input v-model="searchKeyword" placeholder="搜索实体" <el-input
v-model="searchKeyword"
placeholder="搜索实体"
style="width: 150px; border: 1px solid rgba(170, 173, 177, 0.4); border-radius: 5px" style="width: 150px; border: 1px solid rgba(170, 173, 177, 0.4); border-radius: 5px"
:suffix-icon="Search" /> :suffix-icon="Search"
/>
</div> </div>
</div> </div>
<div class="stats-row"> <div class="stats-row">
...@@ -117,14 +136,21 @@ ...@@ -117,14 +136,21 @@
<div class="stats-info"> <div class="stats-info">
<div class="stat-item"> <div class="stat-item">
<span class="dot red"></span> <span class="dot red"></span>
<span class="text">新增 <span class="num red">{{ addCount }}</span> 家 (50%规则涉及<span class="num red">{{ <span class="text"
>新增 <span class="num red">{{ addCount }}</span> 家 (50%规则涉及<span class="num red">{{
addRuleCount addRuleCount
}}</span>家)</span> }}</span
>家)</span
>
</div> </div>
<div class="stat-item"> <div class="stat-item">
<span class="dot green"></span> <span class="dot green"></span>
<span class="text">移除 <span class="num green">{{ removeCount }}</span> 家 (50%规则涉及<span <span class="text"
class="num green">{{ removeRuleCount }}</span>家)</span> >移除 <span class="num green">{{ removeCount }}</span> 家 (50%规则涉及<span
class="num green"
>{{ removeRuleCount }}</span
>家)</span
>
</div> </div>
</div> </div>
</div> </div>
...@@ -156,7 +182,11 @@ ...@@ -156,7 +182,11 @@
>{{ item }}</span >{{ item }}</span
> --> > -->
<div class="domain-box"> <div class="domain-box">
<AreaTag v-for="(domain, index) in scope.row.fields" :key="index" :tagName="domain" /> <AreaTag
v-for="(domain, index) in scope.row.fields"
:key="index"
:tagName="domain"
/>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
...@@ -165,8 +195,11 @@ ...@@ -165,8 +195,11 @@
<el-table-column prop="revenue" label="营收(亿元)" width="110" align="center" /> <el-table-column prop="revenue" label="营收(亿元)" width="110" align="center" />
<el-table-column label="50%规则子企业" width="180" align="center"> <el-table-column label="50%规则子企业" width="180" align="center">
<template #default="scope"> <template #default="scope">
<span v-if="scope.row.subsidiaryCount" class="subsidiary-link" <span
@click="handleSubsidiaryClick(scope.row)"> v-if="scope.row.subsidiaryCount"
class="subsidiary-link"
@click="handleSubsidiaryClick(scope.row)"
>
{{ scope.row.subsidiaryText }} {{ scope.row.subsidiaryText }}
<span class="blue-text">{{ scope.row.subsidiaryCount }}家 ></span> <span class="blue-text">{{ scope.row.subsidiaryCount }}家 ></span>
</span> </span>
...@@ -184,8 +217,12 @@ ...@@ -184,8 +217,12 @@
</div> </div>
</div> </div>
<!-- 50%规则子企业弹框 --> <!-- 50%规则子企业弹框 -->
<RuleSubsidiaryDialog v-model="subsidiaryDialogVisible" :company-name="currentSubsidiaryCompanyName" <RuleSubsidiaryDialog
:total-count="currentSubsidiaryCount" :data-list="currentSubsidiaryList" /> v-model="subsidiaryDialogVisible"
:company-name="currentSubsidiaryCompanyName"
:total-count="currentSubsidiaryCount"
:data-list="currentSubsidiaryList"
/>
</div> </div>
</template> </template>
...@@ -445,7 +482,8 @@ const formattedData = computed(() => { ...@@ -445,7 +482,8 @@ const formattedData = computed(() => {
administrativeOrderId: info.administrativeOrderId ? `No. ${info.administrativeOrderId}` : "", administrativeOrderId: info.administrativeOrderId ? `No. ${info.administrativeOrderId}` : "",
postPersonName: info.postPersonName, postPersonName: info.postPersonName,
domains: info.domainNames, domains: info.domainNames,
avartar: info.postPersonAvatarUrl avartar: info.postPersonAvatarUrl,
postOrgLogoUrl: info.postOrgLogoUrl
}; };
}); });
...@@ -525,23 +563,22 @@ const entityDistribution = ref([ ...@@ -525,23 +563,22 @@ const entityDistribution = ref([
const sanTypeId = ref(""); const sanTypeId = ref("");
// 跳转到数据资源库 // 跳转到数据资源库
const handleToDataLibrary = (item) => { const handleToDataLibrary = item => {
console.log('item', item); console.log("item", item);
const dateStr = formattedData.value.postDate.replace(/(\d{4})(\d{1,2})(\d{1,2})日/, (_, y, m, d) => const dateStr = formattedData.value.postDate.replace(
`${y}-${m.padStart(2, '0')}-${d.padStart(2, '0')}` /(\d{4})(\d{1,2})(\d{1,2})日/,
(_, y, m, d) => `${y}-${m.padStart(2, "0")}-${d.padStart(2, "0")}`
); );
const route = router.resolve({ const route = router.resolve({
path: "/dataLibrary/dataEntityList", path: "/dataLibrary/dataEntityList",
query:{ query: {
selectedDate: JSON.stringify([dateStr,dateStr]), selectedDate: JSON.stringify([dateStr, dateStr]),
selectedCountryId: item.id selectedCountryId: item.id
} }
}); });
window.open(route.href, "_blank"); window.open(route.href, "_blank");
};
}
onMounted(() => { onMounted(() => {
// 获取路由参数中的sanTypeId // 获取路由参数中的sanTypeId
......
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
object-fit: contain; object-fit: contain;
" /> " />
</div> </div>
<div class="translate-text">{{ "显示文" }}</div> <div class="translate-text">{{ "显示文" }}</div>
</div> </div>
<div class="btn" @click="handleDownload"> <div class="btn" @click="handleDownload">
<div class="icon"> <div class="icon">
...@@ -62,13 +62,13 @@ ...@@ -62,13 +62,13 @@
</div> </div>
</div> </div>
<div class="report-box"> <div class="report-box">
<div class="pdf-pane-wrap" v-if="valueSwitch && reportUrlEnWithPage">
<pdf ref="leftPdfRef" :pdfUrl="reportUrlEnWithPage" class="pdf-pane-inner" />
</div>
<div class="pdf-pane-wrap" :class="{ 'is-full': !valueSwitch }" v-if="reportUrlWithPage"> <div class="pdf-pane-wrap" :class="{ 'is-full': !valueSwitch }" v-if="reportUrlWithPage">
<pdf :key="`right-pdf-${valueSwitch ? 'split' : 'full'}`" ref="rightPdfRef" :pdfUrl="reportUrlWithPage" <pdf :key="`right-pdf-${valueSwitch ? 'split' : 'full'}`" ref="rightPdfRef" :pdfUrl="reportUrlWithPage"
class="pdf-pane-inner" /> class="pdf-pane-inner" />
</div> </div>
<div class="pdf-pane-wrap" v-if="valueSwitch && reportUrlEnWithPage">
<pdf ref="leftPdfRef" :pdfUrl="reportUrlEnWithPage" class="pdf-pane-inner" />
</div>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -43,8 +43,8 @@ defineProps({ ...@@ -43,8 +43,8 @@ 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: $base-font-family; font-family: "Microsoft YaHei";
font-weight: bold; font-weight: 700;
margin-left: 20px; margin-left: 20px;
white-space: nowrap; white-space: nowrap;
} }
......
...@@ -234,13 +234,17 @@ ...@@ -234,13 +234,17 @@
<div class="data-origin-icon"> <div class="data-origin-icon">
<img :src="tipsIcon" alt="" /> <img :src="tipsIcon" alt="" />
</div> </div>
<div class="data-origin-text"> <div class="data-origin-text">数据来源:美国财政部海外资产管理办公室官网</div>
美国商务部发布实体清单的频次,数据来源:美国财政部海外资产管理办公室官网
</div>
</div> </div>
<div class="ai-pane"> <div class="ai-pane">
<AiButton /> <!-- <AiButton />
<AiPane :aiContent="entityListReleaseFreqChart.interpretation" /> <AiPane :aiContent="entityListReleaseFreqChart.interpretation" /> -->
<AiButton @mouseenter="handleShowAiPane('entityListReleaseFreqChart')" />
<AiPane
v-if="aiPaneVisible?.entityListReleaseFreqChart"
:aiContent="overviewAiContent.entityListReleaseFreqChart"
@mouseleave="handleHideAiPane('entityListReleaseFreqChart')"
/>
</div> </div>
</div> </div>
<div class="box3-content"> <div class="box3-content">
...@@ -280,13 +284,17 @@ ...@@ -280,13 +284,17 @@
<div class="data-origin-icon"> <div class="data-origin-icon">
<img :src="tipsIcon" alt="" /> <img :src="tipsIcon" alt="" />
</div> </div>
<div class="data-origin-text"> <div class="data-origin-text">数据来源:美国财政部海外资产管理办公室官网</div>
美国商务部发布商业管制清单的频次,数据来源:美国财政部海外资产管理办公室官网
</div>
</div> </div>
<div class="ai-pane"> <div class="ai-pane">
<AiButton /> <!-- <AiButton />
<AiPane :aiContent="commerceControlListReleaseFreqChart.interpretation" /> <AiPane :aiContent="commerceControlListReleaseFreqChart.interpretation" /> -->
<AiButton @mouseenter="handleShowAiPane('commerceControlListReleaseFreqChart')" />
<AiPane
v-if="aiPaneVisible?.commerceControlListReleaseFreqChart"
:aiContent="overviewAiContent.commerceControlListReleaseFreqChart"
@mouseleave="handleHideAiPane('commerceControlListReleaseFreqChart')"
/>
</div> </div>
</div> </div>
<div class="box3-content" style="display: none"> <div class="box3-content" style="display: none">
...@@ -339,13 +347,13 @@ ...@@ -339,13 +347,13 @@
<div class="data-origin-icon"> <div class="data-origin-icon">
<img :src="tipsIcon" alt="" /> <img :src="tipsIcon" alt="" />
</div> </div>
<div class="data-origin-text"> <div class="data-origin-text">数据来源:美国财政部海外资产管理办公室官网</div>
进入SDN清单的中国实体领域分布情况,数据来源:美国财政部海外资产管理办公室官网
</div>
</div> </div>
<div class="ai-pane"> <div class="ai-pane">
<AiButton /> <!-- <AiButton />
<AiPane :aiContent="radarChart.interpretation" /> <AiPane :aiContent="radarChart.interpretation" /> -->
<AiButton @mouseenter="handleShowAiPane('radarChart')" />
<AiPane :aiContent="overviewAiContent.radarChart" @mouseleave="handleHideAiPane('radarChart')" />
</div> </div>
</template> </template>
</custom-container> </custom-container>
...@@ -371,13 +379,17 @@ ...@@ -371,13 +379,17 @@
<div class="data-origin-icon"> <div class="data-origin-icon">
<img :src="tipsIcon" alt="" /> <img :src="tipsIcon" alt="" />
</div> </div>
<div class="data-origin-text"> <div class="data-origin-text">数据来源:美国财政部海外资产管理办公室官网</div>
进入SDN清单的中国实体数量变化趋势,数据来源:美国财政部海外资产管理办公室官网
</div>
</div> </div>
<div class="ai-pane"> <div class="ai-pane">
<AiButton /> <!-- <AiButton />
<AiPane :aiContent="trendChart.interpretation" /> <AiPane :aiContent="trendChart.interpretation" /> -->
<AiButton @mouseenter="handleShowAiPane('trendChart')" />
<AiPane
v-if="aiPaneVisible?.trendChart"
:aiContent="overviewAiContent.trendChart"
@mouseleave="handleHideAiPane('trendChart')"
/>
</div> </div>
</template> </template>
</custom-container> </custom-container>
...@@ -705,6 +717,7 @@ import RiskSignal from "@/components/base/riskSignal/index.vue"; ...@@ -705,6 +717,7 @@ import RiskSignal from "@/components/base/riskSignal/index.vue";
import RiskSignalOverviewDetailDialog from "@/components/base/RiskSignalOverviewDetailDialog/index.vue"; import RiskSignalOverviewDetailDialog from "@/components/base/RiskSignalOverviewDetailDialog/index.vue";
import { onMounted, ref, computed, reactive, shallowRef, watch, nextTick } from "vue"; import { onMounted, ref, computed, reactive, shallowRef, watch, nextTick } from "vue";
import { useContainerScroll } from "@/hooks/useScrollShow"; import { useContainerScroll } from "@/hooks/useScrollShow";
import { getChartAnalysis } from "@/api/aiAnalysis/index";
const homeMainRef = ref(null); const homeMainRef = ref(null);
const { isShow } = useContainerScroll(homeMainRef); const { isShow } = useContainerScroll(homeMainRef);
import * as echarts from "echarts"; import * as echarts from "echarts";
...@@ -1265,7 +1278,8 @@ const fetchRadarData = async checked => { ...@@ -1265,7 +1278,8 @@ const fetchRadarData = async checked => {
}; };
}); });
console.log("图例 =>", radarOption.value); console.log("图例 =>", radarOption.value);
radarChart.interpret({ type: "雷达图", name: "实体清单领域分布情况", data: data }); radarChartData.value = data;
// radarChart.interpret({ type: "雷达图", name: "实体清单领域分布情况", data: data });
} }
} catch (error) { } catch (error) {
console.error("获取雷达图数据失败:", error); console.error("获取雷达图数据失败:", error);
...@@ -1824,6 +1838,128 @@ const handleToDataLibrary = item => { ...@@ -1824,6 +1838,128 @@ const handleToDataLibrary = item => {
window.open(route.href, "_blank"); window.open(route.href, "_blank");
}; };
const requestAiPaneContent = async key => {
if (!key || aiPaneLoading.value[key] || aiPaneFetched.value[key]) return;
aiPaneLoading.value = { ...aiPaneLoading.value, [key]: true };
overviewAiContent.value = { ...overviewAiContent.value, [key]: "智能总结生成中..." };
try {
const payload = buildAiChartPayload(key);
const res = await getChartAnalysis(
{ text: JSON.stringify(payload) },
{
onChunk: chunk => {
const current = overviewAiContent.value[key];
const base = current === "智能总结生成中..." ? "" : current;
overviewAiContent.value = {
...overviewAiContent.value,
[key]: base + chunk
};
}
}
);
const list = res?.data;
const first = Array.isArray(list) ? list[0] : null;
const interpretation = first?.解读 || first?.["解读"];
// 流式已渲染过内容,最终用解析出的解读覆盖(保证显示格式统一)
if (interpretation) {
overviewAiContent.value = {
...overviewAiContent.value,
[key]: interpretation
};
}
aiPaneFetched.value = { ...aiPaneFetched.value, [key]: true };
} catch (error) {
console.error("获取图表解读失败", error);
overviewAiContent.value = { ...overviewAiContent.value, [key]: "智能总结生成失败" };
} finally {
aiPaneLoading.value = { ...aiPaneLoading.value, [key]: false };
}
};
const trendChartData = ref([]);
const radarChartData = ref([]);
const entityListReleaseFreqChartData = ref([]);
const commerceControlListReleaseFreqChartData = ref([]);
const aiPaneVisible = ref({
trendChart: false,
radarChart: false,
entityListReleaseFreqChart: false,
commerceControlListReleaseFreqChart: false
});
const overviewAiContent = ref({
trendChart: "智能总结生成中...",
radarChart: "智能总结生成中...",
entityListReleaseFreqChart: "智能总结生成中...",
commerceControlListReleaseFreqChart: "智能总结生成中..."
});
const aiPaneFetched = ref({
trendChart: false,
radarChart: false,
entityListReleaseFreqChart: false,
commerceControlListReleaseFreqChart: false
});
const aiPaneLoading = ref({
trendChart: false,
radarChart: false,
entityListReleaseFreqChart: false,
commerceControlListReleaseFreqChart: false
});
const chartLoading = ref({
trendChart: false,
radarChart: false,
entityListReleaseFreqChart: false,
commerceControlListReleaseFreqChart: false
});
const buildAiChartPayload = key => {
if (key === "trendChart") {
return { type: "柱状图", name: "制裁清单数量增长趋势", data: trendChartData.value };
}
if (key === "radarChart") {
return { type: "雷达图", name: "实体清单领域分布情况", data: radarChartData.value };
}
if (key === "entityListReleaseFreqChart") {
return {
type: "柱状图",
name: "美国商务部发布实体清单的频次",
data: entityListReleaseFreqChartData.value
};
}
if (key === "commerceControlListReleaseFreqChart") {
return {
type: "柱状图",
name: "美国商务部发布商业管制清单的频次",
data: commerceControlListReleaseFreqChartData.value
};
}
return { type: "", name: "", data: [] };
};
const handleShowAiPane = key => {
aiPaneVisible.value = {
...aiPaneVisible.value,
[key]: true
};
requestAiPaneContent(key);
};
const handleHideAiPane = key => {
aiPaneVisible.value = {
...aiPaneVisible.value,
[key]: false
};
};
onMounted(async () => { onMounted(async () => {
console.log("finance 页面 mounted"); console.log("finance 页面 mounted");
try { try {
...@@ -1886,11 +2022,12 @@ onMounted(async () => { ...@@ -1886,11 +2022,12 @@ onMounted(async () => {
await fetchRadarData(domainChecked.value); await fetchRadarData(domainChecked.value);
// 获取出口管制制裁措施 // 获取出口管制制裁措施
await fetchSanctionList(); await fetchSanctionList();
entityListReleaseFreqChart.interpret({ entityListReleaseFreqChartData.value = entityListReleaseFreq.value;
type: "柱状图", // entityListReleaseFreqChart.interpret({
name: "美国商务部发布实体清单的频次", // type: "柱状图",
data: entityListReleaseFreq.value // name: "美国商务部发布实体清单的频次",
}); // data: entityListReleaseFreq.value
// });
commerceControlListReleaseFreq.value = _.map(cclList1, item => { commerceControlListReleaseFreq.value = _.map(cclList1, item => {
return { return {
year: item.year, year: item.year,
...@@ -1899,11 +2036,12 @@ onMounted(async () => { ...@@ -1899,11 +2036,12 @@ onMounted(async () => {
tags: item.domain tags: item.domain
}; };
}); });
commerceControlListReleaseFreqChart.interpret({ commerceControlListReleaseFreqChartData.value = commerceControlListReleaseFreq.value;
type: "柱状图", // commerceControlListReleaseFreqChart.interpret({
name: "美国商务部发布商业管制清单的频次", // type: "柱状图",
data: commerceControlListReleaseFreq.value // name: "美国商务部发布商业管制清单的频次",
}); // data: commerceControlListReleaseFreq.value
// });
} catch (err) { } catch (err) {
console.log("此处报错?"); console.log("此处报错?");
console.log(err); console.log(err);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
<div class="info-row"> <div class="info-row">
<div class="label">发布机构:</div> <div class="label">发布机构:</div>
<div class="value link"> <div class="value link">
<img :src="title" alt="" class="icon" /> <img :src="formattedData.postOrgLogoUrl || title" alt="" class="icon" />
<span @click="handleClickDp">{{ formattedData.postOrgName }} ></span> <span @click="handleClickDp">{{ formattedData.postOrgName }} ></span>
</div> </div>
</div> </div>
...@@ -46,17 +46,24 @@ ...@@ -46,17 +46,24 @@
<div class="left-top-content"> <div class="left-top-content">
<div class="content-title">制裁实体分布:</div> <div class="content-title">制裁实体分布:</div>
<div class="distribution-list"> <div class="distribution-list">
<div class="list-item" v-for="(item, index) in entityDistribution" :key="index" <div
@click="handleToDataLibrary(item)"> class="list-item"
v-for="(item, index) in entityDistribution"
:key="index"
@click="handleToDataLibrary(item)"
>
<img :src="item.imageUrl || flag" alt="" class="flag" /> <img :src="item.imageUrl || flag" alt="" class="flag" />
<div class="country-name">{{ item.name }}</div> <div class="country-name">{{ item.name }}</div>
<div class="progress-bar-container"> <div class="progress-bar-container">
<div class="progress-bar" :style="{ <div
class="progress-bar"
:style="{
width: item.width, width: item.width,
background: item.gradient background: item.gradient
}"></div> }"
></div>
</div> </div>
<div class="count" :class="{ highlight: index === 0 }">{{ item.count }}</div> <div class="count" :class="{ highlight: item.name === '中国' }">{{ item.count }}</div>
</div> </div>
</div> </div>
</div> </div>
...@@ -97,13 +104,25 @@ ...@@ -97,13 +104,25 @@
</div> </div>
<div class="filter-right"> <div class="filter-right">
<el-checkbox v-model="onlyChina" label="只看中国实体" /> <el-checkbox v-model="onlyChina" label="只看中国实体" />
<el-select v-model="filterField" placeholder="全部领域" style="width: 150px; margin: 0 12px 0 16px"> <el-select
v-model="filterField"
placeholder="全部领域"
style="width: 150px; margin: 0 12px 0 16px"
>
<el-option label="全部领域" value="" /> <el-option label="全部领域" value="" />
<el-option v-for="item in domainOptions" :key="item.value" :label="item.label" :value="item.value" /> <el-option
v-for="item in domainOptions"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select> </el-select>
<el-input v-model="searchKeyword" placeholder="搜索实体" <el-input
v-model="searchKeyword"
placeholder="搜索实体"
style="width: 150px; border: 1px solid rgba(170, 173, 177, 0.4); border-radius: 5px" style="width: 150px; border: 1px solid rgba(170, 173, 177, 0.4); border-radius: 5px"
:suffix-icon="Search" /> :suffix-icon="Search"
/>
</div> </div>
</div> </div>
<div class="stats-row"> <div class="stats-row">
...@@ -118,14 +137,21 @@ ...@@ -118,14 +137,21 @@
<div class="stats-info"> <div class="stats-info">
<div class="stat-item"> <div class="stat-item">
<span class="dot red"></span> <span class="dot red"></span>
<span class="text">新增 <span class="num red">{{ addCount }}</span> 家 (50%规则涉及<span class="num red">{{ <span class="text"
>新增 <span class="num red">{{ addCount }}</span> 家 (50%规则涉及<span class="num red">{{
addRuleCount addRuleCount
}}</span>家)</span> }}</span
>家)</span
>
</div> </div>
<div class="stat-item"> <div class="stat-item">
<span class="dot green"></span> <span class="dot green"></span>
<span class="text">移除 <span class="num green">{{ removeCount }}</span> 家 (50%规则涉及<span <span class="text"
class="num green">{{ removeRuleCount }}</span>家)</span> >移除 <span class="num green">{{ removeCount }}</span> 家 (50%规则涉及<span
class="num green"
>{{ removeRuleCount }}</span
>家)</span
>
</div> </div>
</div> </div>
</div> </div>
...@@ -157,7 +183,11 @@ ...@@ -157,7 +183,11 @@
>{{ item }}</span >{{ item }}</span
> --> > -->
<div class="domain-box"> <div class="domain-box">
<AreaTag v-for="(domain, index) in scope.row.fields" :key="index" :tagName="domain" /> <AreaTag
v-for="(domain, index) in scope.row.fields"
:key="index"
:tagName="domain"
/>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
...@@ -166,20 +196,26 @@ ...@@ -166,20 +196,26 @@
<el-table-column prop="entityTypeId" label="类型" width="120" align="center"> <el-table-column prop="entityTypeId" label="类型" width="120" align="center">
<template #default="scope"> <template #default="scope">
<div style="display: flex; gap: 4px; justify-content: center"> <div style="display: flex; gap: 4px; justify-content: center">
<AreaTag :tagName="scope.row.entityType === 1 <AreaTag
:tagName="
scope.row.entityType === 1
? '个人' ? '个人'
: scope.row.entityType === 2 : scope.row.entityType === 2
? '实体' ? '实体'
: '公司' : '公司'
" /> "
/>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<!-- <el-table-column prop="revenue" label="营收(亿元)" width="110" align="center" /> --> <!-- <el-table-column prop="revenue" label="营收(亿元)" width="110" align="center" /> -->
<el-table-column label="50%规则子企业" width="180" align="center"> <el-table-column label="50%规则子企业" width="180" align="center">
<template #default="scope"> <template #default="scope">
<span v-if="scope.row.subsidiaryCount" class="subsidiary-link" <span
@click="handleSubsidiaryClick(scope.row)"> v-if="scope.row.subsidiaryCount"
class="subsidiary-link"
@click="handleSubsidiaryClick(scope.row)"
>
{{ scope.row.subsidiaryText }} {{ scope.row.subsidiaryText }}
<span class="blue-text">{{ scope.row.subsidiaryCount }}家 ></span> <span class="blue-text">{{ scope.row.subsidiaryCount }}家 ></span>
</span> </span>
...@@ -223,8 +259,12 @@ ...@@ -223,8 +259,12 @@
</div> </div>
</div> </div>
<!-- 50%规则子企业弹框 --> <!-- 50%规则子企业弹框 -->
<RuleSubsidiaryDialog v-model="subsidiaryDialogVisible" :company-name="currentSubsidiaryCompanyName" <RuleSubsidiaryDialog
:total-count="currentSubsidiaryCount" :data-list="currentSubsidiaryList" /> v-model="subsidiaryDialogVisible"
:company-name="currentSubsidiaryCompanyName"
:total-count="currentSubsidiaryCount"
:data-list="currentSubsidiaryList"
/>
</div> </div>
</template> </template>
...@@ -481,7 +521,8 @@ const formattedData = computed(() => { ...@@ -481,7 +521,8 @@ const formattedData = computed(() => {
administrativeOrderId: info.administrativeOrderId ? `No. ${info.administrativeOrderId}` : "", administrativeOrderId: info.administrativeOrderId ? `No. ${info.administrativeOrderId}` : "",
postPersonName: info.postPersonName, postPersonName: info.postPersonName,
domains: info.domainNames, domains: info.domainNames,
avartar: info.postPersonAvatarUrl avartar: info.postPersonAvatarUrl,
postOrgLogoUrl: info.postOrgLogoUrl
}; };
}); });
...@@ -590,10 +631,11 @@ const getReasonHistoryList = async () => { ...@@ -590,10 +631,11 @@ const getReasonHistoryList = async () => {
const sanTypeId = ref(""); const sanTypeId = ref("");
// 跳转到数据资源库 // 跳转到数据资源库
const handleToDataLibrary = (item) => { const handleToDataLibrary = item => {
console.log('item', item); console.log("item", item);
const dateStr = formattedData.value.postDate.replace(/(\d{4})(\d{1,2})(\d{1,2})日/, (_, y, m, d) => const dateStr = formattedData.value.postDate.replace(
`${y}-${m.padStart(2, '0')}-${d.padStart(2, '0')}` /(\d{4})(\d{1,2})(\d{1,2})日/,
(_, y, m, d) => `${y}-${m.padStart(2, "0")}-${d.padStart(2, "0")}`
); );
const route = router.resolve({ const route = router.resolve({
...@@ -604,7 +646,7 @@ const handleToDataLibrary = (item) => { ...@@ -604,7 +646,7 @@ const handleToDataLibrary = (item) => {
} }
}); });
window.open(route.href, "_blank"); window.open(route.href, "_blank");
} };
onMounted(() => { onMounted(() => {
// 获取路由参数中的sanTypeId // 获取路由参数中的sanTypeId
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
</div> </div>
<div class="original-text-btn" @click="handleClickOriginalText"> <div class="original-text-btn" @click="handleClickOriginalText">
<img :src="icon1" alt="" /> <img :src="icon1" alt="" />
<span>实体清单原文</span> <span>SDN清单原文</span>
</div> </div>
<div class="btn3" @click="handleAnalysisClick"> <div class="btn3" @click="handleAnalysisClick">
<div class="icon"> <div class="icon">
......
...@@ -68,7 +68,7 @@ ...@@ -68,7 +68,7 @@
" "
/> />
</div> </div>
<div class="translate-text">{{ "显示文" }}</div> <div class="translate-text">{{ "显示文" }}</div>
</div> </div>
<div class="btn" @click="handleDownload"> <div class="btn" @click="handleDownload">
<div class="icon"> <div class="icon">
...@@ -79,9 +79,6 @@ ...@@ -79,9 +79,6 @@
</div> </div>
</div> </div>
<div class="report-box"> <div class="report-box">
<div class="pdf-pane-wrap" v-if="valueSwitch && reportUrlEnWithPage">
<pdf ref="leftPdfRef" :pdfUrl="reportUrlEnWithPage" class="pdf-pane-inner" />
</div>
<div class="pdf-pane-wrap" :class="{ 'is-full': !valueSwitch }" v-if="reportUrlWithPage"> <div class="pdf-pane-wrap" :class="{ 'is-full': !valueSwitch }" v-if="reportUrlWithPage">
<pdf <pdf
:key="`right-pdf-${valueSwitch ? 'split' : 'full'}`" :key="`right-pdf-${valueSwitch ? 'split' : 'full'}`"
...@@ -90,6 +87,9 @@ ...@@ -90,6 +87,9 @@
class="pdf-pane-inner" class="pdf-pane-inner"
/> />
</div> </div>
<div class="pdf-pane-wrap" v-if="valueSwitch && reportUrlEnWithPage">
<pdf ref="leftPdfRef" :pdfUrl="reportUrlEnWithPage" class="pdf-pane-inner" />
</div>
</div> </div>
</div> </div>
</div> </div>
......
...@@ -75,10 +75,8 @@ const switchTab = name => { ...@@ -75,10 +75,8 @@ const switchTab = name => {
const thinkTank = ref({}); const thinkTank = ref({});
// 获取智库基本信息 // 获取智库基本信息
const handleGetThinkTankSummary = async () => { const handleGetThinkTankSummary = async () => {
const id = getDecodedParams() const id = getDecodedParams()
try { try {
const parmas = { const parmas = {
id: id id: id
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论