提交 3f2140f0 authored 作者: coderBryanFu's avatar coderBryanFu

fix:政令、智库box1替换为通用组件

上级 d51dbb5b
......@@ -43,8 +43,6 @@ const handleClickToDetail = () => {
emit('toDetail')
}
</script>
<style lang="scss" scoped>
......@@ -96,6 +94,9 @@ const handleClickToDetail = () => {
font-weight: 400;
line-height: 24px;
cursor: pointer;
&:hover{
font-weight: bold;
}
}
}
......
......@@ -42,7 +42,7 @@
<div class="home-content-center">
<div class="center-top">
<OverviewMainBox class="box1" title="热门法案" @toDetail="handleClickToDetail">
<template #headerIcon>
<template #header-icon>
<img style="width: 100%; height: 100%" src="./assets/images/box1-header-icon.png" alt="" />
</template>
<div class="box1-left" @click="handleSwithCurBill('left')">
......
......@@ -17,7 +17,7 @@
</template>
<script setup>
import {ref} from 'vue'
import { ref } from 'vue'
const props = defineProps({
isShowAll: {
......@@ -83,6 +83,10 @@ const handleConfirm = () => {
padding: 6px 16px;
color: var(--text-primary-65-color);
cursor: pointer;
&:hover {
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
}
}
.confirm {
......@@ -95,6 +99,10 @@ const handleConfirm = () => {
color: var(--bg-white-100);
text-align: center;
cursor: pointer;
&:hover {
box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
}
}
}
</style>
\ No newline at end of file
<template>
<div class="countrybill-wrapper">
<div class="header-box">我是实体清单</div>
<div class="main-box">
<div class="header-box">
<div class="header-top">
<SelectBox :placeholder-name="areaPlaceHolder" select-title="科技领域" :select-list="areaList"
:select-name="selectedArea" @update:select-text="handleSelectArea" />
<SelectBox :placeholder-name="DatePlaceHolder" select-title="制裁时间" :select-list="dateList"
:select-name="selectedDate" :custom-time="customTime" @update:select-text="handleSelectDate"
@update:custom-time="handleCustomDate" />
<SelectBox v-if="isFolderAll" :placeholder-name="countryPlaceHolder" select-title="国家地区"
:select-list="countryList" :select-name="selectedCountry" @update:select-text="handleSelectCountry" />
<SelectBox v-if="isFolderAll" :placeholder-name="provincePlaceHolder" select-title="实体省份"
:select-list="provinceList" :select-name="selectedProvince" @update:select-text="handleSelectProvince" />
<SelectBox v-if="isFolderAll" :placeholder-name="entityTypePlaceHolder" select-title="实体类型"
:select-list="entityTypeList" :select-name="selectedEntityType"
@update:select-text="handleSelectEntityType" />
<div class="check-box">
<div class="check-box-left text-tip-1">
{{ '50%规则:' }}
</div>
<div class="check-box-right">
<el-checkbox v-model="isHalfRule" class="involve-checkbox">
{{ '只看50%规则' }}
</el-checkbox>
</div>
</div>
<div class="check-box">
<div class="check-box-left text-tip-1">
{{ '中国实体:' }}
</div>
<div class="check-box-right">
<el-checkbox v-model="isCnEntityOnly" class="involve-checkbox">
{{ '只看中国实体' }}
</el-checkbox>
</div>
</div>
</div>
<div class="header-footer">
<div class="header-footer-left">
<ActiveTag v-for="tag, index in activeTagList" :key="index" :tagName="tag.name"
@close="handleCloseCurTag(tag, index)" />
</div>
<div class="header-footer-right">
<HeaderBtnBox :isShowAll="isFolderAll" @show-all="handleSwitchFolderAll" @clear="handleClear"
@confirm="handleConfirm" />
</div>
</div>
</div>
<div class="chart-main-box" v-if="isShowChart">
<div class="info-box">
<div class="switch-box" @click="handleSwitchChartData">
<img v-if="!isShowChart" src="@/views/dataLibrary/assets/icons/chart-active.svg" alt="">
<img v-else src="@/views/dataLibrary/assets/icons/data-active.svg" alt="">
<img src="@/views/dataLibrary/assets/icons/chart-active.svg" alt="">
</div>
<div class="num-box text-title-3-bold">
{{ `共 ${totalNum} 条数据` }}
</div>
</div>
<div class="content-box"></div>
<div class="content-box">
<div class="content-header">
<ChartHeader :list="staticsDemensionList" @clickItem="handleClickDemensionItem">
<template #chart-header-right>
<el-select v-model="selectedTime" placeholder="选择时间" style="width: 150px" v-show="curDemension === '制裁时间'"
@change="handleChangeTime">
<el-option v-for="item in timeList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</template>
</ChartHeader>
</div>
<div class="content-main">
<ChartContainer :chartTitle="curChartTitle" :chartTypeList="curChartTypeList"
@clickChartItem="handleSwitchActiveChart" @download="handleDownloadCurChartData">
<template #chart-box>
<LineChart v-if="activeChart === '折线图'" :lineChartData="curChartData" />
<BarChart v-if="activeChart === '柱状图'" :barChartData="curChartData" />
<PieChart v-if="activeChart === '饼状图'" :pieChartData="curChartData" />
<RaderChart v-if="activeChart === '雷达图'" :radarChartData="curChartData" />
</template>
</ChartContainer>
</div>
</div>
</div>
<div class="data-main-box" v-else>
<div class="data-main-box-header">
<div class="switch-box" @click="handleSwitchChartData">
<img src="@/views/dataLibrary/assets/icons/data-active.svg" alt="">
</div>
<div class="num-box text-title-3-bold">
{{ `共 ${totalNum} 条数据` }}
</div>
</div>
<div class="data-main-box-main">
<div class="data-main-box-main-header">
<div class="header-left">
<div class="header-left-item1">
<el-checkbox v-model="isSelectedAll" label="全选" @change="handleSelectAllChange" size="large" />
</div>
<div class="header-left-item2 text-tip-1">{{ `已选择${selectedCount}项` }}</div>
<div class="header-left-item2 text-tip-1 cancel" @click="handleClearAll" v-show="selectedCount">{{ '取消' }}
<div class="header-left-item3 text-tip-1" v-if="isShowAllDataMaxLengthTip">{{ `(当前最大选择不能超过1万条!)` }}</div>
</div>
</div>
<div class="header-right">
<div class="header-right-item item1" @click="handleExport">
<div class="icon">
<img src="../../assets/icons/download.svg" alt="">
</div>
<div class="text text-tip-1">{{ '导出' }}</div>
</div>
<div class="header-right-item2 item2">
<el-select v-model="curOperation" placeholder="批量操作" style="width: 120px">
<el-option v-for="item in operationList" :key="item.id" :label="item.name" :value="item.id" />
</el-select>
</div>
<div class="header-right-item3 item3">
<el-select v-model="isSort" placeholder="制裁时间" style="width: 166px" @change="handlePxChange">
<template #prefix>
<div style="display: flex; align-items: center; height: 100%">
<img src="../../assets/icons/desc-icon.svg" style="width: 14px; height: 14px" />
</div>
</template>
<el-option v-for="item in releaseTimeList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
</div>
</div>
<div class="data-main-box-main-content" v-loading="loading" element-loading-text="数据加载中,请稍候...">
<el-table ref="tableRef" :data="tableData" row-key="id" @selection-change="handleSelectionChange"
@select="handleSelect" @select-all="handleSelectAll" style="width: 100%" :row-style="{ height: '52px' }">
<el-table-column type="selection" width="40" />
<el-table-column label="实体名称" width="720">
<template #default="scope">
<span class="title-item text-compact-bold" @click="handleClickToDetail(scope.row)">{{
scope.row.originalTitle
}}</span>
</template>
</el-table-column>
<el-table-column label="制裁时间" width="120" class-name="date-column">
<template #default="scope">{{ scope.row.date }}</template>
</el-table-column>
<el-table-column label="上市地点">
<template #default="scope">
<span class="person-item text-compact" @click="handleOrgClick(scope.row)">{{ scope.row.organizationName
}}</span>
</template>
</el-table-column>
<el-table-column label="涉及领域" width="350" class-name="date-column">
<template #default="scope">
<div class="tag-box">
<AreaTag v-for="tag, index in scope.row.domains" :key="index" :tagName="tag" />
</div>
</template>
</el-table-column>
<el-table-column label="实体类型" width="100">
<template #default="scope">{{ scope.row.typeStr }}</template>
</el-table-column>
</el-table>
</div>
</div>
<div class="data-main-box-footer">
<el-pagination background layout="prev, pager, next" :total="totalNum" v-model:current-page="currentPage"
:page-size="pageSize" @current-change="handleCurrentChange" />
</div>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
import { ref, computed, watch, onMounted, nextTick } from 'vue'
import ChartContainer from '../../components/ChartContainer/index.vue'
import ChartHeader from '../../components/ChartHeader/index.vue'
import ActiveTag from '../../components/ActiveTag/index.vue'
import HeaderBtnBox from '../../components/HeaderBtnBox/index.vue'
import LineChart from '../../components/LineChart/index.vue'
import PieChart from '../../components/PieChart/index.vue'
import BarChart from '../../components/BarChart/index.vue'
import RaderChart from '../../components/RadarChart/idnex.vue'
import SelectBox from '../../components/SelectBox/index.vue'
import { useRoute } from "vue-router";
import router from '@/router'
// 图表/数据
const isShowChart = ref(true)
import { search } from '@/api/comprehensiveSearch'
import { ElMessage } from 'element-plus'
import getDateRange from '@/utils/getDateRange'
const route = useRoute();
// 图表/数据
const isShowChart = ref(false)
// 点击切换数据/图表
const handleSwitchChartData = () => {
isShowChart.value = !isShowChart.value
if (isShowChart.value) {
const curDemensionItem = staticsDemensionList.value.filter(item => {
return item.name === curDemension.value
})[0]
setTimeout(() => {
activeChart.value = curDemensionItem.chartTypeList[0]
if (curDemension.value === '制裁时间') {
if (selectedTime.value === '按月度统计') {
curChartData.value = curDemensionItem.data
} else if (selectedTime.value === '按季度统计') {
curChartData.value = curDemensionItem.quatarData
} else {
curChartData.value = curDemensionItem.yearData
}
} else {
curChartData.value = curDemensionItem.data
}
})
}
}
// 总计数据
const totalNum = ref(12)
const totalNum = ref(0)
// 统计维度列表
const staticsDemensionList = ref([
{
name: '制裁时间',
active: true,
chartTypeList: ['折线图', '柱状图'],
chartTitle: '实体清单制裁时间变化趋势',
data: {
dataX: [],
dataY: []
},
quatarData: {
dataX: [],
dataY: []
},
yearData: {
dataX: [],
dataY: []
}
},
{
name: '科技领域',
active: false,
chartTypeList: ['饼状图'],
chartTitle: '实体清单科技领域分布',
data: []
},
{
name: '实体类型',
active: false,
chartTypeList: ['饼状图'],
chartTitle: '实体类型分布',
data: []
},
{
name: '实体国家地区',
active: false,
chartTypeList: ['饼状图'],
chartTitle: '实体国家地区分布',
data: []
},
{
name: '实体省份',
active: false,
chartTypeList: ['饼状图'],
chartTitle: '实体省份分布',
data: []
}
])
// 当前维度下的图表列表
const curChartTypeList = computed(() => {
let arr = staticsDemensionList.value.filter(item => item.active)
return arr[0].chartTypeList
})
// 当前图表标题
const curChartTitle = computed(() => {
let arr = staticsDemensionList.value.filter(item => item.active)
return arr[0].chartTitle
})
// 当前维度
const curDemension = ref('制裁时间')
// 点击维度item
const handleClickDemensionItem = (val) => {
activeChart.value = ''
staticsDemensionList.value.forEach(item => {
item.active = false
})
val.active = true
curDemension.value = val.name
setTimeout(() => {
activeChart.value = val.chartTypeList[0]
if (curDemension.value === '制裁时间' && selectedTime.value === '按年度统计') {
curChartData.value = val.yearData
} else if (curDemension.value === '制裁时间' && selectedTime.value === '按季度统计') {
curChartData.value = val.quatarData
} else {
curChartData.value = val.data
}
})
}
// 时间图表 当前选择时间
const selectedTime = ref('按月统计')
// 时间图表-时间列表
const timeList = ref([
{
label: '按年度统计',
value: '按年度统计'
},
{
label: '按季度统计',
value: '按季度统计'
},
{
label: '按月度统计',
value: '按月度统计'
},
])
const handleChangeTime = value => {
let curChart = activeChart.value
activeChart.value = ''
if (value === '按月度统计') {
setTimeout(() => {
activeChart.value = curChart
curChartData.value = staticsDemensionList.value[0].data
})
} else if (value === '按季度统计') {
setTimeout(() => {
activeChart.value = curChart
curChartData.value = staticsDemensionList.value[0].quatarData
})
} else {
setTimeout(() => {
activeChart.value = curChart
curChartData.value = staticsDemensionList.value[0].yearData
})
}
}
// 激活的标签列表
const activeTagList = computed(() => {
const arr = []
if (selectedArea.value && selectedArea.value !== '全部领域') {
arr.push(
{
tag: '科技领域',
name: selectedArea.value
}
)
}
if (selectedDate.value === '自定义') {
arr.push(
{
tag: '制裁时间',
name: customTime.value.join('至')
}
)
}
if (selectedCountry.value && selectedCountry.value !== '全部国家') {
arr.push(
{
tag: '实体国家地区',
name: selectedCountry.value
}
)
}
if (selectedProvince.value && selectedProvince.value !== '全部省份') {
arr.push(
{
tag: '实体省份',
name: selectedProvince.value
}
)
}
if (selectedEntityType.value && selectedEntityType.value !== '全部实体类型') {
arr.push(
{
tag: '实体类型',
name: selectedEntityType.value
}
)
}
if (isHalfRule.value) {
const halfRuleStr = '是50%规则'
arr.push(
{
tag: '50%规则',
name: halfRuleStr
}
)
}
if (isCnEntityOnly.value) {
const involveStr = '只看中国实体'
arr.push(
{
tag: '只看中国实体',
name: involveStr
}
)
}
return arr
})
// 关闭当前标签
const handleCloseCurTag = (tag, index) => {
switch (tag.tag) {
case '科技领域':
selectedArea.value = '全部领域'
break
case '制裁时间':
selectedDate.value = ''
customTime.value = []
break
case '实体国家地区':
selectedCountry.value = '全部国家'
break
case '实体省份':
selectedProvince.value = '全部省份'
break
case '实体类型':
selectedEntityType.value = '全部实体类型'
break
case '50%规则':
isHalfRule.value = false
break
case '只看中国实体':
isCnEntityOnly.value = false
break
}
}
const activeChart = ref('') // 当前激活的图表
// 切换当前图表
const handleSwitchActiveChart = val => {
activeChart.value = val.name
}
// 雷达图数据
const radarChartData = ref({
title: [
{
name: '航空航天',
max: 10
},
{
name: '先进制造',
max: 10
},
{
name: '量子科技',
max: 10
},
{
name: '人工智能',
max: 10
},
{
name: '新材料',
max: 10
},
{
name: '集成电路',
max: 10
},
],
data: [
{
name: "337调查",
value: [10, 5, 2, 8, 5, 7
]
},
{
name: "232调查",
value: [2, 5, 3, 8, 10, 2]
},
{
name: "301调查",
value: [5, 8, 2, 9, 1, 5]
}
]
}
)
// 数据- 是否全选
const isSelectedAll = ref(false)
// 批量操作-当前操作
const curOperation = ref('')
const operationList = ref([
{
name: 'aaa',
id: 'aaa'
},
{
name: 'bbb',
id: 'bbb'
},
{
name: 'ccc',
id: 'ccc'
},
])
// 科技领域
const areaPlaceHolder = ref('请选择领域')
const selectedArea = ref('全部领域')
const areaList = ref([
{
name: '全部领域',
id: '全部领域'
},
{
name: '人工智能',
id: '人工智能'
},
{
name: '生物科技',
id: '生物科技'
},
{
name: '新一代通信网络',
id: '新一代通信网络'
},
{
name: '量子科技',
id: '量子科技'
},
{
name: '新能源',
id: '新能源'
},
{
name: '集成电路',
id: '集成电路'
},
{
name: '海洋',
id: '海洋'
},
{
name: '先进制造',
id: '先进制造'
},
{
name: '新材料',
id: '新材料'
},
{
name: '航空航天',
id: '航空航天'
},
{
name: '太空',
id: '太空'
},
{
name: '深海',
id: '深海'
},
{
name: '极地',
id: '极地'
},
{
name: '核',
id: '核'
},
{
name: '其他',
id: '其他'
},
])
const handleSelectArea = (value) => {
selectedArea.value = value
}
// 制裁时间
const DatePlaceHolder = ref('请选择时间')
const selectedDate = ref('')
const dateList = ref([
{
name: '自定义',
id: '自定义'
},
{
name: '近一年',
id: '近一年'
},
{
name: '近半年',
id: '近半年'
},
{
name: '近三月',
id: '近三月'
},
{
name: '近一月',
id: '近一月'
}
])
const customTime = ref([]) // 自定义时间
const handleCustomDate = value => {
customTime.value = value
}
const handleSelectDate = (value) => {
selectedDate.value = value
if (selectedDate.value !== '自定义') {
customTime.value = getDateRange(selectedDate.value)
}
}
// 实体国家地区
const countryList = ref([
{
name: '全部国家',
id: '全部国家'
},
])
const selectedCountry = ref('全部国家')
const countryPlaceHolder = ref('请选择实体国家')
const handleSelectCountry = value => {
selectedCountry.value = value
}
// 实体省份(仅支持中国省份)
const provinceList = ref([
{
name: '全部省份',
id: '全部省份',
}
])
const selectedProvince = ref('全部省份')
const provincePlaceHolder = ref('请选择发布机构')
const handleSelectProvince = value => {
selectedProvince.value = value
}
// 实体类型列表
const entityTypeList = ref([
{
name: '全部实体类型',
id: '全部实体类型'
}
])
const selectedEntityType = ref('全部实体类型')
const entityTypePlaceHolder = ref('请选择实体类型')
const handleSelectEntityType = value => {
selectedEntityType.value = value
}
// 是否50%规则
const isHalfRule = ref(false)
// 是否只看中国实体
const isCnEntityOnly = ref(false)
// 清空条件
const handleClear = () => {
selectedArea.value = '全部领域'
selectedDate.value = ''
customTime.value = []
selectedCountry.value = '全部国家'
selectedProvince.value = '全部省份'
selectedEntityType.value = '全部实体类型'
isHalfRule.value = false
isCnEntityOnly.value = false
ElMessage.success('已清空条件!')
}
// 确定
const handleConfirm = () => {
currentPage.value = 1
fetchTableData()
}
// 展开全部 / 收起
const isFolderAll = ref(false)
const handleSwitchFolderAll = () => {
isFolderAll.value = !isFolderAll.value
}
const tableRef = ref(null)
// 表格数据
const tableData = ref([
])
const releaseTimeList = ref([
{
label: "按发布时间倒序",
value: true
},
{
label: "按发布时间升序",
value: false
}
]);
const isSort = ref(true); // true 倒序 false 升序
const handlePxChange = val => {
fetchTableData()
};
const currentPage = ref(1);
const pageSize = ref(10)
// 存储选中的数据(跨页)[citation:3][citation:8]
const selectedMap = ref(new Map()) // 使用 Map 存储,key 为唯一 id
// 计算已选中的条数
const selectedCount = computed(() => selectedMap.value.size)
// 获取当前页表格数据(示例)
const fetchTableData = async () => {
// isSelectedAll.value = false
// selectedMap.value.clear()
loading.value = true
// 调用接口获取数据...
const params = {
page: currentPage.value,
size: pageSize.value,
// keyword: '',
type: 2, // type 1= 法案 2= 政令 3 =智库 4=智库报告 5=实体清单【制裁记录】 6= 人物 7= 机构 8=新闻 9= 社媒
domains: selectedArea.value === '全部领域' ? null : [selectedArea.value],
proposedDateStart: customTime.value[0] ? customTime.value[0] : null,
proposedDateEnd: customTime.value[1] ? customTime.value[1] : null,
organizationName: selectedCountry.value === '全部国家' ? null : selectedCountry.value,
decreeType: selectedEntityType.value === '全部实体类型' ? null : selectedEntityType.value,
isHalfRule: isHalfRule.value ? 'Y' : null,
isTechRelated: isCnEntityOnly.value ? 'Y' : null,
sort: isSort.value ? 0 : 1 // 0 先按分数降序 后按时间降序 1 先按分数降序,再按时间升序
}
try {
const res = await search(params)
console.log('搜索结果', res);
if (res.code === 200 && res.data) {
tableData.value = res.data.records
totalNum.value = res.data.total
staticsDemensionList.value[0].data = {
dataX: Object.keys(res.data.aggregationsDate),
dataY: Object.values(res.data.aggregationsDate).map(value => Number(value))
}
staticsDemensionList.value[0].quatarData = {
dataX: Object.keys(res.data.aggregationsQuarter),
dataY: Object.values(res.data.aggregationsQuarter).map(value => Number(value))
}
staticsDemensionList.value[0].yearData = {
dataX: Object.keys(res.data.aggregationsYear),
dataY: Object.values(res.data.aggregationsYear).map(value => Number(value))
}
staticsDemensionList.value[1].data = Object.entries(res.data.aggregationsDomain).map(([key, value]) => ({
name: key,
value: Number(value)
}))
staticsDemensionList.value[2].data = Object.entries(res.data.aggregationsorganizationName).map(([key, value]) => ({
name: key,
value: Number(value)
}))
}
const curDemensionItem = staticsDemensionList.value.filter(item => {
return item.name === curDemension.value
})[0]
activeChart.value = ''
setTimeout(() => {
activeChart.value = curDemensionItem.chartTypeList[0]
curChartData.value = curDemensionItem.data
})
loading.value = false
} catch (error) {
loading.value = false
}
// tableData.value = res.data
// total.value = res.total
// 数据加载后,回显已选中的行
nextTick(() => {
tableData.value.forEach(row => {
if (selectedMap.value.has(row.id)) {
tableRef.value?.toggleRowSelection(row, true)
}
})
})
}
const allData = ref([])
// 获取筛选条件下全部表格数据
const fetchAllData = async () => {
const params = {
page: 1,
size: 9999,
// keyword: '',
type: 2, // type 1= 法案 2= 政令 3 =智库 4=智库报告 5=实体清单【制裁记录】 6= 人物 7= 机构 8=新闻 9= 社媒
domains: selectedArea.value === '全部领域' ? null : [selectedArea.value],
proposedDateStart: customTime.value[0],
proposedDateEnd: customTime.value[1],
organizationName: selectedCountry.value === '全部国家' ? null : selectedCountry.value,
decreeType: selectedEntityType.value === '全部实体类型' ? null : selectedEntityType.value,
isHalfRule: isHalfRule.value ? 'Y' : null,
isTechRelated: isCnEntityOnly.value ? 'Y' : null,
sort: isSort.value ? 0 : 1
}
try {
const res = await search(params)
console.log('搜索结果', res);
if (res.code === 200 && res.data) {
allData.value = res.data.records
}
} catch (error) {
ElMessage.error('加载全部数据出错!')
}
}
// 单选事件
const handleSelect = (selection, row) => {
if (selection.some(item => item.id === row.id)) {
// 选中:添加到 Map
selectedMap.value.set(row.id, row)
} else {
// 取消选中:从 Map 移除
selectedMap.value.delete(row.id)
}
}
// 表格自带 当前页 全选/全不选事件
const handleSelectAll = (selection) => {
if (selection.length > 0) {
// 全选:将当前页所有数据添加到 Map
tableData.value.forEach(row => {
if (!selectedMap.value.has(row.id)) {
selectedMap.value.set(row.id, row)
}
})
} else {
// 全不选:从 Map 中移除当前页的所有数据
tableData.value.forEach(row => {
selectedMap.value.delete(row.id)
})
}
}
// 处理选择变化(用于统计)
const handleSelectionChange = (val) => {
// 这里可以做一些额外的处理,但主要统计使用 selectedMap
console.log('当前页选中数量:', val.length)
}
// 全选当前页按钮
const handleSelectAllPage = () => {
if (tableData.value.length === 0) return
// 检查当前页是否已全选
const currentPageSelected = tableData.value.every(row =>
selectedMap.value.has(row.id)
)
if (currentPageSelected) {
// 已全选,则不动当前页的全选
tableData.value.forEach(row => {
tableRef.value.toggleRowSelection(row, false)
// selectedMap.value.delete(row.id)
})
} else {
// 未全选,则全选当前页
tableData.value.forEach(row => {
tableRef.value.toggleRowSelection(row, true)
if (!selectedMap.value.has(row.id)) {
selectedMap.value.set(row.id, row)
}
})
}
}
// 全选最大1万条提示
const isShowAllDataMaxLengthTip = ref(false)
const loading = ref(false) // 加载数据loading
// 处理 全选(全部数据)
const handleSelectAllChange = async () => {
if (isSelectedAll.value) {
if (totalNum.value > 10000) {
isShowAllDataMaxLengthTip.value = true
}
loading.value = true
await fetchAllData()
handleSelectAllPage()
allData.value.forEach(row => {
if (!selectedMap.value.has(row.id)) {
selectedMap.value.set(row.id, row)
}
})
loading.value = false
} else {
handleClearAll()
}
}
// 清空所有选择
const handleClearAll = () => {
isSelectedAll.value = false
selectedMap.value.clear()
tableRef.value?.clearSelection()
}
// 翻页
const handleCurrentChange = async (val) => {
currentPage.value = val
await fetchTableData()
if (isSelectedAll.value) {
handleSelectAllPage()
}
}
// 监听数据变化,回显选中状态 [citation:4][citation:8]
watch(tableData, () => {
nextTick(() => {
tableData.value.forEach(row => {
if (selectedMap.value.has(row.id)) {
tableRef.value?.toggleRowSelection(row, true)
}
})
})
})
// 当前图表数据
const curChartData = ref(null)
// 下载当前图表数据
const handleDownloadCurChartData = () => {
const jsonStr = JSON.stringify(curChartData.value, null, 2);
const blob = new Blob([jsonStr], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = 'chartData.json';
link.click();
URL.revokeObjectURL(url);
}
// 跳转到当前页 初始化筛选条件
const initParam = () => {
const hasQuery = Object.keys(route.query).length > 0;
if (hasQuery) {
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) {
selectedDate.value = '自定义'
customTime.value = JSON.parse(route.query.selectedDate)
}
selectedCountry.value = route.query.orgnizationName ? route.query.orgnizationName : '全部国家'
isHalfRule.value = route.query.isHalfRule ? true : false
isCnEntityOnly.value = route.query.isCnEntityOnly ? true : false
selectedEntityType.value = route.query.selectedEntityType ? route.query.selectedEntityType : '全部实体类型'
const query = route.query;
if (Object.keys(query).length > 0) {
sessionStorage.setItem('decreeRouteQuery', JSON.stringify(query));
}
} else {
const savedQuery = JSON.parse(sessionStorage.getItem('decreeRouteQuery') || '{}');
selectedArea.value = savedQuery.domains ? savedQuery.domains : '全部领域'
if (savedQuery.selectedDate && Array.isArray(JSON.parse(savedQuery.selectedDate)) && JSON.parse(savedQuery.selectedDate).length) {
selectedDate.value = '自定义'
customTime.value = JSON.parse(savedQuery.selectedDate)
}
isHalfRule.value = savedQuery.isHalfRule ? true : false
isCnEntityOnly.value = savedQuery.isCnEntityOnly ? true : false
selectedEntityType.value = savedQuery.selectedEntityType ? savedQuery.selectedEntityType : '全部实体类型'
}
}
// 跳转政令详情
const handleClickToDetail = (curDecree) => {
console.log('curDecree', curDecree);
window.sessionStorage.setItem("decreeId", curDecree.id);
window.sessionStorage.setItem("curTabName", curDecree.title);
const route = router.resolve({
path: "/decreeLayout",
query: {
id: curDecree.id
}
});
window.open(route.href, "_blank");
};
// 跳转机构详情
const handleOrgClick = item => {
console.log('item', item);
window.sessionStorage.setItem("curTabName", item.organizationName);
const route = router.resolve({
path: "/institution",
query: {
id: item.organizationId
}
});
window.open(route.href, "_blank");
};
// 导出
const handleExport = () => {
if (!selectedCount.value) {
ElMessage.warning('请选择至少一项数据!')
return
}
console.log(selectedMap.value);
const arr = Array.from(selectedMap.value);
const jsonStr = JSON.stringify(arr, null, 2);
const blob = new Blob([jsonStr], { type: 'application/json' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = 'export.json';
link.click();
URL.revokeObjectURL(url);
};
onMounted(async () => {
handleGetDeparmentList()
initParam()
// 初始化
await fetchTableData()
})
</script>
......@@ -35,6 +1060,8 @@ const totalNum = ref(12)
.countrybill-wrapper {
width: 1600px;
height: 968px;
overflow: hidden;
overflow-y: auto;
.headere-box {
width: 1568px;
......@@ -44,19 +1071,53 @@ const totalNum = ref(12)
border: 1px solid var(--bg-black-5);
margin: 16px auto;
}
.header-box {
width: 1568px;
height: 112px;
min-height: 112px;
border-radius: 10px;
background: rgb(255, 255, 255);
border: 1px solid var(--bg-black-5);
margin: 16px auto;
box-sizing: border-box;
padding: 16px 24px;
.header-top {
min-height: 28px;
display: flex;
flex-wrap: wrap;
gap: 12px 42px;
// transition: all ease 1s;
.check-box {
display: flex;
width: 348px;
height: 28px;
align-items: center;
gap: 8px;
.check-box-left {
width: 100px;
color: var(--text-primary-65-color);
}
}
}
.main-box {
.header-footer {
margin-top: 16px;
display: flex;
justify-content: space-between;
.header-footer-left {
display: flex;
justify-content: space-between;
gap: 8px;
}
}
}
.chart-main-box {
.info-box {
margin: 0 auto;
width: 1568px;
......@@ -90,7 +1151,199 @@ const totalNum = ref(12)
border-radius: 10px;
background: rgba(255, 255, 255);
border: 1px solid var(--bg-black-5);
.content-header {
margin: 16px 24px;
width: 1520px;
height: 28px;
}
.content-main {
width: 1520px;
margin: 0 auto;
}
}
}
.data-main-box {
width: 1568px;
min-height: 810px;
border-radius: 10px;
background: var(--bg-white-100);
margin: 0 auto;
margin-bottom: 20px;
overflow: hidden;
.data-main-box-header {
margin: 16px auto;
width: 1520px;
height: 30px;
display: flex;
justify-content: space-between;
.switch-box {
width: 160px;
border-radius: 20px;
border: 1px solid var(--color-primary-100);
height: 30px;
cursor: pointer;
img {
width: 100%;
height: 100%;
}
}
.num-box {
box-sizing: border-box;
padding: 2px 0;
color: var(--color-red-100);
}
}
.data-main-box-main {
width: 1520px;
// height: 633px;
min-height: 680px;
border-radius: 10px;
border: 1px solid var(--bg-black-5);
margin: 0 auto;
.data-main-box-main-header {
height: 48px;
background: var(--bg-black-2);
display: flex;
justify-content: space-between;
.header-left {
margin-left: 16px;
height: 48px;
display: flex;
gap: 16px;
align-items: center;
.header-left-item2 {
color: var(--color-primary-100);
display: flex;
gap: 8px;
}
.header-left-item3 {
color: var(--color-orange-100);
}
.cancel {
cursor: pointer;
}
}
.header-right {
margin-right: 16px;
display: flex;
gap: 8px;
align-items: center;
.header-right-item {
height: 30px;
padding: 5px 16px;
border: 1px solid var(--bg-black-10);
border-radius: 4px;
background: var(--bg-white-100);
cursor: pointer;
}
.item1 {
display: flex;
gap: 2px;
justify-content: center;
align-items: center;
&:hover {
background: var(--color-primary-2);
}
.icon {
width: 16px;
height: 16px;
img {
width: 100%;
height: 100%;
}
}
.text {
color: var(--text-primary-65-color);
}
}
.item2 {}
.item3 {}
}
}
.data-main-box-main-content {}
}
.data-main-box-footer {
margin: 16px auto 0;
height: 40px;
width: 1520px;
display: flex;
align-items: center;
justify-content: flex-end;
}
}
}
.date-column {
background-color: #ecf5ff;
.tag-box {
display: flex;
flex-wrap: wrap;
gap: 8px;
width: 340px;
}
}
.date-column .cell {
color: #409eff !important;
font-weight: 500;
}
.title-item {
color: var(--text-primary-80-color);
cursor: pointer;
&:hover {
color: var(--color-primary-100);
text-decoration: underline;
}
}
.person-item {
color: var(--color-primary-100);
cursor: pointer;
&:hover {
font-weight: bold;
text-decoration: underline;
}
}
:deep(.el-table__header-wrapper) {
// background-color: #f5f7fa;
height: 48px;
}
:deep(.el-table__header th) {
// background-color: #f5f7fa;
color: var(--text-primary-50-color);
font-weight: bold;
}
</style>
\ No newline at end of file
......@@ -36,13 +36,8 @@
</div>
</div>
<div class="sider-second-item-box" v-if="item.isExpanded">
<div
class="sider-second-item text-compact"
:class="{ 'sider-second-item-acitve': val.active }"
v-for="(val, idx) in item.children"
:key="idx"
@click="handleSiderSecondItem(val)"
>
<div class="sider-second-item text-compact" :class="{ 'sider-second-item-acitve': val.active }"
v-for="(val, idx) in item.children" :key="idx" @click="handleSiderSecondItem(val)">
{{ val.name }}
</div>
</div>
......@@ -50,13 +45,8 @@
</div>
<div class="data-library-content">
<div class="tab-box">
<div
class="tab-item"
:class="{ 'tab-item-active': tab.active }"
v-for="(tab, index) in openedTabList"
:key="index"
@click="handleClickTab(tab)"
>
<div class="tab-item" :class="{ 'tab-item-active': tab.active }" v-for="(tab, index) in openedTabList"
:key="index" @click="handleClickTab(tab)">
<div class="text text-tip-1" :class="{ 'text-active': tab.active }">{{ tab.meta.title }}</div>
<el-tooltip content="关闭当前标签" placement="top">
<div class="icon" @click.stop="handleCloseCurTab(tab, index)">
......@@ -163,15 +153,16 @@ const siderList = ref([
active: false
},
{
name: "商业管制清单",
path: "/dataLibrary/dataCommerceControlList",
name: "实体清单事件",
path: "/dataLibrary/dataEntityListEvent",
active: false
},
{
name: "实体清单事件",
path: "/dataLibrary/dataEntityListEvent",
name: "商业管制清单",
path: "/dataLibrary/dataCommerceControlList",
active: false
},
{
name: "商业管制清单事件",
path: "/dataLibrary/dataCommerceControlListEvent",
......
......@@ -46,7 +46,6 @@
<template #reference>
<div class="item-total" @click="handleToDataLibrary(item)">{{ item.totalOrderNum }}</div>
</template>
</el-popover>
<el-icon color="var(--color-primary-100)">
<ArrowRightBold />
......@@ -64,7 +63,7 @@
<DivideHeader id="position1" class="divide" :titleText="'最新动态'"></DivideHeader>
<div class="home-main-center">
<div class="center-top">
<div class="box1">
<!-- <div class="box1">
<div class="box1-left" @click="handleSwithCurDecree('left')">
<div class="icon">
<img src="./assets/images/box1-left.svg" alt="" />
......@@ -96,7 +95,6 @@
<img class="img-mock-badge-img" src="./assets/images/badge.png" />
<p class="img-mock-badge-title">行政令</p>
<p class="img-mock-badge-title">{{ item.name }}</p>
<!-- <p class="img-mock-badge-org">The White House</p> -->
</div>
</div>
<div class="box1-main-right">
......@@ -124,7 +122,60 @@
</div>
</el-carousel-item>
</el-carousel>
</div> -->
<OverviewMainBox class="box1" title="最新科技政令" @toDetail="handleClickOrder">
<template #header-icon>
<img style="width: 100%; height: 100%" src="./assets/images/box1-header-icon.png" alt="" />
</template>
<div class="box1-left" @click="handleSwithCurDecree('left')">
<div class="icon">
<img src="./assets/images/box1-left.svg" alt="" />
</div>
</div>
<div class="box1-right" @click="handleSwithCurDecree('right')">
<div class="icon">
<img src="./assets/images/box1-right.svg" alt="" />
</div>
</div>
<el-carousel ref="carouselRef" height="395px" :autoplay="true" :interval="3000" arrow="never"
indicator-position="none">
<el-carousel-item v-for="(item, index) in box1DataList" :key="index">
<div class="box1-main">
<div class="box1-main-left">
<img v-if="item.imageUrl" :src="item.imageUrl" alt="" />
<div v-else class="box1-main-left-img-mock">
<img class="img-mock-badge-img" src="./assets/images/badge.png" />
<p class="img-mock-badge-title">行政令</p>
<p class="img-mock-badge-title">{{ item.name }}</p>
<!-- <p class="img-mock-badge-org">The White House</p> -->
</div>
</div>
<div class="box1-main-right">
<div class="box1-main-right-title">
{{ item.name }}
</div>
<div class="box1-main-right-info">
<AreaTag v-for="(tag, index) in item.industryList" :key="index" :tagName="tag.industryName" />
</div>
<div class="box1-main-right-center">
{{ item.describe }}
</div>
<div class="box1-main-right-footer">
<div class="footer-left">{{ item.postDate }}</div>
<div class="footer-right">
<div class="footer-right-item1">
{{ item.officialUrl }}
</div>
<div class="footer-right-item2">
<img src="./assets/images/open-icon.png" alt="" />
</div>
</div>
</div>
</div>
</div>
</el-carousel-item>
</el-carousel>
</OverviewMainBox>
<RiskSignal :list="warningList" @item-click="onNavigateToDetail" @more-click="handleToMoreRiskSignal"
riskLevel="signalLevel" postDate="signalTime" name="signalTitle">
</RiskSignal>
......
......@@ -67,8 +67,11 @@
{{ "No." + (index + 1) }}
</div> -->
<div class="rank">
<el-popover content="跳转至数据资源库" placement="top">
<template #reference>
<div class=" number" @click="handleToDataLibrary(item)">{{ item.reportNumber }} {{ "篇报告" }}</div>
</template>
</el-popover>
</div>
</div>
<div class="card-title">
......@@ -100,7 +103,7 @@
<div class="home-main-center">
<DivideHeader id="position1" class="divide-header" :titleText="'最新动态'"></DivideHeader>
<div class="center-top">
<div class="box1">
<!-- <div class="box1">
<div class="box1-left" @click="handleSwithCurDecree('left')">
<div class="icon">
<img src="./assets/images/box1-left.svg" alt="" />
......@@ -133,6 +136,53 @@
<div class="title">{{ itemData?.reportName }}</div>
<div class="name">
<div class="logo-title-box">
<div class="logo">
<img :src="itemData?.thinkTankImage" alt="" />
</div>
<div class="title">{{ itemData?.thinkTankName + " · " + "智库报告" }}</div>
</div>
<div class="time">{{ itemData?.reportDate }}</div>
</div>
<div class="content">{{ itemData?.summary }}</div>
<div class="box1-right-footer">
<div class="tag-box">
<AreaTag v-for="(item, index) in itemData?.industryVOList" :key="index"
:tagName="item.industryName">
</AreaTag>
</div>
</div>
</div>
</div>
</el-carousel-item>
</el-carousel>
</div> -->
<OverviewMainBox class="box1" title="智库发布" @toDetail="handleClickToDetail">
<template #header-icon>
<img style="width: 100%; height: 100%" src="./assets/images/box1-header-icon.png" alt="" />
</template>
<div class="box1-left" @click="handleSwithCurDecree('left')">
<div class="icon">
<img src="./assets/images/box1-left.svg" alt="" />
</div>
</div>
<div class="box1-right" @click="handleSwithCurDecree('right')">
<div class="icon">
<img src="./assets/images/box1-right.svg" alt="" />
</div>
</div>
<el-carousel ref="carouselRef" height="395px" :autoplay="true" :interval="3000" arrow="never"
indicator-position="none">
<el-carousel-item v-for="(itemData, index) in box1Data" :key="index">
<div class="box1-main">
<div class="box1-main-left">
<img :src="itemData?.imageUrl" alt="" />
</div>
<div class="box1-main-right">
<div class="title">{{ itemData?.reportName }}</div>
<div class="name">
<div class="logo-title-box">
<div class="logo">
......@@ -157,7 +207,7 @@
</div>
</el-carousel-item>
</el-carousel>
</div>
</OverviewMainBox>
<RiskSignal :list="warningList" @more-click="handleToMoreRiskSignal" postDate="time" name="title"
@item-click="handleClickToDetail" />
</div>
......@@ -369,8 +419,9 @@
<ThinkTankCongressHearingOverview v-else-if="activeCate === '国会听证会'" :key="`congress-${resourceTabResetKey}`"
:hearing-data="hearingData" :research-type-list="areaList" :research-time-list="pubTimeList"
v-model:selectedAreaList="congressSelectedAreaList" v-model:selectedPubTimeList="congressSelectedPubTimeList"
:total="congressTotal" :current-page="congressCurrentPage" @filter-change="handleCongressFilterChange"
v-model:selectedAreaList="congressSelectedAreaList"
v-model:selectedPubTimeList="congressSelectedPubTimeList" :total="congressTotal"
:current-page="congressCurrentPage" @filter-change="handleCongressFilterChange"
@page-change="handleCongressCurrentChange" @report-click="handleToHearingDetail" />
<ThinkTankPolicyAdviceOverview v-else :key="`policy-${resourceTabResetKey}`" :research-type-list="areaList"
......@@ -2194,7 +2245,7 @@ const handleSearch = () => {
// 下钻至数据资源库
const handleToDataLibrary = (item) => {
if(!item.reportNumber) {
if (!item.reportNumber) {
ElMessage.warning('当前智库没有相关报告!')
return
}
......@@ -2811,12 +2862,6 @@ onBeforeUnmount(() => {
.box1 {
width: 1063px;
height: 450px;
box-shadow: 0px 0px 20px 0px rgba(22, 69, 130, 0.1);
background: #fff;
box-sizing: border-box;
border-radius: 10px;
position: relative;
border: 1px solid rgb(234, 236, 238);
.box1-left {
position: absolute;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论