提交 2ad8e183 authored 作者: 朱政's avatar 朱政

feat:智库中政令法案跳转,tip标签样式修改

上级 b46e0652
......@@ -77,6 +77,58 @@ function extractInterpretationFromLooseText(text) {
return String(m[1]).replace(/\\n/g, "\n").trim();
}
/**
* 从流式累积 buffer 中提取「解读」字符串的已生成部分(滤掉 ```json、[、{ 等外壳,避免界面出现 json\n[\n)
* 支持未闭合的字符串(流式进行中)
* @param {string} buffer
* @returns {string}
*/
function extractStreamingInterpretationFromBuffer(buffer) {
const s = String(buffer || "");
let rest = s.replace(/^\uFEFF/, "");
const fence = rest.match(/^```(?:json)?\s*/i);
if (fence) {
rest = rest.slice(fence[0].length);
}
const keyRe =
/["'](?:解读|interpretation|analysis|content)["']\s*:\s*"/i;
const m = rest.match(keyRe);
if (!m) {
return "";
}
let pos = m.index + m[0].length;
let out = "";
while (pos < rest.length) {
const ch = rest[pos];
if (ch === '"') {
break;
}
if (ch === "\\") {
pos += 1;
if (pos >= rest.length) {
break;
}
const esc = rest[pos];
if (esc === "n") {
out += "\n";
} else if (esc === "r") {
out += "\r";
} else if (esc === "t") {
out += "\t";
} else if (esc === '"' || esc === "\\") {
out += esc;
} else {
out += esc;
}
pos += 1;
continue;
}
out += ch;
pos += 1;
}
return out;
}
/**
* 图表解读(SSE 流式)
* @param {object} data - 请求体
......@@ -94,6 +146,8 @@ export function getChartAnalysis(data, options = {}) {
return new Promise((resolve, reject) => {
let buffer = "";
let latestInterpretation = "";
/** 已推给前端的「解读」正文长度,用于只增量回调 onChunk */
let lastStreamedInterpretationLen = 0;
let settled = false;
const abortController = new AbortController();
......@@ -175,9 +229,31 @@ export function getChartAnalysis(data, options = {}) {
return;
}
// 每收到一条消息即回调,用于流式渲染
// 流式渲染:不把 ```json、[、{ 等 markdown/JSON 外壳拼到界面
if (chunk && onDelta) {
onDelta(chunk);
let parsedMsg = null;
try {
parsedMsg = JSON.parse(raw);
} catch (_) {
parsedMsg = null;
}
const isReasoningChunk =
parsedMsg &&
typeof parsedMsg === "object" &&
parsedMsg.type === "reasoning" &&
typeof parsedMsg.chunk === "string";
if (isReasoningChunk) {
onDelta(parsedMsg.chunk);
} else {
const visible = extractStreamingInterpretationFromBuffer(buffer);
if (visible.length > lastStreamedInterpretationLen) {
onDelta(
visible.slice(lastStreamedInterpretationLen)
);
lastStreamedInterpretationLen = visible.length;
}
}
}
// 如果 buffer 已经拼完 markdown code fence,则提前解析并中断连接
......
......@@ -286,8 +286,7 @@ export function getThinkPolicyIndustryChange(params) {
/**
* 获取智库政策(政策追踪列表)
* GET /api/thinkTankInfo/policy
* Query: thinkTankId, startDate, endDate, orgIds, domainIds(科技领域/智库领域,逗号分隔 id), pageNum, pageSize, sortField, sortOrder, sortFun, reportId 等
*/
export function getThinkPolicy(params) {
return request({
......
......@@ -103,17 +103,19 @@
</div>
<div class="right-footer-box">
<div class="relatedBills" v-for="(item, index) in box1DataItem.relatedBills" :key="index" v-show="item">
<div class="tag">{{ "政令" }}</div>
<div class="tag">{{ "法案" }}</div>
<div class="tag">{{ "科技领域相似" }}</div>
<div class="relatedBills-content">{{ item.name }}</div>
<div class="footer-image"> <img src="../images/image-right.png" alt="" /></div>
<div class="footer-image" @click.stop="handleBillMoreClick(item)"> <img src="../images/image-right.png"
alt="" /></div>
</div>
<div class="relatedAdministrativeOrders" v-for="(item, index) in box1DataItem.relatedAdministrativeOrders"
v-show="item" :key="index">
<div class="tag">{{ "政令" }}</div>
<div class="tag">{{ "科技领域相似" }}</div>
<div class="relatedAdministrativeOrders-content">{{ item.content }}</div>
<div class="footer-image"> <img src="../images/image-right.png" alt="" /></div>
<div class="footer-image" @click.stop="handleAdministrativeMoreClick(item)"> <img
src="../images/image-right.png" alt="" /></div>
</div>
</div>
</div>
......@@ -217,6 +219,29 @@ const handleTagClick = tag => {
activeItemIndex.value = 0;
updatePageData();
};
const handleBillMoreClick = (bill) => {
const billId = bill?.id;
if (!billId) {
return;
}
const route = router.resolve({
path: "/billLayout/bill/introduction",
query: { billId: String(billId) }
});
window.open(route.href, "_blank");
};
/** 政策建议关联法案:新标签页打开政令介绍页*/
const handleAdministrativeMoreClick = (ad) => {
const id = ad?.bcId;
if (!id) {
return;
}
const route = router.resolve({
path: "/decreeLayout/overview/introduction",
query: { id: String(id) }
});
window.open(route.href, "_blank");
};
const handleSearchOpinions = () => {
// 搜索时默认切回“全部”标签
activeTag.value = "";
......
......@@ -74,11 +74,12 @@
</div>
<div class="box5-footer">
<TipTab :text="REPORT_ANALYSIS_TIP_BOX5" />
<div class="ai-wrap" @mouseenter="handleSwitchAiContentShowBox5(true)">
<AiButton />
</div>
<div class="ai-wrap" @mouseenter="handleSwitchAiContentShowBox5(true)">
<AiButton />
</div>
</div>
<div class="ai-content" v-if="isShowAiContentBox5" @mouseleave="handleSwitchAiContentShowBox5(false)">
<AiPane :aiContent="aiContentBox5" />
</div>
......@@ -927,9 +928,18 @@ onMounted(() => {
display: flex;
justify-content: space-between;
align-items: center;
position: absolute;
bottom: 20px;
left: 32px;
}
.ai-wrap {
position: absolute;
bottom: 18px;
right: 0;
cursor: pointer;
}
......@@ -942,12 +952,7 @@ onMounted(() => {
}
.ai-wrap {
position: relative;
cursor: pointer;
}
}
}
......
......@@ -252,7 +252,7 @@
<div class="file" v-for="(file, idxx) in item.relatedBills" :key="`${file.id}-${idxx}`">
<div class="type">法案</div>
<div class="title">{{ file.name }}</div>
<div class="more">
<div class="more" @click.stop="handleBillMoreClick(file)">
<img src="./images/arrow-right.png" alt="" />
</div>
</div>
......@@ -260,7 +260,7 @@
:key="file.bcId != null ? String(file.bcId) + '-' + idxx : idxx">
<div class="type">政令</div>
<div class="title">{{ file.content }}</div>
<div class="more">
<div class="more" @click.stop="handleAdministrativeMoreClick(file)">
<img src="./images/arrow-right.png" alt="" />
</div>
</div>
......@@ -458,6 +458,30 @@ const handleGetThinkPolicyIndustry = async () => {
}
};
/** 政策建议关联法案:新标签页打开法案介绍页,billId 随接口 id 变化 */
const handleBillMoreClick = (bill) => {
const billId = bill?.id;
if (!billId) {
return;
}
const route = router.resolve({
path: "/billLayout/bill/introduction",
query: { billId: String(billId) }
});
window.open(route.href, "_blank");
};
/** 政策建议关联法案:新标签页打开政令介绍页*/
const handleAdministrativeMoreClick = (ad) => {
const id = ad?.bcId;
if (!id) {
return;
}
const route = router.resolve({
path: "/decreeLayout/overview/introduction",
query: { id: String(id) }
});
window.open(route.href, "_blank");
};
// 政策建议涉及部门分布(饼图)
const box2Data = ref([]);
......@@ -1423,9 +1447,8 @@ onMounted(() => {
.source {
position: absolute;
bottom: 21px;
left: 50%;
transform: translateX(-50%);
width: 350px;
left: 24px;
width: 420px;
height: 22px;
display: flex;
}
......@@ -1486,10 +1509,8 @@ onMounted(() => {
.source {
position: absolute;
bottom: 21px;
left: 50%;
transform: translateX(-50%);
width: 350px;
bottom: 24px;
width: 420px;
height: 22px;
display: flex;
......
......@@ -402,80 +402,8 @@ const handleSelectedFiltersUpdate = val => {
const author = ref('') // 作者
const curFooterList = ref([
// {
// title: "中国对AI的转型产业政策",
// time: "2025年6月26日",
// from: "兰德科技智库",
// img: Img1
// },
// {
// title: "中美对抗、竞争和合作跨越人工智能通用领域...",
// time: "2025年6月26日",
// from: "兰德科技智库",
// img: Img2
// },
// {
// title: "中国、智慧城市和中东:地区和美国的选择",
// time: "2025年6月26日",
// from: "兰德科技智库",
// img: Img3
// },
// {
// title: "中国对AI的转型产业政策",
// time: "2025年6月26日",
// from: "兰德科技智库",
// img: Img4
// },
// {
// title: "中美经济竞争:复杂经济和地缘政治关系中的...",
// time: "2025年6月26日",
// from: "兰德科技智库",
// img: Img5
// },
// {
// title: "中国、智慧城市和中东:留给地区和美国的选择",
// time: "2025年6月26日",
// from: "兰德科技智库",
// img: Img6
// },
// {
// title: "中国对AI的转型产业政策",
// time: "2025年6月26日",
// from: "兰德科技智库",
// img: Img7
// },
// {
// title: "中美对抗、竞争和合作跨越人工智能通用领域...",
// time: "2025年6月26日",
// from: "",
// img: Img8
// },
// {
// title: "中国、智慧城市和中东:地区和美国的选择",
// time: "2025年6月26日",
// from: "兰德科技智库",
// img: Img9
// },
// {
// title: "中国对AI的转型产业政策",
// time: "2025年6月26日",
// from: "兰德科技智库",
// img: Img10
// },
// {
// title: "中美对抗、竞争和合作跨越人工智能通用领域...",
// time: "2025年6月26日",
// from: "兰德科技智库",
// img: Img11
// },
// {
// title: "中国、智慧城市和中东:地区和美国的选择",
// time: "2025年6月26日",
// from: "兰德科技智库",
// img: Img12
// }
]);
/** 智库报告 / 调查项目共用列表:与资源库一致,初始为空,接口非成功时清空 */
const curFooterList = ref([]);
......@@ -579,11 +507,10 @@ const handleGetThinkDynamicsReport = async (payload) => {
params.keyword = keyword;
}
const res = await getThinkTankReport(params);
console.log("智库动态报告", res);
if (res.code === 200 && res.data) {
curFooterList.value = res.data.content;
total.value = res.data.totalElements;
} else if (res.code === 500 && res.message === "未找到对应筛选的报告") {
} else {
curFooterList.value = [];
total.value = 0;
}
......
......@@ -453,9 +453,9 @@ const handleGetThinkTankFundsSource = async () => {
alignTo: 'edge',
offset: [0, -LABEL_OFFSET_UP],
formatter(params) {
const valueYi = (params.data.value || 0) / 100000000
const valueYi = (params.data.value || 0) / 10000
const percent = params.percent || 0
const valueStr = `${valueYi.toFixed(3)}亿 ${percent}%`
const valueStr = `${valueYi} ${percent}%`
let cumulative = 0
for (let i = 0; i < params.dataIndex; i++) cumulative += dataList[i].value || 0
const centerAngle = 90 + ((cumulative + (params.data.value || 0) / 2) / total) * 360
......@@ -1096,10 +1096,10 @@ onMounted(() => {
}
.source {
margin: 0 auto;
margin-top: 10px;
margin-left: 240px;
/* 上下0,左右自动居中 */
width: 370px;
height: 22px;
display: flex;
......@@ -1285,7 +1285,7 @@ onMounted(() => {
}
.source {
margin: 0 auto;
margin-left: 35px;
margin-top: 10px;
/* 上下0,左右自动居中 */
......
......@@ -7,18 +7,11 @@
<div class="title">{{ "科技领域" }}</div>
</div>
<div class="select-main">
<el-checkbox-group
class="checkbox-group"
:model-value="selectedTypeIds"
@change="handleAreaGroupChange">
<el-checkbox-group class="checkbox-group" :model-value="selectedTypeIds" @change="handleAreaGroupChange">
<el-checkbox class="filter-checkbox" :label="RESOURCE_FILTER_ALL_AREA">
{{ RESOURCE_FILTER_ALL_AREA }}
</el-checkbox>
<el-checkbox
class="filter-checkbox"
v-for="t in (researchTypeList || [])"
:key="t.id"
:label="t.id">
<el-checkbox class="filter-checkbox" v-for="t in (researchTypeList || [])" :key="t.id" :label="t.id">
{{ t.name }}
</el-checkbox>
</el-checkbox-group>
......@@ -31,18 +24,11 @@
<div class="title">{{ "发布时间" }}</div>
</div>
<div class="select-main">
<el-checkbox-group
class="checkbox-group"
:model-value="selectedYearIds"
@change="handleYearGroupChange">
<el-checkbox-group class="checkbox-group" :model-value="selectedYearIds" @change="handleYearGroupChange">
<el-checkbox class="filter-checkbox" :label="RESOURCE_FILTER_ALL_TIME">
{{ RESOURCE_FILTER_ALL_TIME }}
</el-checkbox>
<el-checkbox
class="filter-checkbox"
v-for="y in (researchTimeList || [])"
:key="y.id"
:label="y.id">
<el-checkbox class="filter-checkbox" v-for="y in (researchTimeList || [])" :key="y.id" :label="y.id">
{{ y.name }}
</el-checkbox>
</el-checkbox-group>
......@@ -71,17 +57,17 @@
</div>
<div class="file-box">
<div class="file">
<div class="file" v-for="sv in item.billInfoList" :key="sv.id || sv.name">
<div class="type">法案</div>
<div class="title">{{ item.billInfoList[0].name }}</div>
<div class="more">
<div class="title">{{ sv.name }}</div>
<div class="more" @click.stop="handleBillMoreClick(sv)">
<img src="../assets/images/image-right.png" alt="" />
</div>
</div>
<div class="file">
<div class="file" v-for="(sv, index) in item.administrativeOrderInfoVOList" :key="index">
<div class="type">政令</div>
<div class="title">{{ item.billInfoList[0].name }}</div>
<div class="more">
<div class="title">{{ sv.content }}</div>
<div class="more" @click.stop="handleAdministrativeMoreClick(sv)">
<img src="../assets/images/image-right.png" alt="" />
</div>
</div>
......@@ -106,6 +92,7 @@
<script setup>
import { ref } from "vue";
import { useRouter } from "vue-router";
import AreaTag from "@/components/base/AreaTag/index.vue";
import {
RESOURCE_FILTER_ALL_AREA,
......@@ -126,6 +113,32 @@ defineProps({
const emit = defineEmits(["filter-change", "page-change", "item-click"]);
const router = useRouter();
/** 政策建议关联法案:新标签页打开法案介绍页,billId 随接口 id 变化 */
const handleBillMoreClick = (bill) => {
const billId = bill?.id;
if (!billId) {
return;
}
const route = router.resolve({
path: "/billLayout/bill/introduction",
query: { billId: String(billId) }
});
window.open(route.href, "_blank");
};
/** 政策建议关联法案:新标签页打开政令介绍页*/
const handleAdministrativeMoreClick = (ad) => {
const id = ad?.bcId;
if (!id) {
return;
}
const route = router.resolve({
path: "/decreeLayout/overview/introduction",
query: { id: String(id) }
});
window.open(route.href, "_blank");
};
const selectedTypeIds = ref([RESOURCE_FILTER_ALL_AREA]);
const selectedYearIds = ref([RESOURCE_FILTER_ALL_TIME]);
......@@ -428,6 +441,7 @@ const handleYearGroupChange = (val) => {
height: 20px;
display: flex;
margin-top: 2px;
cursor: pointer;
.img {
width: 100%;
......
......@@ -444,19 +444,6 @@ import Logo3 from "./assets/images/logo3.png";
import Logo4 from "./assets/images/logo4.png";
import Logo5 from "./assets/images/logo5.png";
import Img1 from "./assets/images/img1.png";
import Img2 from "./assets/images/img2.png";
import Img3 from "./assets/images/img3.png";
import Img4 from "./assets/images/img4.png";
import Img5 from "./assets/images/img5.png";
import Img6 from "./assets/images/img6.png";
import Img7 from "./assets/images/img7.png";
import Img8 from "./assets/images/img8.png";
import Img9 from "./assets/images/img9.png";
import Img10 from "./assets/images/img10.png";
import Img11 from "./assets/images/img11.png";
import Img12 from "./assets/images/img12.png";
import Box1Img from "./assets/images/box1-img.png";
import Box1Logo from "./assets/images/box1-logo.png";
import { setCanvasCreator } from "echarts/core";
......@@ -1733,80 +1720,8 @@ const toggleResourceLibrarySortPrefix = () => {
}
};
const curFooterList = ref([
{
title: "中国对AI的转型产业政策",
time: "2025年6月26日",
from: "兰德科技智库",
img: Img1
},
{
title: "中美对抗、竞争和合作跨越人工智能通用领域...",
time: "2025年6月26日",
from: "兰德科技智库",
img: Img2
},
{
title: "中国、智慧城市和中东:地区和美国的选择",
time: "2025年6月26日",
from: "兰德科技智库",
img: Img3
},
{
title: "中国对AI的转型产业政策",
time: "2025年6月26日",
from: "兰德科技智库",
img: Img4
},
{
title: "中美经济竞争:复杂经济和地缘政治关系中的...",
time: "2025年6月26日",
from: "兰德科技智库",
img: Img5
},
{
title: "中国、智慧城市和中东:留给地区和美国的选择",
time: "2025年6月26日",
from: "兰德科技智库",
img: Img6
},
{
title: "中国对AI的转型产业政策",
time: "2025年6月26日",
from: "兰德科技智库",
img: Img7
},
{
title: "中美对抗、竞争和合作跨越人工智能通用领域...",
time: "2025年6月26日",
from: "",
img: Img8
},
{
title: "中国、智慧城市和中东:地区和美国的选择",
time: "2025年6月26日",
from: "兰德科技智库",
img: Img9
},
{
title: "中国对AI的转型产业政策",
time: "2025年6月26日",
from: "兰德科技智库",
img: Img10
},
{
title: "中美对抗、竞争和合作跨越人工智能通用领域...",
time: "2025年6月26日",
from: "兰德科技智库",
img: Img11
},
{
title: "中国、智慧城市和中东:地区和美国的选择",
time: "2025年6月26日",
from: "兰德科技智库",
img: Img12
}
]);
/** 与调查项目 surveyFooterList 一致:初始空列表,由接口填充;失败或非 200 时清空 */
const curFooterList = ref([]);
const currentPage = ref(1);
const total = ref(0);
......@@ -1886,40 +1801,6 @@ const handlePolicyCurrentChange = page => {
};
const handleGetThinkTankPolicyAdvice = async () => {
const mockPolicyAdviceList = () => ([
{
id: 23702,
content: "研究未来AI数据中心电力需求与供应",
imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg",
name: "指数级增长下AI的电力需求:外推AI数据中心的电力需求并评估其对美国竞争力的潜在影响",
reportId: "Rand_RRA3572-1",
tagList: ["新能源", "人工智能"],
thinkTankName: null,
times: "2025-12-28"
},
{ id: 23703, content: "构建可信任的AI治理框架:监管与创新的平衡", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "AI治理路线图:从风险评估到合规落地的实践建议", reportId: "Rand_RRA3572-2", tagList: ["人工智能", "网络安全"], thinkTankName: null, times: "2025-12-21" },
{ id: 23704, content: "先进制造供应链韧性评估与关键节点识别", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "供应链韧性:关键材料、关键设备与关键人才的系统性策略", reportId: "Rand_RRA3572-3", tagList: ["先进制造", "新材料"], thinkTankName: null, times: "2025-12-14" },
{ id: 23705, content: "半导体出口管制对产业生态的中长期影响", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "出口管制与产业政策:如何降低对关键环节的外部依赖", reportId: "Rand_RRA3572-4", tagList: ["集成电路", "先进制造"], thinkTankName: null, times: "2025-12-07" },
{ id: 23706, content: "量子信息技术发展态势与应用落地路径", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "量子科技:从基础研究到产业化的阶段性里程碑", reportId: "Rand_RRA3572-5", tagList: ["量子科技", "前沿基础"], thinkTankName: null, times: "2025-11-30" },
{ id: 23707, content: "网络安全威胁图谱:关键基础设施的攻击面", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "关键基础设施安全:供应链、身份与数据的三重防护", reportId: "Rand_RRA3572-6", tagList: ["网络安全", "数据安全"], thinkTankName: null, times: "2025-11-23" },
{ id: 23708, content: "生物技术与医疗创新的监管协同机制", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "生物科技创新:试验、审批与产业化的全流程政策工具箱", reportId: "Rand_RRA3572-7", tagList: ["生物科技", "医疗健康"], thinkTankName: null, times: "2025-11-16" },
{ id: 23709, content: "清洁能源转型下的电网规划与储能配置", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "能源系统转型:电网升级、储能布局与成本测算", reportId: "Rand_RRA3572-8", tagList: ["新能源", "储能"], thinkTankName: null, times: "2025-11-09" },
{ id: 23710, content: "新材料在国防与先进制造中的应用瓶颈", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "关键新材料:验证体系、规模化与供应链安全", reportId: "Rand_RRA3572-9", tagList: ["新材料", "先进制造"], thinkTankName: null, times: "2025-11-02" },
{ id: 23711, content: "通信网络演进:6G 与卫星互联网的融合", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "下一代通信:频谱、标准与产业联盟策略", reportId: "Rand_RRA3572-10", tagList: ["通信网络", "卫星互联网"], thinkTankName: null, times: "2025-10-26" },
{ id: 23712, content: "数据要素市场建设与跨境数据合规路径", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "数据治理与合规:分类分级、出境评估与执法协同", reportId: "Rand_RRA3572-11", tagList: ["数据安全", "数字治理"], thinkTankName: null, times: "2025-10-19" },
{ id: 23713, content: "AI 研发人才供需缺口与教育体系对接", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "AI 人才战略:培养、引进与留用的组合政策", reportId: "Rand_RRA3572-12", tagList: ["人工智能", "人才政策"], thinkTankName: null, times: "2025-10-12" },
{ id: 23714, content: "自动驾驶安全监管与测试评价体系", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "自动驾驶:安全标准、责任划分与道路试点机制", reportId: "Rand_RRA3572-13", tagList: ["智能网联", "交通出行"], thinkTankName: null, times: "2025-10-05" },
{ id: 23715, content: "关键基础设施数字化升级的投融资机制", imageUrl: "https://www.rand.org/content/rand/pubs/research_reports/RRA3572-1/jcr:content/par/teaser.crop.1200x900.cm.jpeg/1738160125961.jpeg", name: "基础设施升级:公共资金撬动与绩效评估体系", reportId: "Rand_RRA3572-14", tagList: ["数字化转型", "基础设施"], thinkTankName: null, times: "2025-09-28" }
]);
const applyMockPolicyAdvice = () => {
const mock = mockPolicyAdviceList();
policyTotal.value = mock.length;
const pageSize = 7;
const page = Math.max(1, Number(policyCurrentPage.value) || 1);
const start = (page - 1) * pageSize;
policyFooterList.value = mock.slice(start, start + pageSize);
};
const strippedPolicyYears = stripAllTimeForRequest(policySelectedYearIds.value);
const allPubTimeIds = (pubTimeList.value || []).map((x) => x.id);
/** 与智库报告一致:仅「全部时间」或选满所有具体年份 → 不按 years 狭义过滤 */
......@@ -1933,7 +1814,7 @@ const handleGetThinkTankPolicyAdvice = async () => {
: (areaList.value || []).map(obj => obj.id);
const domainIdsStr = arrayToString(effectiveDomainIds);
const params = {
currentPage: policyCurrentPage.value - 1,
pageNum: policyCurrentPage.value,
pageSize: 7,
sortFun: policySort.value === true
};
......@@ -1966,19 +1847,20 @@ const handleGetThinkTankPolicyAdvice = async () => {
administrativeOrderInfoVOList: item.administrativeOrderInfoVOList
}));
if (!mapped.length) {
applyMockPolicyAdvice();
return;
}
policyFooterList.value = mapped;
policyTotal.value = res.data.totalElements || mapped.length;
policyTotal.value = res.data.totalElements ?? mapped.length;
} else {
applyMockPolicyAdvice();
policyFooterList.value = [];
policyTotal.value = 0;
if (res?.message) {
ElMessage.warning(res.message);
}
}
} catch (error) {
applyMockPolicyAdvice();
policyFooterList.value = [];
policyTotal.value = 0;
console.error("获取政策建议 error", error);
ElMessage.warning("获取政策建议失败");
}
};
// 处理页码改变事件
......@@ -2019,10 +1901,12 @@ const handleGetetThinkTankReport = async () => {
};
try {
const res = await getThinkTankReport(params);
console.log("智库报告", res);
if (res.code === 200 && res.data) {
curFooterList.value = res.data.content;
total.value = res.data.totalElements;
} else {
curFooterList.value = [];
total.value = 0;
}
} catch (error) {
console.error("获取智库报告error", error);
......@@ -3576,12 +3460,10 @@ onMounted(async () => {
position: absolute;
bottom: 21px;
left: 50%;
/* 让元素左边对齐父级中线 */
transform: translateX(-50%);
left: 24px;
/* 上下0,左右自动居中 */
width: 370px;
height: 22px;
display: flex;
......@@ -3716,13 +3598,11 @@ onMounted(async () => {
position: absolute;
bottom: 21px;
left: 50%;
/* 让元素左边对齐父级中线 */
transform: translateX(-50%);
left: 24px;
/* 让元素自身向左回退一半宽度 */
/* 上下0,左右自动居中 */
width: 370px;
height: 22px;
display: flex;
......@@ -3895,9 +3775,7 @@ onMounted(async () => {
position: absolute;
bottom: 21px;
left: 50%;
/* 让元素左边对齐父级中线 */
transform: translateX(-50%);
left: 24px;
/* 上下0,左右自动居中 */
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论