提交 c3dec961 authored 作者: coderBryanFu's avatar coderBryanFu

fix:更新goToPage.js文件部分跳转方法

流水线 #611 已通过 于阶段
in 1 分 43 秒
......@@ -105,19 +105,11 @@ const setChart = (option, chartId, allowClick, selectParam, otherAreaList) => {
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");
openDataThinkTank(selectParam);
return
} else if (selectParam.key === 2) {
selectParam.domains = params.name
const route = router.resolve({
path: "/dataLibrary/dataThinkTank",
query: selectParam
});
window.open(route.href, "_blank");
openDataThinkTank(selectParam);
return
}
}
......
......@@ -18,7 +18,29 @@ import { getCharacterGlobalInfo } from "@/api/characterPage/characterPage.js";
// 获取路由参数,1为科技领袖,2为国会议员,3为智库研究人员
const route = useRoute();
const type = ref(route.query.type || 1);
const personId = ref(route.query.personId || "Y000064");
const decodeMaybeBase64 = (raw) => {
if (raw == null) return null;
const s0 = String(raw).trim();
if (!s0) return null;
// 明文 personId(如 Y000064)保持原样,避免误解码
if (/^[A-Za-z]\d{6,}$/.test(s0) || /^Y\d+/i.test(s0)) {
return s0;
}
if (s0.length >= 12 && /^[A-Za-z0-9+/_-]+={0,2}$/.test(s0)) {
try {
const normalized = s0.replace(/-/g, "+").replace(/_/g, "/");
const padded = normalized + "===".slice((normalized.length + 3) % 4);
const decoded = atob(padded);
try {
return decodeURIComponent(decoded);
} catch (_) {
return decoded;
}
} catch (_) { }
}
return s0;
};
const personId = ref(decodeMaybeBase64(route.query.personId) || "Y000064");
// 获取人物全局信息
......
......@@ -25,7 +25,7 @@
</div>
</div>
</div> -->
<NewsList :newsList="leftList" @item-click="item => gotoNewsDetail(item.id)" @more-click="handleToMoreNews"
<NewsList :newsList="leftList" @item-click="item => gotoNewsDetail(encodeBase64Param(item.id))" @more-click="handleToMoreNews"
img="image" title="title" content="content" from="from" />
<MessageBubble :messageList="rightList" imageUrl="personImage" @more-click="handleToSocialDetail"
@person-click="handleToSocialDetail" name="name" content="content" source="orgName" image-url="image" />
......@@ -63,6 +63,16 @@ import title03bg from './assets/title03bg.png'
import { useGotoNewsDetail } from '@/router/modules/news';
const gotoNewsDetail = useGotoNewsDetail()
const encodeBase64Param = (val) => {
const s = String(val ?? "").trim();
if (!s) return "";
try {
return btoa(encodeURIComponent(s));
} catch (_) {
return s;
}
};
// 合作限制-查询社交媒体接口
const getCoopRestrictionSocialData = async () => {
try {
......@@ -139,10 +149,12 @@ const handleToNewsDetail = (item) => {
}
// 查看社交媒体详情
const handleToSocialDetail = (item) => {
const encodedPersonId = encodeBase64Param(item?.id);
if (!encodedPersonId) return;
const route = router.resolve({
path: "/characterPage",
query: {
personId: item.id
personId: encodedPersonId
}
});
window.open(route.href, "_blank");
......
......@@ -207,10 +207,16 @@ const handleClickToDetail = item => {
const id = activeItem?.ID || activeItem?.id || activeItem?.limitId;
if (!id) return;
window.sessionStorage.setItem("cooperationRestrictionsTabName", activeItem?.LIMITNAME || "");
const encodedId = (() => {
const s = String(id).trim();
if (!s) return "";
try { return btoa(encodeURIComponent(s)); } catch (_) { return s; }
})();
if (!encodedId) return;
const curRoute = router.resolve({
name: "CooperationRestrictionsDetail",
query: { id: id }
query: { id: encodedId }
});
window.open(curRoute.href, "_blank");
};
......@@ -219,9 +225,15 @@ const handleClickToDetail = item => {
const handleToRiskDetail = (item) => {
const id = item?.cooperationId || item?.ID || item?.id || item?.limitId;
if (!id) return;
const encodedId = (() => {
const s = String(id).trim();
if (!s) return "";
try { return btoa(encodeURIComponent(s)); } catch (_) { return s; }
})();
if (!encodedId) return;
const curRoute = router.resolve({
name: "CooperationRestrictionsDetail",
query: { id },
query: { id: encodedId },
});
window.open(curRoute.href, "_blank");
};
......
......@@ -138,6 +138,15 @@ const getMainDataList = async () => {
const router = useRouter();
const encodeBase64Param = (val) => {
const s = String(val ?? "").trim();
if (!s) return "";
try {
return btoa(encodeURIComponent(s));
} catch (_) {
return s;
}
};
const handleClick = item => {
const id = item?.id || item?.limitId || item?.ID;
if (!id) return;
......@@ -145,10 +154,12 @@ const handleClick = item => {
"cooperationRestrictionsTabName",
item?.limitName || item?.title || item?.name || ""
);
const encodedId = encodeBase64Param(id);
if (!encodedId) return;
const routeData = router.resolve({
name: "CooperationRestrictionsDetail",
query: {
id
id: encodedId
}
});
window.open(routeData.href, "_blank");
......
......@@ -106,6 +106,28 @@ import { getCoopRestrictionIntroduction, getCoopRestrictionRelated, getCoopRestr
const route = useRoute();
const router = useRouter();
const decodeQueryId = (raw) => {
if (raw == null) return null;
const s0 = String(raw).trim();
if (!s0) return null;
// 明文数字直接返回
if (/^\d+$/.test(s0)) return s0;
// base64(encodeURIComponent(id)) 解码(兼容短 base64:Mg==)
if (/^[A-Za-z0-9+/_-]+={0,2}$/.test(s0)) {
try {
const normalized = s0.replace(/-/g, "+").replace(/_/g, "/");
const padded = normalized + "===".slice((normalized.length + 3) % 4);
const decoded = atob(padded);
try {
return decodeURIComponent(decoded);
} catch (_) {
return decoded;
}
} catch (_) { }
}
return s0;
};
const limitId = computed(() => decodeQueryId(route.query?.id));
import defaultImg from "./assets/image01.png"
import defaultCom from "../assets/images/default-icon2.png"
import Harvard from "./assets/哈佛.png";
......@@ -130,10 +152,11 @@ const handleOpenWrittingAsstaint = () => {
// 合作限制-查询限制条款
const limitClauseData = ref([]);
const getlimitClauseData = async () => {
if (!route.query.id) return;
const id = limitId.value;
if (!id) return;
try {
const res = await getCoopRestrictionClause({
limitId: route.query.id
limitId: id
});
if (res && res.code === 200) {
// 兼容后端返回:数组 / 单对象 / 包一层 data
......@@ -153,10 +176,11 @@ const getlimitClauseData = async () => {
// 合作限制-查询背景分析
const backgroundList = ref([]);
const getbackgroundData = async () => {
if (!route.query.id) return;
const id = limitId.value;
if (!id) return;
try {
const res = await getCoopRestrictionBackground({
limitId: route.query.id
limitId: id
});
if (res && res.code === 200) {
backgroundList.value = res.data || [];
......@@ -174,10 +198,11 @@ const getbackgroundData = async () => {
// 合作限制-查询相关实体
const coopRelatedData = ref([]);
const getcoopRelatedData = async () => {
if (!route.query.id) return;
const id = limitId.value;
if (!id) return;
try {
const res = await getCoopRestrictionRelated({
limitId: route.query.id
limitId: id
});
if (res && res.code === 200) {
// 展示图片:优先后端返回的 imageUrl,其次用已有 img 字段,再兜底默认图
......@@ -200,7 +225,17 @@ const handleClickOnEntity = (item) => {
if (entityType === "P") {
const personId = item?.PERSONID || item?.ENTITYID || item?.id;
if (!personId) return;
const url = `http://localhost:3000/characterPage?type=2&personId=${encodeURIComponent(personId)}`;
const encodedPersonId = (() => {
const s = String(personId ?? "").trim();
if (!s) return "";
try {
return btoa(encodeURIComponent(s));
} catch (_) {
return s;
}
})();
if (!encodedPersonId) return;
const url = `http://localhost:3000/characterPage?type=2&personId=${encodeURIComponent(encodedPersonId)}`;
window.open(url, "_blank");
return;
}
......@@ -216,10 +251,11 @@ const handleClickOnEntity = (item) => {
// 合作限制-查询简介接口
const coopData = ref({});
const getCoopRestrictionIntroductionData = async () => {
if (!route.query.id) return;
const id = limitId.value;
if (!id) return;
try {
const res = await getCoopRestrictionIntroduction({
limitId: route.query.id
limitId: id
});
if (res && res.code === 200) {
coopData.value = res.data || {};
......@@ -239,13 +275,19 @@ const handleClick = () => {
let path = "";
let query = {};
const encodedRelationId = (() => {
const s = String(relation.RELATIONID ?? "").trim();
if (!s) return "";
try { return btoa(encodeURIComponent(s)); } catch (_) { return s; }
})();
if (!encodedRelationId) return;
if (relation.TYPE === "行政令") {
path = "/decreeLayout/overview/introduction";
query = { id: relation.RELATIONID };
query = { id: encodedRelationId };
} else if (relation.TYPE === "法案") {
path = "/billLayout/bill/introduction";
query = { billId: relation.RELATIONID };
query = { billId: encodedRelationId };
}
if (path) {
......@@ -264,7 +306,7 @@ const handleClickOnLimitOrg = () => {
// 监听路由 id 变化,自动刷新数据
watch(
() => route.query.id,
() => limitId.value,
(newId) => {
if (newId) {
getCoopRestrictionIntroductionData();
......
......@@ -172,6 +172,7 @@ import InputBox from "../components/InputBox/index.vue";
import DataChartSwitchBox from '../components/dataChartSwitchBox/index.vue'
import { useRoute } from "vue-router";
import router from "@/router";
import { getDecodedParams } from "@/utils/goToPage";
import { search, getThinkTankList } from "@/api/comprehensiveSearch";
import { ElMessage } from "element-plus";
......@@ -912,29 +913,31 @@ const handleDownloadCurChartData = () => {
const initParam = () => {
const hasQuery = Object.keys(route.query).length > 0;
if (hasQuery) {
if (route.query.selectedAreaList) {
selectedArea.value = JSON.parse(route.query.selectedAreaList)
const decodedQuery = route.query.data ? (getDecodedParams() || {}) : null;
const query = decodedQuery && typeof decodedQuery === "object" ? decodedQuery : route.query;
if (query.selectedAreaList) {
selectedArea.value = JSON.parse(query.selectedAreaList)
} else {
selectedArea.value = route.query.domains ? [route.query.domains] : ['全部领域']
selectedArea.value = query.domains ? [query.domains] : ['全部领域']
}
if (
route.query.selectedDate &&
Array.isArray(JSON.parse(route.query.selectedDate)) &&
JSON.parse(route.query.selectedDate).length
query.selectedDate &&
Array.isArray(JSON.parse(query.selectedDate)) &&
JSON.parse(query.selectedDate).length
) {
selectedDate.value = "自定义";
customTime.value = JSON.parse(route.query.selectedDate);
customTime.value = JSON.parse(query.selectedDate);
}
selectedThinkTank.value = route.query.orgnizationName ? route.query.orgnizationName : "全部智库";
selectedThinkTank.value = query.orgnizationName ? query.orgnizationName : "全部智库";
isInvolveCn.value = route.query.isInvolveCn ? true : false;
isInvolveCn.value = query.isInvolveCn ? true : false;
reportName.value = route.query.reportName ? route.query.reportName : "";
reportName.value = query.reportName ? query.reportName : "";
const query = route.query;
if (Object.keys(query).length > 0) {
if (query && Object.keys(query).length > 0) {
sessionStorage.setItem("thinktankRouteQuery", JSON.stringify(query));
}
} else {
......@@ -958,16 +961,28 @@ const initParam = () => {
}
};
// 跳转政令详情
const encodeBase64Param = (val) => {
const s = String(val ?? "").trim();
if (!s) return "";
try {
return btoa(encodeURIComponent(s));
} catch (_) {
return s;
}
};
// 跳转报告详情
const handleClickToDetail = curReport => {
console.log("curReport", curReport);
window.sessionStorage.setItem("billId", curReport.id);
window.sessionStorage.setItem("curTabName", curReport.title);
const encodedId = encodeBase64Param(curReport?.id);
if (!encodedId) return;
const route = router.resolve({
name: "ReportDetail",
params: {
id: curReport.id
id: encodedId
}
});
window.open(route.href, "_blank");
......
......@@ -50,7 +50,7 @@
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount, reactive } from "vue";
import { ref, onMounted, onBeforeUnmount, reactive, computed } from "vue";
import { useRoute } from "vue-router";
import router from "@/router";
import * as G6 from '@antv/g6';
......@@ -63,6 +63,34 @@ import icon1629 from "./assets/icons/icon1629.png";
const route = useRoute();
const decodeMaybeBase64NumericId = (raw) => {
if (raw == null) return "";
let s0 = String(raw).trim();
if (!s0) return "";
if (s0.includes("%")) {
try {
const decodedOnce = decodeURIComponent(s0);
if (decodedOnce) s0 = String(decodedOnce).trim();
} catch (_) { }
}
if (/^\d+$/.test(s0)) return s0;
if (/^[A-Za-z0-9+/_-]+={0,2}$/.test(s0)) {
try {
const normalized = s0.replace(/-/g, "+").replace(/_/g, "/");
const padded = normalized + "===".slice((normalized.length + 3) % 4);
const decoded = atob(padded);
const decodedStr = (() => {
try { return decodeURIComponent(decoded); } catch (_) { return decoded; }
})();
if (/^\d+$/.test(String(decodedStr).trim())) {
return String(decodedStr).trim();
}
} catch (_) { }
}
return s0;
};
const decreeId = computed(() => decodeMaybeBase64NumericId(route.query.id));
// 关联关系
const dialogVisible = ref(false);
......@@ -71,12 +99,14 @@ const mainInfo = ref({ label: "", time: "", id: "" });
const nodeInfo = ref({});
const onDecreeSummaryData = async () => {
try {
const res = await getDecreeSummary({id: route.query.id});
const id = decreeId.value;
if (!id) return;
const res = await getDecreeSummary({id});
console.log("基本信息", res);
if (res.code===200 && res.data) {
mainInfo.value.label = res.data.name;
mainInfo.value.time = res.data.postDate;
mainInfo.value.id = route.query.id;
mainInfo.value.id = id;
}
} catch (error) {
mainInfo.value = { label: "", time: "", id: "" };
......@@ -93,7 +123,9 @@ const handleClickSider = async (item) => {
};
const handleGetRelateOrder = async () => {
try {
const res = await getDecreeRelatedOrder({id: route.query.id});
const id = decreeId.value;
if (!id) return;
const res = await getDecreeRelatedOrder({id});
console.log("相关政令", res);
if (res.code===200 && res.data?.length) {
siderList.value = res.data
......@@ -140,7 +172,7 @@ const initGraphChart = () => {
const onFormatLink = (item, index) => {
return {
id: `link-${index+1}`,
source: route.query.id, target: item.id+'',
source: decreeId.value, target: item.id+'',
label: { show: true, color: "#055fc2", backgroundColor: "#eef7ff", borderWidth: 0, offset: [0, 15], formatter: item.relation },
lineStyle: { color: '#B9DCFF', type: "solid", opacity: 1 }
}
......
......@@ -73,7 +73,7 @@
</template>
<script setup>
import { ref, onMounted } from "vue";
import { ref, onMounted, computed } from "vue";
import router from "@/router";
import { useRoute } from "vue-router";
import { getDecreeSummary } from "@/api/decree/introduction";
......@@ -88,7 +88,33 @@ import USALogo from "./assets/images/USA-logo.png";
const route = useRoute();
const decreeId = ref(route.query.id);
const decodeMaybeBase64NumericId = (raw) => {
if (raw == null) return "";
let s0 = String(raw).trim();
if (!s0) return "";
if (s0.includes("%")) {
try {
const decodedOnce = decodeURIComponent(s0);
if (decodedOnce) s0 = String(decodedOnce).trim();
} catch (_) { }
}
if (/^\d+$/.test(s0)) return s0;
if (/^[A-Za-z0-9+/_-]+={0,2}$/.test(s0)) {
try {
const normalized = s0.replace(/-/g, "+").replace(/_/g, "/");
const padded = normalized + "===".slice((normalized.length + 3) % 4);
const decoded = atob(padded);
const decodedStr = (() => {
try { return decodeURIComponent(decoded); } catch (_) { return decoded; }
})();
if (/^\d+$/.test(String(decodedStr).trim())) {
return String(decodedStr).trim();
}
} catch (_) { }
}
return s0;
};
const decreeId = computed(() => decodeMaybeBase64NumericId(route.query.id));
// const activeName = ref("分析报告");
// const handleSwitchActiveName = name => {
......@@ -144,7 +170,9 @@ const summaryInfo = ref({});
let pageTitle = "科技政令主页"
const handleGetSummary = async () => {
try {
const res = await getDecreeSummary({ id: route.query.id });
const id = decreeId.value;
if (!id) return;
const res = await getDecreeSummary({ id });
console.log("全局信息", res);
if (res.code === 200 && res.data) {
summaryInfo.value = res.data;
......@@ -158,7 +186,7 @@ const handleShowReport = () => {
const curRoute = router.resolve({
path: "/decree/decreeOriginal",
query: {
id: route.query.id
id: decreeId.value
}
});
window.open(curRoute.href, "_blank");
......@@ -185,7 +213,7 @@ const handleAnalysisClick = () => {
path: "/writtingAsstaint",
query: {
topic: "政令",
fileId: route.query.id
fileId: decreeId.value
}
});
};
......
......@@ -92,7 +92,7 @@
</template>
<script setup>
import { ref, onMounted } from "vue";
import { ref, onMounted, computed } from "vue";
import { useRoute } from "vue-router";
import { getDecreeBackground, getDecreeDepend, getDecreePrev } from "@/api/decree/background";
import router from "@/router";
......@@ -101,7 +101,31 @@ import DefaultIcon1 from "@/assets/icons/default-icon1.png";
const route = useRoute();
const decreeId = ref(route.query.id);
const decodeMaybeBase64NumericId = (raw) => {
if (raw == null) return "";
let s0 = String(raw).trim();
if (!s0) return "";
if (s0.includes("%")) {
try {
const decodedOnce = decodeURIComponent(s0);
if (decodedOnce) s0 = String(decodedOnce).trim();
} catch (_) { }
}
if (/^\d+$/.test(s0)) return s0;
if (/^[A-Za-z0-9+/_-]+={0,2}$/.test(s0)) {
try {
const normalized = s0.replace(/-/g, "+").replace(/_/g, "/");
const padded = normalized + "===".slice((normalized.length + 3) % 4);
const decoded = atob(padded);
const decodedStr = (() => {
try { return decodeURIComponent(decoded); } catch (_) { return decoded; }
})();
if (/^\d+$/.test(String(decodedStr).trim())) return String(decodedStr).trim();
} catch (_) { }
}
return s0;
};
const decreeId = computed(() => decodeMaybeBase64NumericId(route.query.id));
// 提出背景
const box1BtnList = ref(["涉华背景", "全部背景"]);
......
......@@ -9,13 +9,39 @@
</div>
</template>
<script setup>
import { ref, onMounted } from "vue";
import { ref, onMounted, computed } from "vue";
import router from "@/router";
import { useRoute } from "vue-router";
import SiderTabs from "@/components/base/SiderTabs/index.vue";
const route = useRoute();
const decreeId = ref(route.query.id);
const decodeMaybeBase64NumericId = (raw) => {
if (raw == null) return "";
let s0 = String(raw).trim();
if (!s0) return "";
if (s0.includes("%")) {
try {
const decodedOnce = decodeURIComponent(s0);
if (decodedOnce) s0 = String(decodedOnce).trim();
} catch (_) { }
}
if (/^\d+$/.test(s0)) return s0;
if (/^[A-Za-z0-9+/_-]+={0,2}$/.test(s0)) {
try {
const normalized = s0.replace(/-/g, "+").replace(/_/g, "/");
const padded = normalized + "===".slice((normalized.length + 3) % 4);
const decoded = atob(padded);
const decodedStr = (() => {
try { return decodeURIComponent(decoded); } catch (_) { return decoded; }
})();
if (/^\d+$/.test(String(decodedStr).trim())) return String(decodedStr).trim();
} catch (_) { }
}
return s0;
};
// rawId 用于路由展示(允许加密),decreeId 用于接口调用(只用明文数字)
const rawId = computed(() => (route.query.id == null ? "" : String(route.query.id)));
const decreeId = computed(() => decodeMaybeBase64NumericId(route.query.id));
const siderList = ref([
{
......@@ -49,7 +75,7 @@ const handleClickLeftSiderBtn = node => {
router.push({
path: node.path,
query: {
id: decreeId.value
id: rawId.value
}
});
};
......
......@@ -181,7 +181,43 @@ import { useGotoNewsDetail } from '@/router/modules/news';
const gotoNewsDetail = useGotoNewsDetail()
const route = useRoute();
const decreeId = ref(route.query.id);
const decodeMaybeBase64 = (raw) => {
if (raw == null) return "";
let s0 = String(raw).trim();
if (!s0) return "";
// 兼容 query 里被 URL 编码的 base64(例如 OTg%3D)
if (s0.includes("%")) {
try {
const decodedOnce = decodeURIComponent(s0);
if (decodedOnce) {
s0 = String(decodedOnce).trim();
}
} catch (_) { }
}
// 明文数字直接返回
if (/^\d+$/.test(s0)) return s0;
// base64(encodeURIComponent(id)) 解码(兼容短 base64)
if (/^[A-Za-z0-9+/_-]+={0,2}$/.test(s0)) {
try {
const normalized = s0.replace(/-/g, "+").replace(/_/g, "/");
const padded = normalized + "===".slice((normalized.length + 3) % 4);
const decoded = atob(padded);
const decodedStr = (() => {
try {
return decodeURIComponent(decoded);
} catch (_) {
return decoded;
}
})();
// 只在“解出来还是纯数字”时才视为合作限制/智库的加密 id,避免误解码影响其它模块
if (/^\d+$/.test(String(decodedStr).trim())) {
return String(decodedStr).trim();
}
} catch (_) { }
}
return s0;
};
const decreeId = ref(decodeMaybeBase64(route.query.id));
// 风险警告
const riskInfo = ref({
......
......@@ -144,7 +144,7 @@
</template>
<script setup>
import { ref, onMounted, reactive } from "vue";
import { ref, onMounted, reactive, computed } from "vue";
import { useRoute } from "vue-router";
import { ElMessage } from "element-plus";
import router from "@/router";
......@@ -161,6 +161,32 @@ import { onNumToChinese } from "@/views/marketAccessRestrictions/utils/index"
const route = useRoute();
const decodeMaybeBase64NumericId = (raw) => {
if (raw == null) return "";
let s0 = String(raw).trim();
if (!s0) return "";
if (s0.includes("%")) {
try {
const decodedOnce = decodeURIComponent(s0);
if (decodedOnce) s0 = String(decodedOnce).trim();
} catch (_) { }
}
if (/^\d+$/.test(s0)) return s0;
if (/^[A-Za-z0-9+/_-]+={0,2}$/.test(s0)) {
try {
const normalized = s0.replace(/-/g, "+").replace(/_/g, "/");
const padded = normalized + "===".slice((normalized.length + 3) % 4);
const decoded = atob(padded);
const decodedStr = (() => {
try { return decodeURIComponent(decoded); } catch (_) { return decoded; }
})();
if (/^\d+$/.test(String(decodedStr).trim())) return String(decodedStr).trim();
} catch (_) { }
}
return s0;
};
const decreeId = computed(() => decodeMaybeBase64NumericId(route.query.id));
const handleClickToolBox = () => {
ElMessage.warning("当前功能正在开发中,敬请期待!");
};
......@@ -191,7 +217,9 @@ const ALPHABET = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m
const onMainContentData = async () => {
try {
const keyword = commandWord.value;
const res = await getDecreeMainContent({ id: route.query.id, keyword, domainId: areaType.value });
const id = decreeId.value;
if (!id) return;
const res = await getDecreeMainContent({ id, keyword, domainId: areaType.value });
console.log("主要指令", res);
if (res && res.code === 200) {
contentList.value = res.data || [];
......@@ -234,7 +262,9 @@ const onDecreeMindMap = async () => {
}
isTreeDialog.value = true;
try {
let res = await getDecreeMindMap({ id: route.query.id });
const id = decreeId.value;
if (!id) return;
let res = await getDecreeMindMap({ id });
console.log("思维导图", res);
if (res.code === 200) {
let nodes = []
......@@ -280,7 +310,9 @@ const onUniqueArray = (list, key = 'id') => {
const entityList = ref([]);
const onRelatedEntityData = async () => {
try {
const res = await getDecreeRelatedEntity({ id: route.query.id });
const id = decreeId.value;
if (!id) return;
const res = await getDecreeRelatedEntity({ id });
console.log("相关实体", res);
if (res && res.code === 200) {
entityList.value = res.data;
......@@ -300,7 +332,9 @@ const organizationInfo = reactive({
})
const handleGetOrgnization = async () => {
try {
const res = await getDecreeOrganization({ id: route.query.id });
const id = decreeId.value;
if (!id) return;
const res = await getDecreeOrganization({ id });
console.log("执行机构", res);
if (res.code === 200 && res.data?.length) {
organizationInfo.list = res.data;
......
......@@ -33,7 +33,7 @@
</template>
<script setup>
import { ref, onMounted } from "vue";
import { ref, onMounted, computed } from "vue";
import { useRoute } from "vue-router";
import { ElMessage } from "element-plus";
import { getDecreeSummary } from "@/api/decree/introduction";
......@@ -41,6 +41,33 @@ import { getDecreeReport } from "@/api/decree/introduction";
import newOriginal from "@/components/base/DecreeOriginal/newOriginal.vue";
const route = useRoute();
const decodeMaybeBase64NumericId = (raw) => {
if (raw == null) return "";
let s0 = String(raw).trim();
if (!s0) return "";
if (s0.includes("%")) {
try {
const decodedOnce = decodeURIComponent(s0);
if (decodedOnce) s0 = String(decodedOnce).trim();
} catch (_) { }
}
if (/^\d+$/.test(s0)) return s0;
if (/^[A-Za-z0-9+/_-]+={0,2}$/.test(s0)) {
try {
const normalized = s0.replace(/-/g, "+").replace(/_/g, "/");
const padded = normalized + "===".slice((normalized.length + 3) % 4);
const decoded = atob(padded);
const decodedStr = (() => {
try { return decodeURIComponent(decoded); } catch (_) { return decoded; }
})();
if (/^\d+$/.test(String(decodedStr).trim())) {
return String(decodedStr).trim();
}
} catch (_) { }
}
return s0;
};
const decreeId = computed(() => decodeMaybeBase64NumericId(route.query.id));
let pdfUrl = "";
const handleDownload = async () => {
if (pdfUrl) {
......@@ -85,9 +112,9 @@ const handleDownload = async () => {
// 获取全局信息
const summaryInfo = ref({});
const handleGetSummary = async () => {
const params = {
id: route.query.id
};
const id = decreeId.value;
if (!id) return;
const params = { id };
try {
const res = await getDecreeSummary(params);
console.log("全局信息", res);
......@@ -101,7 +128,9 @@ const handleGetSummary = async () => {
const refNewOriginal = ref(null);
const handleGetReport = async () => {
try {
const res = await getDecreeReport({id: route.query.id});
const id = decreeId.value;
if (!id) return;
const res = await getDecreeReport({id});
console.log("报告原文", res);
if (res.code === 200) {
pdfUrl = res.data.pdfUrl;
......
......@@ -122,9 +122,57 @@ const route = useRoute();
const gotoNewsDetail = useGotoNewsDetail();
const gotoSearchResults = useGotoSearchResults();
const decodeMaybeBase64 = (raw) => {
if (raw == null) return null;
let s0 = String(raw).trim();
if (!s0) return null;
// 兼容 URL 里被 encodeURIComponent 的 base64(例如 OTg%3D)
if (s0.includes("%")) {
try {
const decodedOnce = decodeURIComponent(s0);
if (decodedOnce) s0 = String(decodedOnce).trim();
} catch (_) { }
}
// 明显不是 base64 的(例如包含 '-' 的新闻明文 id),直接返回
if (!/^[A-Za-z0-9+/_-]+={0,2}$/.test(s0)) return s0;
const encodeBase64Param = (val) => {
const s = String(val ?? "").trim();
if (!s) return "";
try {
return btoa(encodeURIComponent(s));
} catch (_) {
return s;
}
};
const normalizeBase64 = (s) => {
const normalized = String(s ?? "").replace(/-/g, "+").replace(/_/g, "/");
return normalized + "===".slice((normalized.length + 3) % 4);
};
// base64(encodeURIComponent(id)) 解码:仅在“可逆校验通过”时才当作加密参数
try {
const padded = normalizeBase64(s0);
const decoded = atob(padded);
const decodedStr = (() => {
try {
return decodeURIComponent(decoded);
} catch (_) {
return decoded;
}
})();
const reEncoded = encodeBase64Param(decodedStr);
if (!reEncoded) return s0;
if (normalizeBase64(reEncoded) === padded) {
return decodedStr;
}
} catch (_) { }
return s0;
};
onMounted(async () => {
const params = {
newsId: route.params.id
newsId: decodeMaybeBase64(route.params.id)
};
const { data: newsDetailData } = await getNewsDetail(params);
newsDetail.value = newsDetailData ?? {};
......
......@@ -254,6 +254,70 @@ import TipTab from "@/views/thinkTank/TipTab/index.vue";
const router = useRouter();
const decodeRouteId = (raw) => {
if (raw == null) return null;
const s0 = String(raw);
if (!s0) return null;
// 明文 id(听证会/项目常见为纯数字)直接返回,避免误解码
if (/^\d+$/.test(s0) || /^Rand_/i.test(s0)) {
return s0;
}
const tryParseJson = (str) => {
if (typeof str !== "string") return null;
const s = str.trim();
if (!s) return null;
try {
return JSON.parse(s);
} catch (_) {
return null;
}
};
const isProbablyBase64 = (s) => {
if (!s) return false;
// 支持短 base64(如 "Mg==")
if (s.includes("=")) return true;
if (s.length < 12) return false;
return /^[A-Za-z0-9+/_-]+={0,2}$/.test(s);
};
const tryAtob = (val) => {
if (val == null) return null;
const s = String(val).trim();
if (!s) return null;
if (!isProbablyBase64(s)) return null;
const normalized = s.replace(/-/g, "+").replace(/_/g, "/");
const padded = normalized + "===".slice((normalized.length + 3) % 4);
try {
return atob(padded);
} catch (_) {
return null;
}
};
const atobStr = tryAtob(s0);
if (atobStr != null) {
try {
const decoded = decodeURIComponent(atobStr);
return tryParseJson(decoded) ?? decoded;
} catch (_) {
return tryParseJson(atobStr) ?? atobStr;
}
}
try {
const utf8 = decodeURIComponent(escape(s0));
if (utf8 && utf8 !== s0) {
if (/^\d+$/.test(utf8) || /^Rand_/i.test(utf8)) return utf8;
return tryParseJson(utf8) ?? utf8;
}
} catch (_) { }
return s0;
};
const hearingId = computed(() => decodeRouteId(router.currentRoute.value?.params?.id));
const goToAllThinkTank = () => {
const thinkTankId = props?.thinkInfo?.thinkTankId || props?.thinkInfo?.id;
const route = router.resolve({
......@@ -282,7 +346,7 @@ const applyCongressHearingDocumentTitle = (title) => {
};
const handleGetThinkTankHearingInfo = async () => {
try {
const id = router.currentRoute._value.params.id;
const id = hearingId.value;
if (!id) return;
const res = await getThinkTankHearingInfo({ id });
if (res?.code === 200 && res?.data) {
......@@ -441,7 +505,9 @@ const box1Data =
//获取内容摘要
const handleGetThinkTankReportAbstract = async () => {
try {
const res = await getThinkTankReportAbstract(router.currentRoute._value.params.id);
const id = hearingId.value;
if (!id) return;
const res = await getThinkTankReportAbstract(id);
console.log("内容摘要", res);
if (res.code === 200 && res.data) {
box1Data.value = res.data;
......@@ -502,7 +568,7 @@ const box5WordCloudKey = ref(0);
const handleGetThinkTankReportIndustryCloud = async () => {
try {
const params = {
id: router.currentRoute._value.params.id
id: hearingId.value
// industryId: activeArea.value
};
const res = await getThinkTankHearingCloud(params);
......@@ -529,7 +595,9 @@ const handleGetThinkTankReportIndustryCloud = async () => {
//涉及科技领域
const handleGetThinkTankReportIndustry = async () => {
try {
const res = await getThinkTankReportIndustry(router.currentRoute._value.params.id);
const id = hearingId.value;
if (!id) return;
const res = await getThinkTankReportIndustry(id);
console.log("涉及科技领域", res);
if (res.code === 200 && res.data) {
areaList.value = res.data;
......@@ -569,10 +637,18 @@ const majorOpinions = ref([
]);
//处理点击详情页事件
const handleOpenReportOriginal = item => {
const id = hearingId.value;
if (!id) return;
const encodedId = (() => {
const s = String(id).trim();
if (!s) return "";
try { return btoa(encodeURIComponent(s)); } catch (_) { return s; }
})();
if (!encodedId) return;
const route = router.resolve({
name: "ReportOriginal",
params: {
id: router.currentRoute._value.params.id
id: encodedId
},
query: {
currentPage: currentPage.value,
......@@ -623,7 +699,7 @@ const handleCurrentChange = page => {
const handleGetThinkTankReportViewpoint = async () => {
try {
const params = {
testimonyId: router.currentRoute._value.params.id,
testimonyId: hearingId.value,
pageNum: currentPage.value,
pageSize: pageSize.value,
keyword: (searchOpinions.value || "").trim(),
......
......@@ -473,9 +473,15 @@ const hasReportLinkForSourceView = (sv) => Boolean(String(sv?.report_id ?? "").t
const handleOpenReportOriginalFromSource = (sv) => {
const id = String(sv?.report_id ?? "").trim()
if (!id) return
const encodedId = (() => {
const s = String(id).trim()
if (!s) return ""
try { return btoa(encodeURIComponent(s)) } catch (_) { return s }
})()
if (!encodedId) return
const route = router.resolve({
name: "ReportDetail",
params: { id }
params: { id: encodedId }
})
window.open(route.href, "_blank")
}
......@@ -916,10 +922,16 @@ const handleCurrentChange = page => {
const handleToReportDetail = (item) => {
if (!item?.id) return;
window.sessionStorage.setItem("curTabName", item.name);
const encodedId = (() => {
const s = String(item.id).trim();
if (!s) return "";
try { return btoa(encodeURIComponent(s)); } catch (_) { return s; }
})();
if (!encodedId) return;
const route = router.resolve({
name: "ReportDetail",
params: {
id: item.id
id: encodedId
}
});
window.open(route.href, "_blank");
......
......@@ -85,7 +85,7 @@
</template>
<script setup>
import { ref, onMounted } from "vue";
import { ref, onMounted, computed } from "vue";
import ReportAnalysis from "./reportAnalysis/index.vue";
import PolicyTracking from "./policyTracking/index.vue";
......@@ -93,6 +93,75 @@ import { getThinkTankReportSummary, getThinkTankReportRelated, getThinkTankRepor
import { useRoute, useRouter } from "vue-router";
const router = useRouter();
const route = useRoute();
const decodeRouteId = (raw) => {
if (raw == null) return null;
const s0 = String(raw);
if (!s0) return null;
// 明文 id(常见:Rand_... 或纯数字)直接返回,避免被误判为 base64
if (/^\d+$/.test(s0) || /^Rand_/i.test(s0)) {
return s0;
}
const tryParseJson = (str) => {
if (typeof str !== "string") return null;
const s = str.trim();
if (!s) return null;
try {
return JSON.parse(s);
} catch (_) {
return null;
}
};
const isProbablyBase64 = (s) => {
// 过短的字符串(如 1/2)不参与 base64 解码,避免 atob 误解;
// 但像 "Mg==" 这种带 padding 的短 base64 需要支持
if (!s) return false;
if (s.includes("=")) return true;
if (s.length < 12) return false;
return /^[A-Za-z0-9+/_-]+={0,2}$/.test(s);
};
const tryAtob = (val) => {
if (val == null) return null;
const s = String(val).trim();
if (!s) return null;
if (!isProbablyBase64(s)) return null;
const normalized = s.replace(/-/g, "+").replace(/_/g, "/");
const padded = normalized + "===".slice((normalized.length + 3) % 4);
try {
return atob(padded);
} catch (_) {
return null;
}
};
// 1) 常规:base64(encodeURIComponent(id)) → atob → decodeURIComponent
const atobStr = tryAtob(s0);
if (atobStr != null) {
try {
const decoded = decodeURIComponent(atobStr);
return tryParseJson(decoded) ?? decoded;
} catch (_) {
return tryParseJson(atobStr) ?? atobStr;
}
}
// 2) 兜底:路由可能把二进制串 percent-encode(出现奇怪字符),尝试 latin1→utf8
try {
const utf8 = decodeURIComponent(escape(s0));
if (utf8 && utf8 !== s0) {
if (/^\d+$/.test(utf8) || /^Rand_/i.test(utf8)) return utf8;
return tryParseJson(utf8) ?? utf8;
}
} catch (_) { }
// 3) 明文 id:直接返回
return s0;
};
const reportId = computed(() => decodeRouteId(route.params?.id));
const reportUrl = ref("");
const thinkInfo = ref({});
const reportList = ref({});
......@@ -100,7 +169,9 @@ const reportList = ref({});
// 获取报告全局信息
const handleGetThinkTankReportSummary = async () => {
try {
const res = await getThinkTankReportSummary(router.currentRoute._value.params.id);
const id = reportId.value;
if (!id) return;
const res = await getThinkTankReportSummary(id);
console.log("报告全局信息", res);
if (res.code === 200 && res.data) {
reportUrl.value = res.data.reportUrl;
......@@ -119,7 +190,9 @@ const handleGetThinkTankReportSummary = async () => {
// 获取相关报告信息
const handleGetThinkTankReport = async () => {
try {
const res = await getThinkTankReportRelated(router.currentRoute._value.params.id);
const id = reportId.value;
if (!id) return;
const res = await getThinkTankReportRelated(id);
console.log("报告全局信息", res);
if (res.code === 200 && res.data) {
reportList.value = res.data;
......@@ -130,10 +203,18 @@ const handleGetThinkTankReport = async () => {
};
const toReport = () => {
console.log(reportUrl.value, "reportUrl.valuereportUrl.value");
const id = reportId.value;
if (!id) return;
const encodedId = (() => {
const s = String(id).trim();
if (!s) return "";
try { return btoa(encodeURIComponent(s)); } catch (_) { return s; }
})();
if (!encodedId) return;
const route = router.resolve({
name: "ReportOriginal",
params: {
id: router.currentRoute._value.params.id
id: encodedId
}
});
console.log("route.href", route.href);
......@@ -146,11 +227,13 @@ const switchTab = name => {
};
const handleAnalysisClick = () => {
const id = reportId.value;
if (!id) return;
router.push({
path: "/writtingAsstaint",
query: {
topic: "智库",
fileId: router.currentRoute._value.params.id
fileId: id
}
});
};
......@@ -188,7 +271,9 @@ const downloadOnePdf = async (url, filename) => {
const handleDownloadDocument = async () => {
try {
const { ElMessage } = await import("element-plus");
const res = await getThinkTankReportcontentUrl(router.currentRoute._value.params.id);
const id = reportId.value;
if (!id) return;
const res = await getThinkTankReportcontentUrl(id);
if (res.code !== 200 || !res.data) {
ElMessage.warning("暂无下载链接");
return;
......
......@@ -135,9 +135,56 @@ import {
getThinkTankReportPolicy,
getThinkTankReportPolicyAction
} from "@/api/thinkTank/overview";
import { useRouter } from "vue-router";
import { useRoute, useRouter } from "vue-router";
import DefaultNewsImg from '@/assets/images/default-icon-news.png'
const router = useRouter();
const route = useRoute();
const decodeRouteId = (raw) => {
if (raw == null) return null;
const s0 = String(raw);
if (!s0) return null;
const tryParseJson = (str) => {
if (typeof str !== "string") return null;
const s = str.trim();
if (!s) return null;
try {
return JSON.parse(s);
} catch (_) {
return null;
}
};
const tryAtob = (val) => {
if (val == null) return null;
const s = String(val).trim();
if (!s) return null;
const normalized = s.replace(/-/g, "+").replace(/_/g, "/");
const padded = normalized + "===".slice((normalized.length + 3) % 4);
try {
return atob(padded);
} catch (_) {
return null;
}
};
const atobStr = tryAtob(s0);
if (atobStr != null) {
try {
const decoded = decodeURIComponent(atobStr);
return tryParseJson(decoded) ?? decoded;
} catch (_) {
return tryParseJson(atobStr) ?? atobStr;
}
}
try {
const utf8 = decodeURIComponent(escape(s0));
if (utf8 && utf8 !== s0) {
return tryParseJson(utf8) ?? utf8;
}
} catch (_) { }
return s0;
};
const reportId = computed(() => decodeRouteId(route.params?.id));
const loading = ref(false);
const searchOpinions = ref("");
// 政策建议相关情况(当前页/当前筛选展示的数据)
......@@ -208,10 +255,18 @@ const scrollToWrapTop = () => {
const toReport = () => {
const id = reportId.value;
if (!id) return;
const encodedId = (() => {
const s = String(id).trim();
if (!s) return "";
try { return btoa(encodeURIComponent(s)); } catch (_) { return s; }
})();
if (!encodedId) return;
const route = router.resolve({
name: "ReportOriginal",
params: {
id: router.currentRoute._value.params.id
id: encodedId
}
});
window.open(route.href, "_blank");
......@@ -286,7 +341,7 @@ const handleGetThinkTankReportPolicyAction = async () => {
try {
loading.value = true;
const params = {
reportId: router.currentRoute._value.params.id,
reportId: reportId.value,
// 这里请求全量数据,前端自行分页
currentPage: 0,
pageSize: 1000,
......
......@@ -227,7 +227,7 @@ import {
getThinkTankReportViewpoint
} from "@/api/thinkTank/overview";
import { getChartAnalysis } from "@/api/aiAnalysis/index";
import { useRouter } from "vue-router";
import { useRoute, useRouter } from "vue-router";
import "echarts-wordcloud";
import AiSummary from '@/components/base/Ai/AiSummary/index.vue'
import { getPersonSummaryInfo } from "@/api/common/index";
......@@ -237,6 +237,69 @@ import TipTab from "@/views/thinkTank/TipTab/index.vue";
const router = useRouter();
const route = useRoute();
const decodeRouteId = (raw) => {
if (raw == null) return null;
let s0 = String(raw);
if (!s0) return null;
// 路由参数可能是百分号编码后的“乱码串”,先尝试 decodeURIComponent 还原一层
if (s0.includes("%")) {
try {
const decodedOnce = decodeURIComponent(s0);
if (decodedOnce) {
s0 = decodedOnce;
}
} catch (_) { }
}
// 明文 id(常见:Rand_... 或纯数字)直接返回,避免被误判为 base64
if (/^\d+$/.test(s0) || /^Rand_/i.test(s0)) {
return s0;
}
const tryParseJson = (str) => {
if (typeof str !== "string") return null;
const s = str.trim();
if (!s) return null;
try {
return JSON.parse(s);
} catch (_) {
return null;
}
};
const tryAtob = (val) => {
if (val == null) return null;
const s = String(val).trim();
if (!s) return null;
const normalized = s.replace(/-/g, "+").replace(/_/g, "/");
const padded = normalized + "===".slice((normalized.length + 3) % 4);
try {
return atob(padded);
} catch (_) {
return null;
}
};
const atobStr = tryAtob(s0);
if (atobStr != null) {
try {
const decoded = decodeURIComponent(atobStr);
return tryParseJson(decoded) ?? decoded;
} catch (_) {
return tryParseJson(atobStr) ?? atobStr;
}
}
try {
const utf8 = decodeURIComponent(escape(s0));
if (utf8 && utf8 !== s0) {
if (/^\d+$/.test(utf8) || /^Rand_/i.test(utf8)) return utf8;
return tryParseJson(utf8) ?? utf8;
}
} catch (_) { }
return s0;
};
const reportId = computed(() => decodeRouteId(route.params?.id));
const goToAllThinkTank = () => {
const thinkTankId = props?.thinkInfo?.thinkTankId || props?.thinkInfo?.id;
const route = router.resolve({
......@@ -393,7 +456,9 @@ const box1Data =
//获取内容摘要
const handleGetThinkTankReportAbstract = async () => {
try {
const res = await getThinkTankReportAbstract(router.currentRoute._value.params.id);
const id = reportId.value;
if (!id) return;
const res = await getThinkTankReportAbstract(id);
console.log("内容摘要", res);
if (res.code === 200 && res.data) {
box1Data.value = res.data;
......@@ -454,7 +519,7 @@ const box5WordCloudKey = ref(0);
const handleGetThinkTankReportIndustryCloud = async () => {
try {
const params = {
id: router.currentRoute._value.params.id
id: reportId.value
// industryId: activeArea.value
};
const res = await getThinkTankReportIndustryCloud(params);
......@@ -482,7 +547,9 @@ const handleGetThinkTankReportIndustryCloud = async () => {
//涉及科技领域
const handleGetThinkTankReportIndustry = async () => {
try {
const res = await getThinkTankReportIndustry(router.currentRoute._value.params.id);
const id = reportId.value;
if (!id) return;
const res = await getThinkTankReportIndustry(id);
console.log("涉及科技领域", res);
if (res.code === 200 && res.data) {
areaList.value = res.data;
......@@ -522,10 +589,18 @@ const majorOpinions = ref([
]);
//处理点击详情页事件
const handleOpenReportOriginal = item => {
const id = reportId.value;
if (!id) return;
const encodedId = (() => {
const s = String(id).trim();
if (!s) return "";
try { return btoa(encodeURIComponent(s)); } catch (_) { return s; }
})();
if (!encodedId) return;
const route = router.resolve({
name: "ReportOriginal",
params: {
id: router.currentRoute._value.params.id
id: encodedId
},
query: {
currentPage: currentPage.value,
......@@ -576,7 +651,7 @@ const handleCurrentChange = page => {
const handleGetThinkTankReportViewpoint = async () => {
try {
const params = {
reportId: router.currentRoute._value.params.id,
reportId: reportId.value,
currentPage: currentPage.value - 1,
pageSize: pageSize.value,
keyword: (searchOpinions.value || "").trim(),
......
......@@ -163,7 +163,7 @@ import {
getThinkTankProjectRelated
} from "@/api/thinkTank/overview";
import { getChartAnalysis } from "@/api/aiAnalysis/index";
import { useRouter } from "vue-router";
import { useRoute, useRouter } from "vue-router";
import "echarts-wordcloud";
import AiSummary from '@/components/base/Ai/AiSummary/index.vue'
import { getPersonSummaryInfo } from "@/api/common/index";
......@@ -171,6 +171,69 @@ import AiButton from "@/components/base/Ai/AiButton/index.vue";
import AiPane from "@/components/base/Ai/AiPane/index.vue";
import TipTab from "@/views/thinkTank/TipTab/index.vue";
const router = useRouter();
const route = useRoute();
const decodeRouteId = (raw) => {
if (raw == null) return null;
const s0 = String(raw);
if (!s0) return null;
// 明文 id(调查项目常见为纯数字)直接返回,避免误解码
if (/^\d+$/.test(s0) || /^Rand_/i.test(s0)) {
return s0;
}
const tryParseJson = (str) => {
if (typeof str !== "string") return null;
const s = str.trim();
if (!s) return null;
try {
return JSON.parse(s);
} catch (_) {
return null;
}
};
const isProbablyBase64 = (s) => {
if (!s) return false;
// 支持短 base64(如 "Mg==")
if (s.includes("=")) return true;
if (s.length < 12) return false;
return /^[A-Za-z0-9+/_-]+={0,2}$/.test(s);
};
const tryAtob = (val) => {
if (val == null) return null;
const s = String(val).trim();
if (!s) return null;
if (!isProbablyBase64(s)) return null;
const normalized = s.replace(/-/g, "+").replace(/_/g, "/");
const padded = normalized + "===".slice((normalized.length + 3) % 4);
try {
return atob(padded);
} catch (_) {
return null;
}
};
const atobStr = tryAtob(s0);
if (atobStr != null) {
try {
const decoded = decodeURIComponent(atobStr);
return tryParseJson(decoded) ?? decoded;
} catch (_) {
return tryParseJson(atobStr) ?? atobStr;
}
}
try {
const utf8 = decodeURIComponent(escape(s0));
if (utf8 && utf8 !== s0) {
if (/^\d+$/.test(utf8) || /^Rand_/i.test(utf8)) return utf8;
return tryParseJson(utf8) ?? utf8;
}
} catch (_) { }
return s0;
};
const projectId = computed(() => decodeRouteId(route.params?.id));
const thinkInfo = ref({
......@@ -241,7 +304,9 @@ const formatDate = (dateStr) => {
// 获取项目报告信息
const handleGetThinkTankReport = async () => {
try {
const res = await getThinkTankProjectRelated(router.currentRoute._value.params.id);
const id = projectId.value;
if (!id) return;
const res = await getThinkTankProjectRelated(id);
console.log("报告全局信息", res);
if (res.code === 200 && res.data) {
reportList.value = Array.isArray(res.data) ? res.data : [];
......@@ -294,7 +359,7 @@ const box1Data =
// 获取调查项目详情(header/摘要/背景)
const handleGetThinkTankProjectsInfo = async () => {
try {
const id = router.currentRoute._value.params.id;
const id = projectId.value;
if (!id) return;
const res = await getThinkTankProjectsInfo({ id });
if (res?.code === 200 && res?.data) {
......@@ -318,7 +383,7 @@ const handleGetThinkTankProjectsInfo = async () => {
};
const handleGetThinkTankProjectsAuthor = async () => {
try {
const id = router.currentRoute._value.params.id;
const id = projectId.value;
if (!id) return;
const res = await getThinkTankProjectsAuthors({ id });
if (res?.code === 200 && res?.data) {
......@@ -334,7 +399,9 @@ const handleGetThinkTankProjectsAuthor = async () => {
//获取内容摘要
const handleGetThinkTankReportAbstract = async () => {
try {
const res = await getThinkTankReportAbstract(router.currentRoute._value.params.id);
const id = projectId.value;
if (!id) return;
const res = await getThinkTankReportAbstract(id);
console.log("内容摘要", res);
if (res.code === 200 && res.data) {
box1Data.value = res.data;
......@@ -395,7 +462,7 @@ const box5WordCloudKey = ref(0);
const handleGetThinkTankReportIndustryCloud = async () => {
try {
const params = {
id: router.currentRoute._value.params.id
id: projectId.value
// industryId: activeArea.value
};
const res = await getThinkTankProjectCloud(params);
......@@ -422,7 +489,9 @@ const handleGetThinkTankReportIndustryCloud = async () => {
//涉及科技领域
const handleGetThinkTankReportIndustry = async () => {
try {
const res = await getThinkTankReportIndustry(router.currentRoute._value.params.id);
const id = projectId.value;
if (!id) return;
const res = await getThinkTankReportIndustry(id);
console.log("涉及科技领域", res);
if (res.code === 200 && res.data) {
areaList.value = res.data;
......@@ -462,10 +531,18 @@ const majorOpinions = ref([
]);
//处理点击详情页事件
const handleOpenReportOriginal = item => {
const id = projectId.value;
if (!id) return;
const encodedId = (() => {
const s = String(id).trim();
if (!s) return "";
try { return btoa(encodeURIComponent(s)); } catch (_) { return s; }
})();
if (!encodedId) return;
const route = router.resolve({
name: "ReportOriginal",
params: {
id: router.currentRoute._value.params.id
id: encodedId
},
query: {
currentPage: currentPage.value,
......@@ -491,7 +568,7 @@ const total = ref(0);
const handleGetThinkTankReportViewpoint = async () => {
try {
const params = {
reportId: router.currentRoute._value.params.id,
reportId: projectId.value,
currentPage: currentPage.value - 1,
pageSize: pageSize.value,
keyword: (searchOpinions.value || "").trim(),
......
......@@ -1293,10 +1293,16 @@ function mapPolicyRowToView(row) {
const toDetail = item => {
window.sessionStorage.setItem("curTabName", item.contentZh ?? item.content ?? "");
const encodedId = (() => {
const s = String(item?.reportId ?? "").trim();
if (!s) return "";
try { return btoa(encodeURIComponent(s)); } catch (_) { return s; }
})();
if (!encodedId) return;
const route = router.resolve({
name: "ReportDetail",
params: {
id: item.reportId
id: encodedId
}
});
window.open(route.href, "_blank");
......
......@@ -48,7 +48,7 @@
</template>
<script setup>
import { ref, reactive, onMounted, nextTick } from "vue";
import { ref, reactive, onMounted, nextTick, computed } from "vue";
import SurveyForm from "./SurveyForm/index.vue"
import TimeSortSelectBox from "@/components/base/TimeSortSelectBox/index.vue";
// import Img1 from "./images/img1.png";
......@@ -82,7 +82,7 @@ import { getDecodedParams } from "@/utils/goToPage";
import ThinkTankReport from "./ThinkTankReport/index.vue";
import CongressHearing from "./CongressHearing/index.vue";
const router = useRouter();
const thinkTankId = getDecodedParams();
const thinkTankId = computed(() => getDecodedParams());
const isThinkTankReport = ref(true);
const isSurveyForm = ref(false);
const isCongressHearing = ref(false);
......@@ -94,10 +94,16 @@ const isCongressHearingLoading = ref(false);
const handleToReportDetail = (item) => {
window.sessionStorage.setItem('curTabName', item.name)
const encodedId = (() => {
const s = String(item?.id ?? "").trim();
if (!s) return "";
try { return btoa(encodeURIComponent(s)); } catch (_) { return s; }
})();
if (!encodedId) return;
const route = router.resolve({
name: 'ReportDetail',
params: {
id: item.id
id: encodedId
}
});
window.open(route.href, "_blank");
......@@ -107,21 +113,33 @@ const handleToHearingDetail = item => {
const id = item?.id;
if (!id) return;
window.sessionStorage.setItem('curTabName', item?.title || item?.name || "");
const encodedId = (() => {
const s = String(id).trim();
if (!s) return "";
try { return btoa(encodeURIComponent(s)); } catch (_) { return s; }
})();
if (!encodedId) return;
const route = router.resolve({
name: "CongressHearingView",
params: {
id
id: encodedId
}
});
window.open(route.href, "_blank");
};
const handleToProjectDetail = (item) => {
window.sessionStorage.setItem('curTabName', item.name)
const encodedId = (() => {
const s = String(item?.id ?? "").trim();
if (!s) return "";
try { return btoa(encodeURIComponent(s)); } catch (_) { return s; }
})();
if (!encodedId) return;
const route = router.resolve({
name: 'SurveyProjectView',
params: {
id: item.id
id: encodedId
}
});
window.open(route.href, "_blank");
......@@ -426,7 +444,7 @@ const handleGetThinkDynamicsReport = async (payload) => {
curFooterList.value = [];
curFooterProjectList.value = [];
const res = await getThinkTankTestimoniesByThinkTankId({
thinkTankId,
thinkTankId: thinkTankId.value,
pageNum: Math.max(0, (currentPage.value || 1)),
pageSize: 10,
// 国会听证会:排序语义与其它资源库相反(正序→desc,倒序→asc)
......@@ -452,7 +470,7 @@ const handleGetThinkDynamicsReport = async (payload) => {
// 调查项目:用新接口 /think-tank/{thinkTankId}/projects
curFooterList.value = [];
const res = await getThinkTankProjectsByThinkTankId({
thinkTankId,
thinkTankId: thinkTankId.value,
pageNum: currentPage.value,
pageSize: 12,
sortFun: sort.value === true,
......@@ -482,8 +500,8 @@ const handleGetThinkDynamicsReport = async (payload) => {
startDate,
endDate
};
if (thinkTankId) {
params.thinkTankId = thinkTankId;
if (thinkTankId.value) {
params.thinkTankId = thinkTankId.value;
}
if (keyword) {
params.keyword = keyword;
......
......@@ -128,9 +128,15 @@ const router = useRouter();
const handleOpenReportOriginal = (item) => {
const reportId = item?.reportId || item?.report_id || item?.id
if (!reportId) return
const encodedId = (() => {
const s = String(reportId).trim();
if (!s) return "";
try { return btoa(encodeURIComponent(s)); } catch (_) { return s; }
})();
if (!encodedId) return
const route = router.resolve({
name: "ReportDetail",
params: { id: String(reportId) }
params: { id: encodedId }
})
window.open(route.href, "_blank")
}
......
......@@ -216,7 +216,7 @@
</div>
<DivideHeader id="position2" class="divide-header" :titleText="'资讯要闻'"></DivideHeader>
<div class="center-center">
<NewsList :newsList="newsList" @item-click="item => gotoNewsDetail(item.newsId)"
<NewsList :newsList="newsList" @item-click="item => gotoNewsDetailEncrypted(item.newsId)"
@more-click="handleToMoreNews" img="newsImage" title="newsTitle" content="newsContent" from="from" />
<MessageBubble :messageList="messageList" imageUrl="personImage" @more-click="handleToSocialDetail"
@person-click="handleClickPerson" name="personName" content="remarks" source="orgName" />
......@@ -566,6 +566,23 @@ const handleSwitchAiContentShowBox7 = (val) => {
isBox7InterpretLoading.value = false;
}
};
const encodeBase64Param = (val) => {
const s = String(val ?? "").trim();
if (!s) return "";
try {
return btoa(encodeURIComponent(s));
} catch (_) {
return s;
}
};
// 智库-新闻资讯:新闻 id 加密后跳转(newsDetail 页面会做兼容解密)
const gotoNewsDetailEncrypted = (newsId) => {
const encoded = encodeBase64Param(newsId);
if (!encoded) return;
gotoNewsDetail(encoded);
};
const handleGetAllThinkTankList = async () => {
try {
const res = await getAllThinkTankList({
......@@ -781,10 +798,12 @@ const handleClickToDetail = () => {
const toDetaile = () => {
window.sessionStorage.setItem("curTabName", box1Data.value[box1DataIndex.value].reportName);
const encodedId = encodeBase64Param(box1Data.value[box1DataIndex.value].reportId);
if (!encodedId) return;
const route = router.resolve({
name: "ReportDetail",
params: {
id: box1Data.value[box1DataIndex.value].reportId
id: encodedId
}
});
window.open(route.href, "_blank");
......@@ -1780,9 +1799,11 @@ const handleBox8ToDataLibrary = (item) => {
const selectParam = {
reportName: item.clause
}
const jsonStr = JSON.stringify(selectParam);
const base64 = btoa(encodeURIComponent(jsonStr));
const route = router.resolve({
path: "/dataLibrary/dataThinkTank",
query: selectParam
query: { data: base64 }
});
window.open(route.href, "_blank");
......@@ -1873,10 +1894,12 @@ const handleGetHylyList = async () => {
};
// 查看社交媒体详情
const handleToSocialDetail = item => {
const encodedPersonId = encodeBase64Param(item?.id);
if (!encodedPersonId) return;
const route = router.resolve({
path: "/characterPage",
query: {
personId: item.id
personId: encodedPersonId
}
});
window.open(route.href, "_blank");
......@@ -2351,11 +2374,13 @@ const handleClickPerson = async item => {
return;
}
window.sessionStorage.setItem("curTabName", item.personName);
const encodedPersonId = encodeBase64Param(item?.personId);
if (!encodedPersonId) return;
const route = router.resolve({
path: "/characterPage",
query: {
type: type, // type=1为科技企业领袖,2为国会议员,3为智库研究人员
personId: item.personId
personId: encodedPersonId
}
});
window.open(route.href, "_blank");
......@@ -2373,30 +2398,36 @@ const handleClickPerson = async item => {
const handleToReportDetail = item => {
window.sessionStorage.setItem("curTabName", item.name);
const encodedId = encodeBase64Param(item?.id);
if (!encodedId) return;
const route = router.resolve({
name: "ReportDetail",
params: {
id: item.id
id: encodedId
}
});
window.open(route.href, "_blank");
};
const handleToHearingDetail = item => {
window.sessionStorage.setItem("curTabName", item.titleZh);
const encodedId = encodeBase64Param(item?.id);
if (!encodedId) return;
const route = router.resolve({
name: "CongressHearingView",
params: {
id: item.id
id: encodedId
}
});
window.open(route.href, "_blank");
};
const handleToSurveyProjectView = item => {
window.sessionStorage.setItem("curTabName", item.name);
const encodedId = encodeBase64Param(item?.id);
if (!encodedId) return;
const route = router.resolve({
name: "SurveyProjectView",
params: {
id: item.id
id: encodedId
}
});
window.open(route.href, "_blank");
......
......@@ -89,6 +89,71 @@ import { useRoute, useRouter } from "vue-router";
const router = useRouter();
const route = useRoute();
const decodeRouteId = (raw) => {
if (raw == null) return null;
const s0 = String(raw);
if (!s0) return null;
// 明文 id(如纯数字、Rand_...)直接返回,避免误解码
if (/^\d+$/.test(s0) || /^Rand_/i.test(s0)) {
return s0;
}
const tryParseJson = (str) => {
if (typeof str !== "string") return null;
const s = str.trim();
if (!s) return null;
try {
return JSON.parse(s);
} catch (_) {
return null;
}
};
const isProbablyBase64 = (s) => {
if (!s) return false;
// 支持短 base64(如 "Mg==")
if (s.includes("=")) return true;
if (s.length < 12) return false;
return /^[A-Za-z0-9+/_-]+={0,2}$/.test(s);
};
const tryAtob = (val) => {
if (val == null) return null;
const s = String(val).trim();
if (!s) return null;
if (!isProbablyBase64(s)) return null;
const normalized = s.replace(/-/g, "+").replace(/_/g, "/");
const padded = normalized + "===".slice((normalized.length + 3) % 4);
try {
return atob(padded);
} catch (_) {
return null;
}
};
const atobStr = tryAtob(s0);
if (atobStr != null) {
try {
const decoded = decodeURIComponent(atobStr);
return tryParseJson(decoded) ?? decoded;
} catch (_) {
return tryParseJson(atobStr) ?? atobStr;
}
}
// 路由参数可能是 base64 解码后的二进制串(会被浏览器编码成 %E...),这里做 latin1→utf8 尝试还原
try {
const utf8 = decodeURIComponent(escape(s0));
if (utf8 && utf8 !== s0) {
if (/^\d+$/.test(utf8) || /^Rand_/i.test(utf8)) return utf8;
return tryParseJson(utf8) ?? utf8;
}
} catch (_) { }
return s0;
};
const reportId = computed(() => decodeRouteId(route.params?.id));
const reportUrl = ref('')
const reportUrlEn = ref('')
const thinkInfo = ref({})
......@@ -268,7 +333,9 @@ const applyReportOriginalDocumentTitle = (title) => {
// 获取报告全局信息
const handleGetThinkTankReportSummary = async () => {
try {
const res = await getThinkTankReportSummary(router.currentRoute._value.params.id);
const id = reportId.value;
if (!id) return;
const res = await getThinkTankReportSummary(id);
console.log("报告全局信息", res);
if (res.code === 200 && res.data) {
const raw = res.data;
......@@ -284,7 +351,9 @@ const handleGetThinkTankReportSummary = async () => {
//获取原文
const handleGetThinkTankReportcontentUrl = async () => {
try {
const res = await getThinkTankReportcontentUrl(router.currentRoute._value.params.id);
const id = reportId.value;
if (!id) return;
const res = await getThinkTankReportcontentUrl(id);
console.log("获取原文", res);
if (res.code === 200 && res.data) {
reportUrl.value = res.data.content
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论