提交 f78815c8 authored 作者: yanpeng's avatar yanpeng

bugfix-3

上级 02ee47e1
...@@ -8,6 +8,28 @@ import { ...@@ -8,6 +8,28 @@ import {
// Token管理 // Token管理
const TOKEN_KEY = 'auth_token' const TOKEN_KEY = 'auth_token'
// 定义全局控制器,以便在取消后重新赋值
let currentMainAbortController = new AbortController()
/**
* 获取当前有效的 AbortSignal
* 供 axios 拦截器和 fetch 请求共同使用
*/
export const getMainAbortSignal = () => {
return currentMainAbortController.signal
}
/**
* 取消所有正在进行的请求
* 路由守卫中调用此方法
*/
export const cancelAllMainRequests = () => {
// 1. 终止当前控制器的所有请求
currentMainAbortController.abort()
// 2. 创建一个新的控制器,供后续新请求使用
currentMainAbortController = new AbortController()
}
// ===== 兼容导出(勿删):历史代码仍会 import formatBearerAuthorization ===== // ===== 兼容导出(勿删):历史代码仍会 import formatBearerAuthorization =====
// 说明:当前线上版本后端用 `token` 头,不用 Authorization;但为了不影响其它模块编译/运行,这里保留该方法导出。 // 说明:当前线上版本后端用 `token` 头,不用 Authorization;但为了不影响其它模块编译/运行,这里保留该方法导出。
const formatBearerAuthorization = (raw) => { const formatBearerAuthorization = (raw) => {
...@@ -70,6 +92,10 @@ service.interceptors.request.use(config => { ...@@ -70,6 +92,10 @@ service.interceptors.request.use(config => {
config.headers['X-API-Key'] = aiApiKey config.headers['X-API-Key'] = aiApiKey
} }
} }
if (!config.signal) {
config.signal = getMainAbortSignal()
}
return config return config
}, error => { }, error => {
console.log(error) console.log(error)
......
...@@ -3,6 +3,7 @@ import { setToken, removeToken, getToken } from "@/api/request.js"; ...@@ -3,6 +3,7 @@ import { setToken, removeToken, getToken } from "@/api/request.js";
import { AUTH_LOGOUT_CHANNEL } from "@/utils/authCrossTabLogout.js"; import { AUTH_LOGOUT_CHANNEL } from "@/utils/authCrossTabLogout.js";
import { cancelAllRequests } from "@/api/finance/service.js" import { cancelAllRequests } from "@/api/finance/service.js"
import { cancelAllMainRequests } from "@/api/request.js"
/** localStorage:跨标签页记录当前前端的 bootId(与 vite define 的 __APP_BOOT_ID__ 对齐) */ /** localStorage:跨标签页记录当前前端的 bootId(与 vite define 的 __APP_BOOT_ID__ 对齐) */
const VITE_BOOT_STORAGE_KEY = "app_vite_boot_id"; const VITE_BOOT_STORAGE_KEY = "app_vite_boot_id";
...@@ -149,6 +150,7 @@ const router = createRouter({ ...@@ -149,6 +150,7 @@ const router = createRouter({
router.beforeEach((to, from, next) => { router.beforeEach((to, from, next) => {
// 在每次路由跳转开始前,取消上一个页面所有未完成的请求 // 在每次路由跳转开始前,取消上一个页面所有未完成的请求
// 这能防止旧页面的数据回来覆盖新页面,也能减少服务器压力 // 这能防止旧页面的数据回来覆盖新页面,也能减少服务器压力
cancelAllMainRequests();
cancelAllRequests(); cancelAllRequests();
if (import.meta.env.DEV) { if (import.meta.env.DEV) {
clearTokenIfNewDevBoot(); clearTokenIfNewDevBoot();
......
差异被折叠。
...@@ -17,27 +17,47 @@ ...@@ -17,27 +17,47 @@
<div class="text">科技领域</div> <div class="text">科技领域</div>
</div> </div>
<div class="checkbox-group"> <div class="checkbox-group">
<el-checkbox v-for="(item, index) in techFields" :key="index" v-model="item.checked" :label="item.label" <el-checkbox
@change="handleFilterChange(item, techFields, 'tech')" /> v-for="(item, index) in techFields"
:key="index"
v-model="item.checked"
:label="item.label"
@change="handleFilterChange(item, techFields, 'tech')"
/>
</div> </div>
<div class="title"> <div class="title">
<div class="box"></div> <div class="box"></div>
<div class="text">实体类型</div> <div class="text">实体类型</div>
</div> </div>
<div class="checkbox-group"> <div class="checkbox-group">
<el-checkbox v-for="(item, index) in entityTypes" :key="index" v-model="item.checked" :label="item.label" <el-checkbox
@change="handleFilterChange(item, entityTypes, 'type')" /> v-for="(item, index) in entityTypes"
:key="index"
v-model="item.checked"
:label="item.label"
@change="handleFilterChange(item, entityTypes, 'type')"
/>
</div> </div>
<div class="title"> <div class="title">
<div class="box"></div> <div class="box"></div>
<div class="text">制裁时间</div> <div class="text">制裁时间</div>
</div> </div>
<div class="checkbox-group"> <div class="checkbox-group">
<el-checkbox v-for="(item, index) in sanctionTimes" :key="index" v-model="item.checked" :label="item.label" <el-checkbox
@change="handleFilterChange(item, sanctionTimes, 'time')" /> v-for="(item, index) in sanctionTimes"
:key="index"
v-model="item.checked"
:label="item.label"
@change="handleFilterChange(item, sanctionTimes, 'time')"
/>
<div v-if="sanctionTimes.find(i => i.value === 'custom' && i.checked)" class="custom-date-picker"> <div v-if="sanctionTimes.find(i => i.value === 'custom' && i.checked)" class="custom-date-picker">
<el-date-picker v-model="customDateRange" type="daterange" range-separator="-" start-placeholder="开始日期" <el-date-picker
end-placeholder="结束日期" /> v-model="customDateRange"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
/>
</div> </div>
</div> </div>
</div> </div>
...@@ -114,13 +134,20 @@ ...@@ -114,13 +134,20 @@
<span class="highlight" @click="handlToDataLibrary">{{ ruleCount.totalCount }}</span> <span class="highlight" @click="handlToDataLibrary">{{ ruleCount.totalCount }}</span>
</div> </div>
<div class="rule-text"> <div class="rule-text">
(50%规则涉及<span class="highlight" @click="handlToDataLibrary1">{{ ruleCount.ruleCount }}</span>家) (50%规则涉及<span class="highlight" @click="handlToDataLibrary1">{{
ruleCount.ruleCount
}}</span
>家)
</div> </div>
</div> </div>
</template> </template>
<div class="right-table"> <div class="right-table">
<el-table :data="entityRows" table-layout="fixed" :row-class-name="tableRowClassName" <el-table
:header-cell-style="{ background: '#fff' }"> :data="entityRows"
table-layout="fixed"
:row-class-name="tableRowClassName"
:header-cell-style="{ background: '#fff' }"
>
<el-table-column label="实体名称" min-width="200"> <el-table-column label="实体名称" min-width="200">
<template #default="{ row }"> <template #default="{ row }">
<div class="entity-name-cell" @click="handleCompClick(row)"> <div class="entity-name-cell" @click="handleCompClick(row)">
...@@ -128,30 +155,56 @@ ...@@ -128,30 +155,56 @@
<div v-else class="avatar-undefined"> <div v-else class="avatar-undefined">
{{ (row.entityNameZh || row.entityName)?.match(/[\u4e00-\u9fa5a-zA-Z0-9]/)?.[0] }} {{ (row.entityNameZh || row.entityName)?.match(/[\u4e00-\u9fa5a-zA-Z0-9]/)?.[0] }}
</div> </div>
<CommonPrompt :content="row.entityNameZh || row.entityName" style="flex: 1; overflow: hidden" /> <CommonPrompt
:content="row.entityNameZh || row.entityName"
style="flex: 1; overflow: hidden"
/>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="涉及领域" min-width="150"> <el-table-column label="涉及领域" min-width="150">
<template #default="{ row }"> <template #default="{ row }">
<div class="domain-cell"> <div class="domain-cell">
<el-tag v-for="tag in row.techDomains" :key="tag" class="domain-tag" effect="plain" <el-tag
:disable-transitions="true" :style="getTagStyle(tag)"> v-for="tag in row.techDomains"
:key="tag"
class="domain-tag"
effect="plain"
:disable-transitions="true"
:style="getTagStyle(tag)"
>
{{ tag }} {{ tag }}
</el-tag> </el-tag>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column prop="listingLocation" label="上市地点" width="140" show-overflow-tooltip align="center" /> <el-table-column
<el-table-column prop="startTime" label="制裁时间" width="140" show-overflow-tooltip align="center" /> prop="listingLocation"
label="上市地点"
width="140"
show-overflow-tooltip
align="center"
/>
<el-table-column
prop="startTime"
label="制裁时间"
width="140"
show-overflow-tooltip
align="center"
/>
<el-table-column label="50%规则子企业" min-width="280" show-overflow-tooltip align="right"> <el-table-column label="50%规则子企业" min-width="280" show-overflow-tooltip align="right">
<template #default="{ row }"> <template #default="{ row }">
<div class="rule-cell" v-if="row.ruleOrgCount > 0"> <div class="rule-cell" v-if="row.ruleOrgCount > 0">
<div class="rule-text" :title="row.ruleOrgList?.[0]?.orgName || ''"> <div class="rule-text" :title="row.ruleOrgList?.[0]?.orgName || ''">
{{ row.ruleOrgList?.[0]?.orgName || "" }}...等 {{ row.ruleOrgList?.[0]?.orgName || "" }}...等
</div> </div>
<el-link class="rule-link" type="primary" :underline="false" @click="handleRuleClick(row)">{{ <el-link
row.ruleOrgCount }}家 ></el-link> class="rule-link"
type="primary"
:underline="false"
@click="handleRuleClick(row)"
>{{ row.ruleOrgCount }}家 ></el-link
>
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
...@@ -159,15 +212,26 @@ ...@@ -159,15 +212,26 @@
</div> </div>
<div class="tight-footer"> <div class="tight-footer">
<div class="total-text">共 {{ total }} 项</div> <div class="total-text">共 {{ total }} 项</div>
<el-pagination :current-page="currentPage" v-model:page-size="pageSize" :total="total" <el-pagination
layout="prev, pager, next" prev-text="<" next-text=">" @current-change="handleCurrentChange" /> :current-page="currentPage"
v-model:page-size="pageSize"
:total="total"
layout="prev, pager, next"
prev-text="<"
next-text=">"
@current-change="handleCurrentChange"
/>
</div> </div>
</AnalysisBox> </AnalysisBox>
</div> </div>
</div> </div>
</div> </div>
<RuleSubsidiaryDialog v-model="ruleDialogVisible" :company-name="currentRuleCompany" :total-count="currentRuleCount" <RuleSubsidiaryDialog
:data-list="currentRuleList" /> v-model="ruleDialogVisible"
:company-name="currentRuleCompany"
:total-count="currentRuleCount"
:data-list="currentRuleList"
/>
</div> </div>
</template> </template>
...@@ -273,6 +337,7 @@ const entityTypes = ref([ ...@@ -273,6 +337,7 @@ const entityTypes = ref([
const sanctionTimes = ref([ const sanctionTimes = ref([
{ label: "全部时间", value: "all", checked: true }, { label: "全部时间", value: "all", checked: true },
{ label: "2026年", value: "2026", checked: false },
{ label: "2025年", value: "2025", checked: false }, { label: "2025年", value: "2025", checked: false },
{ label: "2024年", value: "2024", checked: false }, { label: "2024年", value: "2024", checked: false },
{ label: "2023年", value: "2023", checked: false }, { label: "2023年", value: "2023", checked: false },
...@@ -352,7 +417,7 @@ const getExportControlListApi = async () => { ...@@ -352,7 +417,7 @@ const getExportControlListApi = async () => {
if (abortController) { if (abortController) {
try { try {
abortController.abort(); abortController.abort();
} catch { } } catch {}
} }
abortController = new AbortController(); abortController = new AbortController();
isFetching.value = true; isFetching.value = true;
...@@ -468,26 +533,25 @@ watch(customDateRange, () => { ...@@ -468,26 +533,25 @@ watch(customDateRange, () => {
// 跳转到数据资源库 // 跳转到数据资源库
const handlToDataLibrary = () => { const handlToDataLibrary = () => {
const params = { const params = {
isCnEntityOnly: true, isCnEntityOnly: true
}; };
const route = router.resolve({ const route = router.resolve({
path: "/dataLibrary/dataEntityList", path: "/dataLibrary/dataEntityList",
query: params query: params
}); });
window.open(route.href, "_blank"); window.open(route.href, "_blank");
} };
const handlToDataLibrary1 = () => { const handlToDataLibrary1 = () => {
const params = { const params = {
isCnEntityOnly: true, isCnEntityOnly: true,
isHalfRule: true, isHalfRule: true
}; };
const route = router.resolve({ const route = router.resolve({
path: "/dataLibrary/dataEntityList", path: "/dataLibrary/dataEntityList",
query: params query: params
}); });
window.open(route.href, "_blank"); window.open(route.href, "_blank");
} };
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
...@@ -692,7 +756,6 @@ const handlToDataLibrary1 = () => { ...@@ -692,7 +756,6 @@ const handlToDataLibrary1 = () => {
.highlight { .highlight {
color: #cd4246; color: #cd4246;
margin: 0 4px; margin: 0 4px;
} }
} }
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论