提交 466614be authored 作者: 付康's avatar 付康

合并分支 'fk-dev' 到 'pre'

Fk dev 查看合并请求 !287
流水线 #248 已通过 于阶段
in 3 分 23 秒
......@@ -11,3 +11,10 @@ export function search(data) {
data:data
})
}
export function getThinkTankList() {
return request({
method: 'GET',
url: `/temporarySearch/search-info/all-organization-names`,
})
}
\ No newline at end of file
......@@ -246,6 +246,9 @@ const handleToModule = (item, index) => {
window.sessionStorage.setItem('homeActiveTitleIndex', index)
if (index === 1) {
homeActiveTitleIndex.value = index
menuList.value.forEach(val => {
val.active = false
})
item.active = true
router.push({
path: item.path
......
......@@ -11,7 +11,7 @@
`}}
</pre>
<div class="chart-box">
<GraphChart :nodes="nodes" :links="links" layoutType="force">
<GraphChart :nodes="nodes" :links="links" layoutType="none">
</GraphChart>
</div>
</el-col>
......
const getQuarterRange = (quatarNum) => {
const getQuarterRange = (year, quatarNum) => {
const quarters = {
1: ['2025-01-01', '2025-03-31'],
2: ['2025-04-01', '2025-06-30'],
3: ['2025-07-01', '2025-09-30'],
4: ['2025-10-01', '2025-12-31']
1: [year+ '-01-01', year+ '-03-31'],
2: [year+ '-04-01', year+ '-06-30'],
3: [year+ '-07-01', year+ '-09-30'],
4: [year+ '-10-01', year+ '-12-31']
};
return quarters[quatarNum];
......
......@@ -16,68 +16,52 @@ const setChart = (option, chartId, allowClick, selectParam) => {
chart.on('click', function (params) {
switch (selectParam.moduleType) {
case '国会法案':
// 判断点击的是否为饼图的数据项
if (params.componentType === 'series' && params.seriesType === 'pie') {
console.log('点击的扇形名称:', params.name);
if (selectParam.key === '领域') {
if (selectParam.key === 1) {
// console.log('当前点击', selectParam, params.seriesName, params.name);
selectParam.selectedStatus = params.seriesName
selectParam.selectedDate = JSON.stringify(getMonthRange(params.name))
const route = router.resolve({
path: "/dataLibrary/countryBill",
query: selectParam
});
window.open(route.href, "_blank");
return
} else if (selectParam.key === 2) {
selectParam.domains = params.name
if (selectParam.selectedDate.length === 4) {
selectParam.selectedDate = JSON.stringify([selectParam.selectedDate + '-01-01', selectParam.selectedDate + '-12-31'])
}
} else if (selectParam.key === '议院委员会') {
const route = router.resolve({
path: "/dataLibrary/countryBill",
query: selectParam
});
window.open(route.href, "_blank");
return
} else if (selectParam.key === 3) {
if (params.name === '众议院' || params.name === '参议院') {
selectParam.selectedCongress = params.name
selectParam.selectedOrg = ''
selectParam.selectedOrg = '全部委员会'
if (selectParam.selectedDate.length === 4) {
selectParam.selectedDate = JSON.stringify([selectParam.selectedDate + '-01-01', selectParam.selectedDate + '-12-31'])
}
} else {
selectParam.selectedOrg = params.name
selectParam.selectedCongress = ''
selectParam.selectedCongress = '全部议院'
if (selectParam.selectedDate.length === 4) {
selectParam.selectedDate = JSON.stringify([selectParam.selectedDate + '-01-01', selectParam.selectedDate + '-12-31'])
}
}
}
const route = router.resolve({
path: "/dataLibrary/countryBill",
query: selectParam
});
window.open(route.href, "_blank");
} else if (params.componentType === 'series' && params.seriesType === 'bar') {
if (params.name === '已立法') {
selectParam.selectedStatus = 1
} else {
selectParam.selectedStatus = 0
}
if (selectParam.selectedDate.length === 4) {
selectParam.selectedDate = JSON.stringify([selectParam.selectedDate + '-01-01', selectParam.selectedDate + '-12-31'])
}
const route = router.resolve({
path: "/dataLibrary/countryBill",
query: selectParam
});
window.open(route.href, "_blank");
return
} else {
console.log('当前点击', selectParam, params.seriesName, params.name);
if (params.seriesName !== '通过率') {
selectParam.selectedDate = JSON.stringify(getMonthRange(params.name))
if (params.seriesName === '通过法案') {
selectParam.selectedStatus = 1
} else {
selectParam.selectedStatus = null
}
selectParam.selectedStatus = params.name
const route = router.resolve({
path: "/dataLibrary/countryBill",
query: selectParam
});
window.open(route.href, "_blank");
}
}
break
case '政令':
......@@ -89,16 +73,37 @@ const setChart = (option, chartId, allowClick, selectParam) => {
});
window.open(route.href, "_blank");
} else if (params.componentType === 'series' && params.seriesType === 'bar') {
const quatarNum = Number(params.name[params.name.length - 1])
selectParam.selectedDate = JSON.stringify(getQuarterRange(quatarNum))
selectParam.selectedDate = JSON.stringify(getQuarterRange(selectParam.selectedDate, quatarNum))
const route = router.resolve({
path: "/dataLibrary/dataDecree",
query: selectParam
});
window.open(route.href, "_blank");
}
break
case '科技智库报告':
if (selectParam.key === 1) {
selectParam.domains = params.seriesName
const year = params.name.slice(0,4)
const quatarNum = Number(params.name[params.name.length - 1])
selectParam.selectedDate = JSON.stringify(getQuarterRange(year, quatarNum))
const route = router.resolve({
path: "/dataLibrary/dataThinkTank",
query: selectParam
});
window.open(route.href, "_blank");
return
} else if (selectParam.key === 2) {
selectParam.domains = params.name
const route = router.resolve({
path: "/dataLibrary/dataThinkTank",
query: selectParam
});
window.open(route.href, "_blank");
return
}
}
});
......
......@@ -890,7 +890,9 @@ const handleBox5 = async () => {
})[0]?.name
const selectParam = {
moduleType: '国会法案',
domains: domain
key: 1,
domains: domain ? domain : '全部领域',
isInvolveCn: true
}
setChart(box5Chart, "box5Chart", true, selectParam);
}
......@@ -941,8 +943,9 @@ const handleBox7Data = async () => {
const selectParam = {
moduleType: '国会法案',
key: '议院委员会',
selectedDate: box7selectetedTime.value,
key: 3,
selectedDate: box7selectetedTime.value ? JSON.stringify([box7selectetedTime.value + '-01-01', box7selectetedTime.value + '-12-31']) : '',
isInvolveCn: true
}
const box7Chart = getDoublePieChart(data1, data2);
......@@ -1092,10 +1095,10 @@ const handleBox9Data = async () => {
);
const selectParam = {
moduleType: '国会法案',
key: '领域',
selectedDate: box9selectetedTime.value,
selectedStatus: selectedIndex,
isInvolveCn: 1
key: 2,
selectedDate: box9selectetedTime.value ? JSON.stringify([box9selectetedTime.value + '-01-01', box9selectetedTime.value + '-12-31']) : '',
selectedStatus: box9LegislativeStatus.value ? box9LegislativeStatus.value : '全部阶段',
isInvolveCn: true
}
box9ChartInstance = setChart(box9Chart, "box9Chart", true, selectParam);
}
......@@ -1274,9 +1277,9 @@ const handleBox8Data = async () => {
const selectParam = {
moduleType: '国会法案',
key: '所处阶段',
selectedDate: box8selectetedTime.value,
isInvolveCn: 1
key: 4,
selectedDate: box8selectetedTime.value ? JSON.stringify([box8selectetedTime.value + '-01-01', box8selectetedTime.value + '-12-31']) : '',
isInvolveCn: true
}
await nextTick();
......
......@@ -316,7 +316,7 @@ const handleSearch = async () => {
console.log("综合搜索结果", res);
if (res.code === 200 && res.data) {
if (!selectedDomains.value.length) {
domains.value = Object.entries(res.data.aggregations).map(([name, id]) => ({
domains.value = Object.entries(res.data.aggregationsDomain).map(([name, id]) => ({
name,
id,
selected: false
......
......@@ -94,11 +94,11 @@
</div>
</div>
<div class="header-right">
<div class="header-right-item item1">
<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" @click="handleExport">{{ '导出' }}</div>
<div class="text text-tip-1">{{ '导出' }}</div>
</div>
<div class="header-right-item2 item2">
<el-select v-model="curOperation" placeholder="批量操作" style="width: 120px">
......@@ -833,13 +833,12 @@ const fetchTableData = async () => {
}))
}
const curDemensionItem = staticsDemensionList.value.filter(item => {
return item.name === curDemension.value
})[0]
activeChart.value = ''
timer3.value = setTimeout(() => {
activeChart.value = curDemensionItem.chartTypeList[0]
curChartData.value = curDemensionItem.data
......@@ -1040,7 +1039,7 @@ const initParam = () => {
}
isInvolveCn.value = route.query.isInvolveCn ? true : false
if (route.query.selectedStatus) {
selectedStatus.value = route.query.selectedStatus === '1' ? '通过' : '提出'
selectedStatus.value = route.query.selectedStatus
} else {
selectedStatus.value = '全部阶段'
}
......@@ -1061,7 +1060,7 @@ const initParam = () => {
}
isInvolveCn.value = savedQuery.isInvolveCn ? true : false
if (savedQuery.selectedStatus) {
selectedStatus.value = savedQuery.selectedStatus === '1' ? '通过' : '提出'
selectedStatus.value = savedQuery.selectedStatus
} else {
selectedStatus.value = '全部阶段'
}
......@@ -1102,6 +1101,10 @@ const handlePerClick = item => {
// 导出
const handleExport = () => {
if (!selectedCount.value) {
ElMessage.warning('请至少选择一项!')
return
}
console.log(selectedMap.value);
const arr = Array.from(selectedMap.value);
......@@ -1111,7 +1114,7 @@ const handleExport = () => {
const link = document.createElement('a');
link.href = url;
link.download = 'export.json';
link.download = 'bill.json';
link.click();
URL.revokeObjectURL(url);
......
<template>
<div class="input-wrapper">
<div class="input-left text-tip-1">{{ inputTitle + ':' }}</div>
<div class="input-right">
<el-input v-model="inputValue" :placeholder="placeholderName" style="width: 240px" />
</div>
</div>
</template>
<script setup>
import { computed } from 'vue';
const props = defineProps({
inputTitle: {
type: String,
default: ''
},
placeholderName: {
type: String,
default: ''
},
inputName: {
type: String,
default: ''
},
})
const emit = defineEmits(['update:inputText', 'update:customTime'])
const inputValue = computed({
get: () => props.inputName,
set: (value) => emit('update:inputText', value)
})
</script>
<style lang="scss" scoped>
.input-wrapper {
width: 348px;
height: 28px;
display: flex;
justify-content: space-between;
align-items: center;
gap: 8px;
.input-left {
width: 100px;
height: 24px;
color: var(--text-primary-65-color);
}
.input-right {
width: 240px;
display: flex;
gap: 8px;
justify-content: space-between;
:deep(.el-input__wrapper) {
border-radius: 4px;
border: 1px solid var(--bg-black-10);
}
}
}
</style>
\ No newline at end of file
......@@ -101,11 +101,11 @@
</div>
</div>
<div class="header-right">
<div class="header-right-item item1">
<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" @click="handleExport">{{ '导出' }}</div>
<div class="text text-tip-1">{{ '导出' }}</div>
</div>
<div class="header-right-item2 item2">
<el-select v-model="curOperation" placeholder="批量操作" style="width: 120px">
......@@ -137,7 +137,7 @@
<el-table-column label="发布时间" width="120" class-name="date-column">
<template #default="scope">{{ scope.row.date }}</template>
</el-table-column>
<el-table-column label="发布机构" width="180">
<el-table-column label="发布机构">
<template #default="scope">
<span class="person-item text-compact" @click="handlePerClick(scope.row)">{{ scope.row.organizationName
}}</span>
......@@ -396,6 +396,7 @@ const handleCloseCurTag = (tag, index) => {
break
case '发布时间':
selectedDate.value = ''
customTime.value = []
break
case '发布机构':
selectedIns.value = '全部机构'
......@@ -765,6 +766,8 @@ const fetchTableData = async () => {
return item.name === curDemension.value
})[0]
activeChart.value = ''
setTimeout(() => {
activeChart.value = curDemensionItem.chartTypeList[0]
curChartData.value = curDemensionItem.data
......@@ -989,12 +992,12 @@ const initParam = () => {
const handleClickToDetail = (curDecree) => {
console.log('curDecree', curDecree);
window.sessionStorage.setItem("billId", curDecree.id);
window.sessionStorage.setItem("decreeId", curDecree.id);
window.sessionStorage.setItem("curTabName", curDecree.title);
const route = router.resolve({
path: "/decreeLayout",
query: {
billId: curDecree.id
id: curDecree.id
}
});
window.open(route.href, "_blank");
......@@ -1340,4 +1343,6 @@ onMounted(async () => {
// :deep(.el-table__header th:first-child) {
// background-color: #e6f7ff;
// color: #1890ff;
// }</style>
\ No newline at end of file
// }
</style>
\ No newline at end of file
<template>
<div class="countrybill-wrapper">
<div class="header-box">我是美国科技智库</div>
<div class="main-box">
<div class="thinktank-wrapper">
<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="thinkTankPlaceHolder" select-title="发布智库"
:select-list="thinkTankList" :select-name="selectedThinkTank" @update:select-text="handleSelectThinkTank" />
<SelectBox v-if="isFolderAll" :placeholder-name="authorPlaceHolder" select-title="作者" :select-list="authorList"
:select-name="selectedAuthor" @update:select-text="handleSelectAuthor" />
<InputBox input-title="报告名称" :input-name="reportName" @update:input-text="handleInputReportName"
placeholder-name="请输入智库报告名称" />
<div class="check-box">
<div class="check-box-left text-tip-1">
{{ '是否涉华:' }}
</div>
<div class="check-box-right">
<el-checkbox v-model="isInvolveCn" 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">
<div class="icon">
<img src="../assets/icons/download.svg" alt="">
</div>
<div class="text text-tip-1" @click="handleExport">{{ '导出' }}</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="handlePerClick(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 InputBox from '../components/InputBox/index.vue'
import { useRoute } from "vue-router";
import router from '@/router'
// 图表/数据
const isShowChart = ref(true)
import { search, getThinkTankList } from '@/api/comprehensiveSearch'
import { ElMessage } from 'element-plus'
import getDateRange from '@/utils/getDateRange'
import { getDepartmentList } from "@/api/decree/home";
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: []
}
])
// 当前维度下的图表列表
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 (selectedThinkTank.value && selectedThinkTank.value !== '全部智库') {
arr.push(
{
tag: '发布智库',
name: selectedThinkTank.value
}
)
}
if (reportName.value) {
arr.push(
{
tag: '报告名称',
name: reportName.value
}
)
}
if (isInvolveCn.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 '发布智库':
selectedThinkTank.value = '全部智库'
break
case '报告名称':
reportName.value = ''
break
case '是否涉华':
isInvolveCn.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 thinkTankList = ref([
{
name: '全部智库',
id: '全部智库'
},
])
const selectedThinkTank = ref('全部智库')
const thinkTankPlaceHolder = ref('请选择发布智库')
const handleSelectThinkTank = value => {
selectedThinkTank.value = value
}
const handleGetThinkTankList = async () => {
try {
const res = await getThinkTankList();
console.log("智库列表", res);
let arr = res.map(item => {
return {
name: item,
id: item
}
})
thinkTankList.value = [...thinkTankList.value, ...arr]
} catch (error) {
}
}
// 作者
const authorList = ref([
{
name: '全部作者',
id: '全部作者'
},
])
const selectedAuthor = ref('暂无作者信息')
const authorPlaceHolder = ref('请选择发布智库')
const handleSelectAuthor = value => {
selectedAuthor.value = value
}
// 报告名称列表
const reportName = ref('')
const handleInputReportName = (value) => {
reportName.value = value
}
// 是否涉华
const isInvolveCn = ref(false)
// 清空条件
const handleClear = () => {
selectedArea.value = '全部领域'
selectedDate.value = ''
customTime.value = []
selectedThinkTank.value = '全部智库'
reportName.value = ''
isInvolveCn.value = false
ElMessage.success('已清空条件!')
}
// 确定
const handleConfirm = () => {
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()
// 调用接口获取数据...
const params = {
page: currentPage.value,
size: pageSize.value,
keyword: '',
type: 4, // 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: selectedThinkTank.value === '全部智库' ? null : selectedThinkTank.value, // 智库名称
reportNameZh: reportName.value? reportName.value : null, // 报告名称
isInvolveCn: isInvolveCn.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
})
} catch (error) {
}
// 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: 4, // 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: selectedThinkTank.value === '全部智库' ? null : selectedThinkTank.value,
reportNameZh: reportName.value? reportName.value : null,
isInvolveCn: isInvolveCn.value ? 'Y' : 'N',
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)
}
selectedThinkTank.value = route.query.orgnizationName ? route.query.orgnizationName : '全部智库'
isInvolveCn.value = route.query.isInvolveCn ? true : false
reportName.value = route.query.reportName ? route.query.reportName : ''
const query = route.query;
if (Object.keys(query).length > 0) {
sessionStorage.setItem('thinktankRouteQuery', JSON.stringify(query));
}
} else {
const savedQuery = JSON.parse(sessionStorage.getItem('thinktankRouteQuery') || '{}');
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)
}
isInvolveCn.value = savedQuery.isInvolveCn ? true : false
reportName.value = savedQuery.reportName ? savedQuery.reportName : ''
}
}
// 跳转政令详情
const handleClickToDetail = (curDecree) => {
console.log('curDecree', curDecree);
window.sessionStorage.setItem("billId", curDecree.id);
window.sessionStorage.setItem("curTabName", curDecree.title);
const route = router.resolve({
path: "/decreeLayout",
query: {
billId: curDecree.id
}
});
window.open(route.href, "_blank");
};
// 跳转人物详情
const handlePerClick = item => {
window.sessionStorage.setItem("curTabName", item.sponsorPersonName);
const route = router.resolve({
path: "/characterPage",
query: {
type: 2,
personId: item.personId
}
});
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 () => {
handleGetThinkTankList()
initParam()
// 初始化
await fetchTableData()
})
</script>
<style lang="scss" scoped>
.countrybill-wrapper {
.thinktank-wrapper {
width: 1600px;
height: 968px;
overflow: hidden;
overflow-y: auto;
.headere-box {
width: 1568px;
......@@ -44,19 +1023,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 +1103,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);
}
.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>
......@@ -298,7 +298,8 @@
</div>
<div class="box8-main">
<div class="box8-main-item">
<div class="box8-item" v-for="(item, index) in box8Data" :key="index">
<div class="box8-item" v-for="(item, index) in box8Data" :key="index"
@click="handleBox8ToDataLibrary(item)">
<div class="item-left"
:class="{ itemBold1: index === 0, itemBold2: index === 1, itemBold3: index === 2 }">
{{ index + 1 }}
......@@ -1001,8 +1002,14 @@ const renderBox5Chart = () => {
if (!chartInput.title.length || !chartInput.data.length) {
return;
}
const selectParam = {
moduleType: '科技智库报告',
key: 1,
}
const box5Chart = getMultiLineChart(chartInput);
setChart(box5Chart, "box5Chart");
setChart(box5Chart, "box5Chart", true, selectParam);
};
const handleBox5AreaChange = () => {
......@@ -1318,8 +1325,14 @@ const renderBox6Chart = () => {
if (!pieData.length) {
return;
}
const selectParam = {
moduleType: '科技智库报告',
key: 2,
selectedDate: JSON.stringify([box6selectetedYear.value + '-01-01', box6selectetedYear.value + '-12-31']),
orgnizationName: box6selectetedTank.value,
}
const box6Chart = getPieChart(pieData);
setChart(box6Chart, "box6Chart");
setChart(box6Chart, "box6Chart", true, selectParam);
};
const handleBox6AreaChange = () => {
......@@ -1580,6 +1593,19 @@ const handleGetThinkTankHot = async date => {
}
};
const handleBox8ToDataLibrary = (item) => {
console.log('item', item);
const selectParam = {
reportName: item.clause
}
const route = router.resolve({
path: "/dataLibrary/dataThinkTank",
query: selectParam
});
window.open(route.href, "_blank");
}
// 资源库
const categoryList = ref(["智库报告", "调查项目", "国会听证会", "政策建议"]);
const activeCate = ref("智库报告");
......@@ -3958,6 +3984,16 @@ onMounted(async () => {
width: 452px;
height: 24px;
display: flex;
cursor: pointer;
&:hover {
.item-center {
color: var(--color-primary-100) !important;
text-decoration: underline;
}
}
.item-left {
width: 20px;
......
......@@ -108,7 +108,7 @@ const getMultiLineChart = (data) => {
return {
tooltip: {
trigger: 'axis',
trigger: 'item',
axisPointer: {
type: 'cross',
label: {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论