生成时间: 2026-08-03 · 数据来源: xnybw平台需求及工作计划.xlsx(南网在线绿能云缺陷跟踪表)· 仅针对 backup730/730backup 分支代码

Row 14:项目信息查询列表点击"查阅"后进入页面一直显示空白

严重 已关闭 · 复测通过 全部类型 模块:项目信息查询 处理人:陈键泽

1基本信息

问题描述项目信息查询列表点击"查阅"之后进去一直显示空白。
所属模块项目信息查询 / -
严重程度严重(阻断流程:是)
涉及类型全部类型
提出人罗晶
处理人 / 状态陈键泽 / 5.1.已关闭(复测通过)

2问题截图

项目信息查询列表-查阅按钮
图1:项目信息查询列表,"查阅"操作按钮
点击查阅后空白页面
图2:点击查阅后跳转到 project-form 页面,URL 携带 planId/implId 参数,但页面完全空白

3旧代码定位(backup730 分支)

入口:src/views/projectNew/projectInfoSearchList.vue 第 371-396 行,"查阅"按钮通过 handleJump()query 查询字符串方式打开新窗口:

handleJump(row, activeName, status) {
  const query = {
    planId: row.planId,
    implId: row.id,
    status: status,
    mode: status,
    ...
  }
  window.open('/project-form?' + new URLSearchParams(query))   // 第395行:只传 query,没有 /:id 路径参数
}

路由定义:src/router/modules/base.js 第 28-33 行:

{
  path: '/project-form',        // 注意:没有 :id 段
  name: 'ProjectTabs',
  component: () => import('@/views/projectNew/ProjectTabs.vue'),
}

实际渲染组件:src/views/projectNew/ProjectTabs.vue 第 131-150 行(created() 钩子):

created() {
  this.status  = this.$route.query.status  || ''
  this.implId  = this.$route.query.implId  || ''     // 136行:implId 正常读到
  this.type    = this.$route.query.type    || ''
  ...
  try {
    this.getPlanIdByImplId(this.implId);              // 143行:异步方法,未 await
  } catch (error) {
    // 144-146行:只有"同步抛错"才会走到这里
    this.planId = this.$route.query.planId || '';     // query 里明明带了 planId,却被搁置为兜底分支
  }
  this.loadOptionsData()
  if (this.projectId) {          // 149行:projectId = this.$route.params.id,此路由没有 :id 段,恒为 undefined
    this.loadProjectData()
  }
},
...
async getPlanIdByImplId(implId){                       // 第239行
  const response = await newEnergyApi.getPlanIdByImplId(implId);
  this.planId = response.data;
}
根因说明:
① 异步异常未被捕获:getPlanIdByImplId()async 方法,其内部 await 失败时抛出的是"异步"异常,不会被外层同步 try/catch 捕获(这是 JS 中"调用 async 函数但不 await"的经典反模式)。一旦后端 getPlanIdByImplId 接口失败/超时/无权限,catch 分支永远不会执行,this.planId 就会一直停留在初始值 '',而本该兜底使用的 query.planId(其实前端已经正确带上了)被彻底忽略。
② 子 Tab 组件被 v-if 挡住:ProjectTabs.vue 模板第 26/35/43 行,jhbwDetail/gridInfoDetail/actualDetail 均用 v-if="planId" 守卫,planId 为空字符串时这些 Tab 内容根本不会挂载;第 21 行的 projectDetail(基本信息 Tab)虽未加 v-if,但接收到的 :planId="planId" 也是空字符串,内部按 planId 查详情自然拿不到数据。
点击"查阅"
URL 带上 planId + implId(query)
ProjectTabs.created() 用 implId 异步重新查 planId
接口失败/迟迟未返回 → planId 一直为空
v-if="planId" 各 Tab 不渲染 → 页面空白

4修复方案

修复代码文件:src/views/projectNew/ProjectTabs.vue(原第 131-150 行 created()

async created() {          // ① created 改为 async,能够真正 await 异步调用
  this.status  = this.$route.query.status  || ''
  this.implId  = this.$route.query.implId  || ''
  this.type    = this.$route.query.type    || ''
  this.activeTab = this.$route.query.activeName
  document.title = this.$route.query.title || '电网运行管理系统'

  // ② 优先信任 URL 已经带上的 planId,implId 仅作为兜底反查手段
  this.planId = this.$route.query.planId || ''
  if (!this.planId && this.implId) {
    try {
      await this.getPlanIdByImplId(this.implId)   // ③ 用 await,真正让 catch 生效
    } catch (error) {
      console.error('[根据 implId 查询 planId 失败]', error)
      this.$message.error('项目数据加载失败,请返回列表重试')
    }
  }

  this.loadOptionsData()
  if (this.projectId) {
    this.loadProjectData()
  }
},

同时建议加固 getPlanIdByImplId()(原第 239-242 行),避免异常继续往外抛导致页面卡死:

async getPlanIdByImplId(implId) {
  try {
    const response = await newEnergyApi.getPlanIdByImplId(implId)
    this.planId = response && response.data ? response.data : ''
  } catch (error) {
    this.planId = ''
    throw error   // 继续抛出,交给上层 created() 的 try/catch 统一提示用户
  }
}
效果:无论后端 getPlanIdByImplId 接口是否可用,只要前端 URL 中已经携带了 planId(当前"查阅"按钮实际上一直是带的),页面都能正常拿到 planId 渲染各 Tab;接口异常时也会给出明确的错误提示,而不是静默空白。