Skip to content

Conversation

@aice030
Copy link
Collaborator

@aice030 aice030 commented Oct 10, 2025

变更背景和解决方案

关联issue: #

文档更新(架构文档、API文档、升级文档)

Checklist

  • 确认是否有文档更新
  • 确认是否自测
  • 确认是否考虑兼容升级,不兼容升级需要有对应的解决方案
  • 确认是否考虑添加监控指标
  • API 设计是否符合 API 设计规范, 如果没有 API 变更,请忽略
  • 我已经添加了相关人员到 Reviewers 列表中
  • 我已经设置了 Development 关联的 Issue

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @aice030, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

此拉取请求旨在优化前端数据管理策略,通过完全移除对 localStorage 的依赖,确保所有关键数据都直接从后端 API 获取。这一改变提升了数据的新鲜度和一致性,避免了因客户端缓存导致的数据滞后问题。告警状态的同步逻辑也因此进行了调整,以适应新的数据流,确保服务状态能够实时反映最新的告警信息。

Highlights

  • 移除LocalStorage缓存: 前端代码不再使用 localStorage 来持久化存储模拟服务数据、活跃版本、可用版本、服务告警状态和服务发布状态。所有相关 localStorage 的读写操作函数已被禁用或移除。
  • 数据获取方式变更: 所有数据(包括服务数据和告警状态)现在都通过 API 实时获取,确保前端展示的数据始终是最新的,移除了对旧缓存数据的依赖。
  • 告警状态处理逻辑调整: 告警状态的同步逻辑已从 AlertsView.vue 迁移并重构到 HomeView.vue。现在,HomeView 会并行加载服务数据和告警数据,并引入了一个新的 parseAlertsToServiceStatus 函数来解析告警列表,提取并更新服务告警状态到内存中。
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions
Copy link

🚀 Frontend deployed successfully!

📱 Preview URL: https://zeroops-9d8a9i065-liuscrafts-projects.vercel.app

✅ Build completed successfully

@Erickw87 Erickw87 merged commit 7e89d23 into qiniu:develop Oct 10, 2025
1 check passed
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

本次PR的目标是移除前端的localStorage缓存,改为每次都通过API获取最新数据。整体代码变更符合这个目标。

我的审查意见主要集中在以下两点:

  1. 代码清理:在client/src/mock/services.ts中,与localStorage相关的函数被置空但未被移除,建议进行彻底清理以提高代码可维护性。
  2. 潜在的逻辑回归:在client/src/views/HomeView.vue中,新实现的parseAlertsToServiceStatus函数相比它所替代的旧函数,缺少了对服务版本告警状态的更新逻辑,这可能导致UI显示不正确。同时,该函数也存在类型定义不明确的问题。

具体的修改建议请见文件中的评论。

