提交 61fe4368 authored 作者: 张伊明's avatar 张伊明

合并分支 'zz-dev' 到 'master'

feat:完善智库主页,增加智库报告分页功能及点击详情图片跳转报告原文功能 查看合并请求 !155
......@@ -222,9 +222,14 @@ export function getThinkTankReportAbstract(params) {
//获取报告主要观点
export function getThinkTankReportContent(params) {
const { id, currentPage, pageSize } = params
return request({
method: 'GET',
url: `/api/thinkTankReport/content/${params}`,
url: `/api/thinkTankReport/content/${id}`,
params: {
currentPage,
pageSize,
}
})
}
......
......@@ -10,23 +10,20 @@
</div>
</div>
<div class="box3-main">
<div class="box3-item" v-for="(news, index) in list" :key="index" @click="handleClickToNewsDetail(news)">
<div class="box3-item" v-for="(news, index) in normalizedList" :key="index"
@click="handleClickToNewsDetail(news)">
<div class="left">
<img
:src="getProxyUrl(news.newsImage) || defaultImg"
alt=""
referrerpolicy="no-referrer"
@error="e => (e.target.src = errImg||News1)"
/>
<img :src="getProxyUrl(news.newsImage) || defaultImg" alt="" referrerpolicy="no-referrer"
@error="e => (e.target.src = errImg || News1)" />
</div>
<div class="right">
<div class="right-top">
<div class="title">{{ news.newsTitle||news.title }}</div>
<div class="title">{{ news.newsTitle || news.title }}</div>
<div class="time">
{{ news.newsDate ? news.newsDate.slice(5) : "" }} {{ news.newsOrg ? "-" + news.newsOrg : "" }}
</div>
</div>
<div class="right-footer">{{ news.newsContent||news.description }}</div>
<div class="right-footer">{{ news.newsContent || news.description }}</div>
</div>
</div>
</div>
......@@ -34,15 +31,21 @@
</template>
<script setup>
import { computed } from "vue";
import router from "@/router/index";
import News1 from "@/assets/images/news1.png"; // 错误图片
import defaultNew from "@/assets/images/default-icon-news.png"; // 默认图片
let { list,errImg,defaultImg } = defineProps({
let { list, newsList, errImg, defaultImg } = defineProps({
list: {
type: Array,
default: () => []
},
// 兼容历史用法:部分页面使用 newsList 作为入参
newsList: {
type: Array,
default: undefined
},
defaultImg: {
type: String,
default: defaultNew
......@@ -53,6 +56,11 @@ let { list,errImg,defaultImg } = defineProps({
}
});
// 统一对外渲染数据源:优先使用 list,其次兼容 newsList
const normalizedList = computed(() => {
return (Array.isArray(list) && list.length ? list : newsList) || [];
});
// 处理图片代理
const getProxyUrl = url => {
if (!url) return "";
......@@ -74,7 +82,7 @@ const handleClickToNewsDetail = news => {
const route = router.resolve({
path: "/newsAnalysis",
query: {
newsId: news.newsId
newsId: news.newsId ?? news.id
}
});
window.open(route.href, "_blank");
......@@ -183,9 +191,11 @@ const handleToMoreNews = () => {
width: 657px;
display: flex;
justify-content: space-between;
&:hover {
text-decoration: underline;
color: var(--color-main-active);
.title {
color: var(--color-main-active);
}
......
......@@ -67,7 +67,7 @@ const handleCollect = () => {
}
const emit = defineEmits(['save','download','collect'])
const emit = defineEmits(['save', 'download', 'collect'])
</script>
......
......@@ -7,7 +7,6 @@ import { ref, onMounted } from 'vue';
import { getNetProfitList, getPersonnelList, getRevenueList } from '@/api/companyPages';
import SanctionsSituation, { LineDataItem } from './SanctionsSituation.vue';
import { l } from 'vite/dist/node/types.d-aGj9QkWt';
// 定义组件属性
......
......@@ -50,14 +50,10 @@
</template>
<script setup>
import NewsList from "@/components/base/NewsList/index.vue";
import NewsList from "@/components/NewsList.vue";
import { ref, onMounted } from "vue";
import router from '@/router'
import { getCoopRestrictionNews, getCoopRestrictionSocial } from '@/api/coopRestriction/coopRestriction'
import CommonPrompt from "../../commonPrompt/index.vue";
import defaultNews from "../../assets/images/default-icon-news.png"
import defaultAvatar from "../../assets/images/default-icon1.png"
import title01 from './assets/title01.png'
import title02 from './assets/title02.png'
import title03 from './assets/title03.png'
......@@ -92,7 +88,7 @@ const getCoopRestrictionSocialData = async () => {
console.error("获取合作限制社交媒体数据失败:", error);
}
};
const leftList = ref([])
// 合作限制-查询新闻资讯接口
const getCoopRestrictionNewsData = async () => {
......@@ -114,7 +110,7 @@ const getCoopRestrictionNewsData = async () => {
};
const leftList = ref([])
const rightList = ref([])
......
......@@ -701,7 +701,7 @@
</template>
<script setup>
import NewsList from "@/components/base/newsList/index.vue";
import NewsList from "@/components/NewsList.vue";
import RiskSignal from "@/components/RiskSignal/RiskSignal.vue";
import { onMounted, ref, computed, reactive, shallowRef, watch, nextTick } from "vue";
import { useContainerScroll } from "@/hooks/useScrollShow";
......
......@@ -9,7 +9,7 @@
</div>
</div> -->
<div class="home-main" ref="containerRef">
<div class="home-top-bg"></div>
<div class="home-top-bg"></div>
<div class="home-main-header">
<div class="home-main-header-center">
<SearchContainer style="margin-bottom: 0; height: fit-content" v-if="containerRef" placeholder="搜索投融资限制政策"
......@@ -477,7 +477,7 @@ import CustomContainer from "@/components/Container/index.vue";
import ClickableCard from "./components/link.vue";
import InfoCard from "./components/info.vue";
import CustomTitle from "./components/title.vue";
import NewsList from "@/components/base/NewsList/index.vue";
import NewsList from "@/components/NewsList.vue";
import trumpAvatar from "@/assets/images/icon-trump.png";
import elongAvatar from "@/assets/images/icon-elong.png";
......@@ -1719,7 +1719,7 @@ onMounted(async () => {
// background: url("./assets/images/background.png");
// background-size: 100% 100%;
.home-top-bg {
.home-top-bg {
background:
url("./assets/images/background.png"),
linear-gradient(180deg, rgba(229, 241, 254, 1) 0%, rgba(246, 251, 255, 0) 30%);
......
......@@ -374,18 +374,13 @@
<script setup>
import RiskSignal from "@/components/base/RiskSignal/index.vue";
import NewsList from "@/components/base/NewsList/index.vue";
import RiskSignal from "@/components/RiskSignal/RiskSignal.vue";
import NewsList from "@/components/NewsList.vue";
import { onMounted, ref, computed } from "vue";
import * as echarts from "echarts";
import router from "@/router";
import DivideHeader from "@/components/DivideHeader.vue";
import scrollToTop from "@/utils/scrollToTop";
import { useContainerScroll } from "@/hooks/useScrollShow";
import getBarChart from "./utils/barChart";
import getPieChart from "./utils/piechart";
import getCalendarHeatChart from "./utils/cleandarHeat";
import EChart from "@/components/Chart/index.vue";
import { pieOption, raderOption } from "./utils/charts";
import {
......
......@@ -436,9 +436,9 @@
</template>
<script setup>
import RiskSignal from "@/components/RiskSignal/RiskSignal.vue";
import { onMounted, ref } from "vue";
import NewsList from "@/components/base/NewsList/index.vue";
import RiskSignal from "@/components/base/RiskSignal/index.vue";
import DivideHeader from "@/components/DivideHeader.vue";
import setChart from "@/utils/setChart";
import router from "@/router";
......@@ -1802,6 +1802,7 @@ onMounted(async () => {
.box1 {
width: 1064px;
height: 450px;
.box1-left {
position: absolute;
left: 0;
......
......@@ -61,7 +61,7 @@
</template>
<script setup>
import NewsList from "@/components/base/NewsList/index.vue";
import NewsList from "@/components/NewsList.vue";
import { ref, onBeforeMount } from "vue";
import router from "@/router"
......
......@@ -53,7 +53,7 @@
</template>
<script setup>
import NewsList from "@/components/base/NewsList/index.vue";
import NewsList from "@/components/NewsList.vue";
import { ref, onMounted } from "vue";
import {
......
......@@ -95,6 +95,7 @@ const handleGetThinkTankReportSummary = async () => {
if (res.code === 200 && res.data) {
reportUrl.value = res.data.reportUrl;
thinkInfo.value = res.data;
console.log(reportUrl.value, 'reportUrl.value')
}
} catch (error) {
console.error("获取报告全局信息error", error);
......
......@@ -57,43 +57,35 @@
</div>
<div class="center">
<div class="title">{{ item.content }}</div>
<div>
<img src="../images/image-open.png" alt="" class="center-image"
@click="handleOpenReportOriginal(item)">
</div>
<!-- <div class="desc">{{ item.econtent }}</div> -->
</div>
<div class="right">
<!-- <div class="tag" v-for="(val, idx) in item.hylyList" :key="idx">
<!-- <div class="right"> -->
<!-- <div class="tag" v-for="(val, idx) in item.hylyList" :key="idx">
{{ val }}
</div>
<div class="tag" v-for="(val, idx) in item.serialNum" :key="idx">
{{ val }}
</div> -->
<AreaTag v-for="(val, idx) in item.hylyList" :key="idx" :tagName="val"></AreaTag>
</div>
<!-- <AreaTag v-for="(val, idx) in item.hylyList" :key="idx" :tagName="val"></AreaTag>
</div> -->
<!-- <div class="more">
<img src="@/assets/icons/open.png" alt="" />
</div> -->
</div>
</div>
<div class="box3-main-footer">
<div class="info"> {{ total }}</div>
<div class="info">{{ total }}条核心论点</div>
<div class="page-box">
<el-pagination :page-size="12" background layout="prev, pager, next" :total="total"
<el-pagination :page-size="10" background layout="prev, pager, next" :total="total"
@current-change="handleCurrentChange" :current-page="currentPage" />
</div>
</div>
</div>
<div class="box3-footer">
<div class="footer-left">
<img src="@/assets/icons/box-footer-left-icon.png" alt="" />
</div>
<div class="footer-center">
{{
`中美经济深度交织,全面脱钩成本高昂且不现实。其核心揭示了三大纽带:生产网络相互依存使强行分离代价巨大;人才双向流动推动创新却成政策博弈焦点;能源领域合作与竞争并存,关乎全球气候治理与经济博弈。报告主张理性竞合,在竞争中找到合作路径。`
}}
</div>
<div class="footer-right">
<img src="@/assets/icons/box-footer-right-icon.png" alt="" />
</div>
</div>
</AnalysisBox>
</div>
</div>
......@@ -240,22 +232,49 @@ const majorOpinions = ref([
]
}
]);
//处理点击详情页事件
const handleOpenReportOriginal = item => {
const route = router.resolve({
name: "ReportOriginal",
params: {
id: router.currentRoute._value.params.id
},
query: {
currentPage: currentPage.value,
pageSize: pageSize.value,
opinionId: item?.id ?? "",
opinionContent: item?.content ?? ""
}
});
window.open(route.href, "_blank");
};
const tabActiveName = ref("报告分析");
const switchTab = name => {
tabActiveName.value = name;
}
// 处理页码改变事件
const currentPage = ref(1);
const pageSize = ref(10);
const total = ref(0)
const handleCurrentChange = page => {
currentPage.value = page;
handleGetThinkDynamicsReport();
handleGetThinkTankReportContent();
};
//获取报告主要观点
const handleGetThinkTankReportContent = async () => {
try {
const res = await getThinkTankReportContent(router.currentRoute._value.params.id);
const params = {
id: router.currentRoute._value.params.id,
currentPage: currentPage.value - 1,
pageSize: pageSize.value,
};
const res = await getThinkTankReportContent(params);
console.log("主要观点", res.data);
if (res.code === 200 && res.data) {
majorOpinions.value = res.data.content;
majorOpinions.value = res.data.content || [];
handleGetBox3AnalysisContent(majorOpinions.value)
total.value = res.data.totalElements
total.value = res.data.totalElements || 0
}
} catch (error) {
console.error("获取主要观点error", error);
......@@ -489,7 +508,7 @@ onMounted(() => {
.box3 {
width: 1103px;
height: 946px;
height: 965px;
// border: 1px solid rgba(234, 236, 238, 1);
// border-radius: 10px;
// box-shadow: 0px 0px 20px 0px rgba(25, 69, 130, 0.1);
......@@ -498,11 +517,11 @@ onMounted(() => {
.box3-main {
width: 1057px;
height: 800px;
margin: 0 auto;
.box3-main-main {
height: 720px;
height: 767px;
overflow: hidden;
.box3-item {
......@@ -541,6 +560,7 @@ onMounted(() => {
.title {
margin-top: 12px;
width: 918px;
// height: 55px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
......@@ -556,6 +576,16 @@ onMounted(() => {
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.center-image {
width: 16px;
height: 24px;
margin-top: 12px;
margin-left: 18px;
}
.desc {
......
......@@ -168,7 +168,12 @@
<div class="item-right">
<div>
<div class="title">{{ item.content }}</div>
<div class="info">{{ item.times }} · {{ item.name }}</div>
<div class="info">
{{ item.times }} · {{ item.name }}
<div class="more" @click="toDetail(item)">
<img src="@/views/thinkTank/ThinkTankDetail/thinkDynamics/images/image open.png" alt="" />
</div>
</div>
<div class="tag-box">
<AreaTag v-for="(tag, idx) in item.tagList" :key="idx" :tagName="tag"></AreaTag>
</div>
......@@ -190,15 +195,13 @@
</div>
</div>
<div>
<div class="more" @click="toDetail(item)">
<img src="@/assets/icons/open.png" alt="" />
</div>
</div>
</div>
</div>
</div>
<div class="right-footer">
<div class="info"> {{ total }} 项</div>
<div class="info">{{ total }}条政策建议</div>
<div class="page-box">
<el-pagination :page-size="12" background layout="prev, pager, next" :total="total"
@current-change="handleCurrentChange" :current-page="currentPage" />
......@@ -269,7 +272,8 @@ const box1Data = ref([
// color: "#D6E4FF"
// }
]);
const relationBillsList = ref([{ billName: "2025《人工智能安全与评估法案》" }])
const relationAdList = ref([{ adName: "2025《人工智能安全与评估法案》" }])
const box1SelectYear = ref("2025");
const box1YearList = ref([
{
......@@ -627,7 +631,12 @@ const handleGetThinkPolicy = async () => {
const res = await getThinkPolicy(parmas);
console.log("智库政策", res);
if (res.code === 200 && res.data) {
policyList.value = res.data.content;
policyList.value = res.data.content.map(item => ({
...item,
relationBillsList: relationBillsList.value,
relationAdList: relationAdList.value
}));
total.value = res.data.totalElements;
}
} catch (error) {
......@@ -663,6 +672,7 @@ onMounted(() => {
margin: 16px 0;
display: flex;
gap: 16px;
.box {
width: 520px;
height: 420px;
......@@ -1170,21 +1180,30 @@ onMounted(() => {
background: rgba(255, 255, 255, 1);
.right-main {
margin: 17px auto;
width: 1209px;
margin-top: 17px;
margin-left: 0;
width: 100%;
box-sizing: border-box;
padding-left: 37px;
padding-right: 0;
max-height: 1540px;
.right-main-item {
// height: 154px;
box-sizing: border-box;
padding-top: 8px;
padding-top: 16px;
padding-bottom: 16px;
margin-left: -37px;
padding-left: 37px;
padding-right: 36px;
width: calc(100% + 37px - 36px);
border-bottom: 1px solid rgba(234, 236, 238, 1);
display: flex;
.item-left {
width: 57px;
height: 77px;
margin-top: 3px;
img {
width: 100%;
......@@ -1201,7 +1220,7 @@ onMounted(() => {
.title {
// height: 24px;
color: rgba(59, 65, 75, 1);
font-family: Microsoft YaHei;
font-family: "Source Han Sans CN";
font-size: 18px;
font-weight: 700;
line-height: 24px;
......@@ -1213,12 +1232,25 @@ onMounted(() => {
margin-top: 7px;
height: 22px;
color: rgba(95, 101, 108, 1);
font-family: Microsoft YaHei;
font-family: "Source Han Sans CN";
font-size: 14px;
font-weight: 400;
line-height: 22px;
letter-spacing: 0px;
text-align: left;
display: flex;
.more {
width: 16px;
height: 16px;
margin-top: 3px;
margin-left: 9px;
img {
width: 100%;
height: 100%;
}
}
}
.tag-box {
......@@ -1248,30 +1280,30 @@ onMounted(() => {
.file {
height: 32px;
padding: 0 8px;
padding: 4px 8px;
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
gap: 12px;
border-radius: 4px;
background: rgba(246, 250, 255, 1);
.type {
height: 22px;
margin-top: 1px;
padding: 0 4px;
border-radius: 4px;
background: rgba(231, 243, 255, 1);
color: rgba(5, 95, 194, 1);
font-family: Microsoft YaHei;
font-family: "Source Han Sans CN";
font-size: 14px;
font-weight: 400;
line-height: 22px;
}
.title {
height: 24px;
color: rgba(5, 95, 194, 1);
font-family: Microsoft YaHei;
font-family: "Source Han Sans CN";
font-size: 16px;
font-weight: 400;
line-height: 24px;
......@@ -1280,12 +1312,16 @@ onMounted(() => {
.more {
width: 20px;
height: 20px;
display: flex;
margin-top: 2px;
img {
.img {
width: 100%;
height: 100%;
}
}
}
}
}
......@@ -1293,21 +1329,32 @@ onMounted(() => {
}
.right-footer {
margin: 0 auto;
width: 1209px;
height: 96px;
height: 86px;
display: flex;
justify-content: space-between;
margin-top: 17px;
.info {
margin-top: 29px;
margin-left: 39px;
color: rgba(132, 136, 142, 1);
font-family: Microsoft YaHei;
font-size: 14px;
height: 19px;
font-weight: 400;
line-height: 18px;
letter-spacing: 0px;
text-align: left;
}
.page-box {
margin-top: 23px;
margin-right: 36px;
height: 32px;
}
}
}
}
......@@ -1319,4 +1366,22 @@ onMounted(() => {
height: 8px !important;
margin-right: 4px;
}
/* PolicyTracking 分页按钮样式:1px 描边 + 白底 + 6px 圆角 */
:deep(.right-footer .el-pagination.is-background .btn-prev),
:deep(.right-footer .el-pagination.is-background .btn-next),
:deep(.right-footer .el-pagination.is-background .el-pager li) {
border: 1px solid rgba(0, 0, 0, 0.15) !important;
background-color: rgba(255, 255, 255, 1) !important;
border-radius: 6px !important;
box-sizing: border-box;
}
// 选中状态的页码样式(描边+文字颜色改为指定蓝色)
:deep(.right-footer .el-pagination.is-background .el-pager li.is-active) {
border-color: rgba(22, 119, 255, 1) !important; // 选中后描边颜色
color: rgba(22, 119, 255, 1) !important; // 选中后页码文字颜色
background-color: rgba(255, 255, 255, 1) !important; // 保持白色背景
font-weight: 400;
}
</style>
\ No newline at end of file
......@@ -22,9 +22,12 @@
</div>
<div class="select-main">
<div class="checkbox-group">
<el-checkbox label="全部领域" class="filter-checkbox"></el-checkbox>
<el-checkbox v-for="type in researchTypeList" :key="type.id" v-model="selectedResearchTypeList"
:label="type.id" class="filter-checkbox" @change="handleGetThinkDynamicsReport()">
<el-checkbox class="filter-checkbox" :model-value="isGroupAllSelected(researchTypeIds)"
@change="val => handleToggleAll(val, researchTypeIds)">
全部领域
</el-checkbox>
<el-checkbox v-for="type in researchTypeList" :key="type.id" v-model="selectedResearchIds" :label="type.id"
class="filter-checkbox" @change="handleGetThinkDynamicsReport()">
{{ type.name }}
</el-checkbox>
</div>
......@@ -37,8 +40,11 @@
</div>
<div class="select-main">
<div class="checkbox-group">
<el-checkbox label="全部时间"></el-checkbox>
<el-checkbox v-for="type in researchTimeList" :key="type.id" v-model="selectedResearchTypeList"
<el-checkbox class="filter-checkbox" :model-value="isGroupAllSelected(researchTimeIds)"
@change="val => handleToggleAll(val, researchTimeIds)">
全部时间
</el-checkbox>
<el-checkbox v-for="type in researchTimeList" :key="type.id" v-model="selectedResearchTimeIds"
:label="type.id" class="filter-checkbox" @change="handleGetThinkDynamicsReport()">
{{ type.name }}
</el-checkbox>
......@@ -78,7 +84,7 @@
</div>
</template>
<script setup>
import { ref, toRefs, watch } from "vue";
import { computed, ref, toRefs, watch } from "vue";
const props = defineProps({
researchTypeList: {
......@@ -89,9 +95,13 @@ const props = defineProps({
type: Array,
default: () => []
},
selectedResearchTypeList: {
type: Array,
default: () => []
selectedFilters: {
type: Object,
default: () => ({
researchTypeIds: [],
researchTimeIds: [],
researchHearingIds: []
})
},
curFooterList: {
type: Array,
......@@ -108,7 +118,7 @@ const props = defineProps({
});
const emit = defineEmits([
"update:selectedResearchTypeList",
"update:selectedFilters",
"filter-change",
"page-change",
"report-click"
......@@ -117,31 +127,51 @@ const emit = defineEmits([
// 解构 props,保持模板里变量名不变
const { researchTypeList, researchTimeList, curFooterList, total, currentPage } = toRefs(props);
// 用本地 ref 替代 computed,el-checkbox 会直接修改数组,需要可变的 ref
const selectedResearchTypeList = ref([...(props.selectedResearchTypeList || [])]);
const selectedResearchIds = ref([]);
const selectedResearchTimeIds = ref([]);
// 父组件更新时同步到子组件
watch(
() => props.selectedResearchTypeList,
() => props.selectedFilters,
val => {
selectedResearchTypeList.value = val ? [...val] : [];
selectedResearchIds.value = val?.researchTypeIds ? [...val.researchTypeIds] : [];
selectedResearchTimeIds.value = val?.researchTimeIds ? [...val.researchTimeIds] : [];
},
{ immediate: true, deep: true }
);
// 子组件勾选变化时通知父组件,flush: 'sync' 确保在 @change 触发前父组件已更新,否则 filter-change 时父组件拿到的还是旧值
watch(
selectedResearchTypeList,
val => {
emit("update:selectedResearchTypeList", val);
},
{ deep: true, flush: "sync" }
);
const buildSelectedFiltersPayload = () => ({
researchTypeIds: [...selectedResearchIds.value],
researchTimeIds: [...selectedResearchTimeIds.value],
researchHearingIds: []
});
const researchTypeIds = computed(() => (researchTypeList.value || []).map(item => item.id));
const researchTimeIds = computed(() => (researchTimeList.value || []).map(item => item.id));
const getTargetSelection = ids => (ids === researchTypeIds.value ? selectedResearchIds : selectedResearchTimeIds);
const isGroupAllSelected = ids =>
ids.length > 0 && ids.every(id => getTargetSelection(ids).value.includes(id));
const handleToggleAll = (checked, ids) => {
if (!ids.length) return;
const targetSelection = getTargetSelection(ids);
const nextSelected = new Set(targetSelection.value);
if (checked) {
ids.forEach(id => nextSelected.add(id));
} else {
ids.forEach(id => nextSelected.delete(id));
}
targetSelection.value = [...nextSelected];
handleGetThinkDynamicsReport();
};
// 保持模板里的方法名不变,但改成通知父组件,直接传入当前选中值避免时序问题
const handleGetThinkDynamicsReport = () => {
emit("update:selectedResearchTypeList", [...selectedResearchTypeList.value]);
emit("filter-change", [...selectedResearchTypeList.value]);
const payload = buildSelectedFiltersPayload();
emit("update:selectedFilters", payload);
emit("filter-change", payload);
};
const handleCurrentChange = page => {
......@@ -171,7 +201,7 @@ const handleToReportDetail = item => {
.select-research-box {
width: 360px;
height: 284px;
margin-top: 21px;
margin-top: 19px;
.select-box-header {
display: flex;
......@@ -200,7 +230,7 @@ const handleToReportDetail = item => {
.select-main {
margin-left: 25px;
margin-left: 24px;
.checkbox-group {
display: grid;
......@@ -230,13 +260,14 @@ const handleToReportDetail = item => {
}
.select-time-box {
margin-top: 21px;
margin-top: 44px;
width: 360px;
height: 156px;
.select-box-header {
display: flex;
gap: 17px;
margin-bottom: 12px;
.icon {
margin-top: 4px;
......@@ -260,11 +291,17 @@ const handleToReportDetail = item => {
.select-main {
margin-left: 25px;
margin-left: 24px;
.checkbox-group {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px 4px;
.filter-checkbox {
width: 160px;
height: 24px;
}
}
......@@ -394,4 +431,26 @@ const handleToReportDetail = item => {
margin-right: 0 !important;
}
/* PolicyTracking 分页按钮样式:1px 描边 + 白底 + 6px 圆角 */
:deep(.right-footer .el-pagination.is-background .btn-prev),
:deep(.right-footer .el-pagination.is-background .btn-next),
:deep(.right-footer .el-pagination.is-background .el-pager li) {
border: 1px solid rgba(0, 0, 0, 0.15) !important;
background-color: rgba(255, 255, 255, 1) !important;
border-radius: 6px !important;
box-sizing: border-box;
}
// 选中状态的页码样式(描边+文字颜色改为指定蓝色)
:deep(.right-footer .el-pagination.is-background .el-pager li.is-active) {
border-color: rgba(22, 119, 255, 1) !important; // 选中后描边颜色
color: rgba(22, 119, 255, 1) !important; // 选中后页码文字颜色
background-color: rgba(255, 255, 255, 1) !important; // 保持白色背景
font-weight: 400;
}
:deep(.el-checkbox__inner) {
border-radius: 4px !important;
}
</style>
\ No newline at end of file
......@@ -69,18 +69,28 @@
</div>
</div>
</div>
<div v-if="pageChange">
<div v-if="isThinkTankReport">
<ThinkTankReport :research-type-list="researchTypeList" :research-time-list="researchTimeList"
:selected-research-type-list="selectedResearchTypeList" :cur-footer-list="curFooterList" :total="total"
:current-page="currentPage" @update:selected-research-type-list="val => (selectedResearchTypeList.value = val)"
:key="`智库报告-${tabResetKey}`" :selected-filters="selectedFilters" :cur-footer-list="curFooterList" :total="total"
:current-page="currentPage"
@update:selected-filters="handleSelectedFiltersUpdate"
@filter-change="(payload) => handleGetThinkDynamicsReport(payload)" @page-change="handleCurrentChange"
@report-click="handleToReportDetail" />
</div>
<div v-if="!pageChange">
<div v-if="isCongressHearing">
<CongressHearing :research-type-list="researchTypeList" :research-time-list="researchTimeList"
:research-hearing-list="researchHearingList" :selected-research-type-list="selectedResearchTypeList"
:cur-footer-list="curFooterList" :total="total" :current-page="currentPage" :hearing-data="hearingData"
@update:selected-research-type-list="val => (selectedResearchTypeList.value = val)"
:key="`国会听证会-${tabResetKey}`" :research-hearing-list="researchHearingList"
:selected-filters="selectedFilters" :selected-year="selectedYear" :cur-footer-list="curFooterList" :total="total"
:current-page="currentPage" :hearing-data="hearingData"
@update:selected-filters="handleSelectedFiltersUpdate"
@filter-change="(payload) => handleGetThinkDynamicsReport(payload)" @page-change="handleCurrentChange"
@report-click="handleToReportDetail" />
</div>
<div>
<SurveyForm v-if="isSurveyForm" :research-type-list="researchTypeList" :research-time-list="researchTimeList"
:key="`调查项目-${tabResetKey}`" :selected-filters="selectedFilters" :cur-footer-list="curFooterList" :total="total"
:current-page="currentPage"
@update:selected-filters="handleSelectedFiltersUpdate"
@filter-change="(payload) => handleGetThinkDynamicsReport(payload)" @page-change="handleCurrentChange"
@report-click="handleToReportDetail" />
</div>
......@@ -89,6 +99,7 @@
<script setup>
import { ref, reactive, onMounted } from "vue";
import SurveyForm from "./SurveyForm/index.vue"
// import Img1 from "./images/img1.png";
// import Img2 from "./images/img2.png";
// import Img3 from "./images/img3.png";
......@@ -111,7 +122,9 @@ import { useRouter } from "vue-router";
import ThinkTankReport from "./ThinkTankReport/index.vue";
import CongressHearing from "./CongressHearing/index.vue";
const router = useRouter();
const pageChange = ref(true)
const isThinkTankReport = ref(true);
const isSurveyForm = ref(false);
const isCongressHearing = ref(false);
const searchReport = ref('')
const handleToReportDetail = (item) => {
......@@ -302,15 +315,46 @@ const choseTypeList = ref([
])
const activeTypeId = ref(choseTypeList.value[0]?.id || null)
const tabResetKey = ref(0)
const createDefaultSelectedFilters = () => ({
researchTypeIds: [],
researchTimeIds: [],
researchHearingIds: []
})
const resetThinkDynamicsState = () => {
searchReport.value = ''
selectedYear.value = 1
sort.value = false
author.value = ''
currentPage.value = 1
selectedFilters.value = createDefaultSelectedFilters()
curFooterList.value = []
total.value = 0
tabResetKey.value += 1
}
const handleChooseType = (type) => {
if (activeTypeId.value === type.id) {
return
}
activeTypeId.value = type.id
if (type.id === '国会听证会') {
pageChange.value = false
isThinkTankReport.value = false
isCongressHearing.value = true
isSurveyForm.value = false
} else if (type.id === "智库报告") {
isThinkTankReport.value = true
isCongressHearing.value = false
isSurveyForm.value = false
} else {
pageChange.value = true
isThinkTankReport.value = false
isCongressHearing.value = false
isSurveyForm.value = true
}
resetThinkDynamicsState()
handleGetThinkDynamicsReport()
}
const researchTimeList = ref([
{
......@@ -368,7 +412,11 @@ const researchHearingList = ref([
name: '新材料',
}
])
const selectedResearchTypeList = ref([])
const selectedFilters = ref(createDefaultSelectedFilters())
const handleSelectedFiltersUpdate = val => {
selectedFilters.value = val
}
const author = ref('') // 作者
......@@ -524,11 +572,26 @@ function arrayToString(arr) {
}, "");
}
function buildThinkDynamicsYears(selectedYears) {
const allYearIds = researchTimeList.value.map(item => item.id)
if (!selectedYears?.length || selectedYears.length === allYearIds.length) {
return null
}
return arrayToString(selectedYears)
}
// 获取智库动态报告,payload 为子组件筛选变更时传入的当前选中值,避免时序导致拿到旧值
const handleGetThinkDynamicsReport = async (payload) => {
const selectedIds = Array.isArray(payload) ? payload : selectedResearchTypeList.value;
if (Array.isArray(payload)) {
selectedResearchTypeList.value = payload;
const nextFilters = payload && typeof payload === 'object'
? {
researchTypeIds: payload.researchTypeIds ? [...payload.researchTypeIds] : [],
researchTimeIds: payload.researchTimeIds ? [...payload.researchTimeIds] : [],
researchHearingIds: payload.researchHearingIds ? [...payload.researchHearingIds] : []
}
: selectedFilters.value;
if (payload && typeof payload === 'object') {
selectedFilters.value = nextFilters;
currentPage.value = 1;
}
try {
const parmas = {
......@@ -540,7 +603,8 @@ const handleGetThinkDynamicsReport = async (payload) => {
sortFun: sort.value ?? true,
currentPage: currentPage.value - 1,
pageSize: 12,
researchTypeIds: arrayToString(selectedIds) === '' ? null : arrayToString(selectedIds)
researchTypeIds: arrayToString(nextFilters.researchTypeIds) === '' ? null : arrayToString(nextFilters.researchTypeIds),
years: buildThinkDynamicsYears(nextFilters.researchTimeIds)
}
}
......
......@@ -33,10 +33,10 @@
</div>
<div class="report-box">
<iframe :src="reportUrl" width="50%" height="100%">
<iframe :src="reportUrlWithPage" width="50%" height="100%">
</iframe>
<iframe :src="reportUrlEn" width="50%" height="100%">
<iframe :src="reportUrlEnWithPage" width="50%" height="100%">
</iframe>
<!-- <pdf :pdfUrl="reportUrl" style="width: 48%;" />
......@@ -49,21 +49,35 @@
</template>
<script setup>
import { ref, onMounted } from "vue";
import { computed, ref, onMounted } from "vue";
import pdf from "./pdf.vue";
import {
getThinkTankReportSummary,
getThinkTankReportcontentUrl
} from "@/api/thinkTank/overview";
import { useRouter } from "vue-router";
import { useRoute, useRouter } from "vue-router";
const router = useRouter();
const route = useRoute();
const reportUrl = ref('')
const reportUrlEn = ref('')
const thinkInfo = ref({})
const defaultPdfPage = ref(1)
const sourceCurrentPage = ref(Number(route.query.currentPage) || 1)
const sourcePageSize = ref(Number(route.query.pageSize) || 12)
const opinionId = ref(route.query.opinionId || "")
const opinionContent = ref(route.query.opinionContent || "")
const buildPdfPageUrl = url => {
if (!url) return ''
return `${url}#page=${defaultPdfPage.value}`
}
const reportUrlWithPage = computed(() => buildPdfPageUrl(reportUrl.value))
const reportUrlEnWithPage = computed(() => buildPdfPageUrl(reportUrlEn.value))
// 获取报告全局信息
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论