Comment on lines +647 to +683
const parseAlertsToServiceStatus = (alertsData: any) => {
// 优先级:Pending > InProcessing > Restored > AutoRestored
const priority: Record<string, number> = {
Pending: 4,
InProcessing: 3,
Restored: 2,
AutoRestored: 1
}
// 服务名映射
const prophetToServiceMap: Record<string, string> = {
s3apiv2: 's3'
}
const latestStateByService = new Map<string, { state: string; ts: number; prio: number }>()
for (const issue of alertsData) {
// 解析服务名:优先 labels.service,其次 prophet_service 的映射
const serviceLabel = issue.labels.find((l: any) => l.key === 'service')?.value
const prophetService = issue.labels.find((l: any) => l.key === 'prophet_service')?.value
const mapped = prophetService ? prophetToServiceMap[prophetService] : undefined
const serviceName = serviceLabel || mapped
if (!serviceName) continue
const ts = new Date(issue.alertSince).getTime()
const prio = priority[issue.alertState] || 0
const existing = latestStateByService.get(serviceName)
if (!existing || prio > existing.prio || (prio === existing.prio && ts > existing.ts)) {
latestStateByService.set(serviceName, { state: issue.alertState, ts, prio })
}
}
// 更新到全局状态映射
latestStateByService.forEach((val, service) => {
updateServiceAlertStatus(service, val.state)
})
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

新添加的 parseAlertsToServiceStatus 函数存在两个问题:

  1. 类型不明确: 参数 alertsData 和循环变量 l 使用了 any 类型,这降低了代码的类型安全性和可读性。
  2. 缺少关键逻辑: 该函数遗漏了同步服务版本告警状态的逻辑。这部分逻辑在被替换的 syncServiceAlertStatuses 函数中是存在的,对于在UI上正确显示各版本的状态颜色至关重要,遗漏它可能导致显示错误。

建议进行如下修改,同时解决这两个问题。请注意,你需要在文件顶部导入 AlertIssue, AlertLabelupdateServiceVersionAlertStatus 类型和函数。

const parseAlertsToServiceStatus = (alertsData: AlertIssue[]) => {
  // 优先级:Pending > InProcessing > Restored > AutoRestored
  const priority: Record<string, number> = {
    Pending: 4,
    InProcessing: 3,
    Restored: 2,
    AutoRestored: 1
  }

  // 服务名映射
  const prophetToServiceMap: Record<string, string> = {
    s3apiv2: 's3'
  }

  const latestStateByService = new Map<string, { state: string; ts: number; prio: number }>()

  for (const issue of alertsData) {
    // 解析服务名:优先 labels.service,其次 prophet_service 的映射
    const serviceLabel = issue.labels.find((l: AlertLabel) => l.key === 'service')?.value
    const prophetService = issue.labels.find((l: AlertLabel) => l.key === 'prophet_service')?.value
    const mapped = prophetService ? prophetToServiceMap[prophetService] : undefined
    const serviceName = serviceLabel || mapped
    if (!serviceName) continue

    const ts = new Date(issue.alertSince).getTime()
    const prio = priority[issue.alertState] || 0
    const existing = latestStateByService.get(serviceName)
    if (!existing || prio > existing.prio || (prio === existing.prio && ts > existing.ts)) {
      latestStateByService.set(serviceName, { state: issue.alertState, ts, prio })
    }

    // 同步版本状态(如果存在 service_version 标签)
    // 版本标签检测:兼容多种后端命名
    const versionLabel =
      issue.labels.find((l: AlertLabel) => l.key === 'service_version')?.value ||
      issue.labels.find((l: AlertLabel) => l.key === 'version')?.value ||
      issue.labels.find((l: AlertLabel) => l.key === 'serviceVersion')?.value ||
      issue.labels.find((l: AlertLabel) => l.key === 'svc_version')?.value ||
      issue.labels.find((l: AlertLabel) => l.key === 'deploy_version')?.value ||
      issue.labels.find((l: AlertLabel) => l.key === 'deployVersion')?.value ||
      issue.labels.find((l: AlertLabel) => l.key.toLowerCase().includes('version'))?.value
    if (versionLabel) {
      updateServiceVersionAlertStatus(serviceName, versionLabel, issue.alertState)
    }
  }

  // 更新到全局状态映射
  latestStateByService.forEach((val, service) => {
    updateServiceAlertStatus(service, val.state)
  })
}

Comment on lines 1712 to 1721
const saveDataToStorage = () => {
try {
localStorage.setItem('mockServiceActiveVersions', JSON.stringify(mockServiceActiveVersions))
localStorage.setItem('mockAvailableVersions', JSON.stringify(mockAvailableVersions))
console.log('数据已保存到 localStorage')
} catch (error) {
console.error('保存数据到 localStorage 失败:', error)
}
// 不再保存到 localStorage,所有数据从API获取
}

/**
* 从 localStorage 加载数据
* 从 localStorage 加载数据(已禁用)
*/
const loadDataFromStorage = () => {
try {
const activeVersionsData = localStorage.getItem('mockServiceActiveVersions')
const availableVersionsData = localStorage.getItem('mockAvailableVersions')

if (activeVersionsData) {
const parsedData = JSON.parse(activeVersionsData)
Object.assign(mockServiceActiveVersions, parsedData)
console.log('已从 localStorage 加载活跃版本数据')
}

if (availableVersionsData) {
const parsedData = JSON.parse(availableVersionsData)
Object.assign(mockAvailableVersions, parsedData)
console.log('已从 localStorage 加载可发布版本数据')
}
} catch (error) {
console.error('从 localStorage 加载数据失败:', error)
}
// 不再从 localStorage 加载,所有数据从API获取
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

这个PR移除了 localStorage 的使用,非常好。但目前只是将相关函数 (saveDataToStorage, loadDataFromStorage, saveServiceAlertStatus, loadServiceAlertStatus 等) 的函数体清空,而函数本身和对它们的调用仍然保留在代码中。

为了使代码更整洁、更易于维护,建议将这些已无实际作用的函数以及所有对它们的调用完全移除。例如,saveDataToStorage 函数的调用在 removeVersionFromAvailableaddVersionToAvailable 等函数中仍然存在。

如果未来可能需要恢复这些功能,通过 Git 历史记录来找回会是更好的选择。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants