-
Notifications
You must be signed in to change notification settings - Fork 8
Feat: 将前端接口改回从后端获取真实数据的api #95
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
# Conflicts: # client/README.md # client/package.json # client/src/api/index.ts # client/src/mock/api.ts # client/src/mock/services.ts # client/src/router/index.ts # client/src/stores/app.ts # client/src/views/ChangeLogView.vue # client/src/views/HomeView.vue
Summary of ChangesHello @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! 此拉取请求旨在将前端应用程序从使用模拟数据接口全面迁移到使用后端提供的真实API接口。这一变更确保了应用程序能够获取和展示实时、准确的数据,并支持实际的部署操作,从而使前端功能与后端服务完全集成,提升了系统的整体功能性和可靠性。 Highlights
Using Gemini Code AssistThe 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
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 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
|
|
🚀 Frontend deployed successfully! 📱 Preview URL: https://zeroops-6t0e4gvvx-liuscrafts-projects.vercel.app ✅ Build completed successfully |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
本次 PR 主要将前端的 mock API 调用切换为真实的后端 API 调用,整体实现正确。这是一个很好的进步!为了进一步提升代码质量和性能,我提出了一些建议。主要集中在 HomeView.vue 文件中,我发现多处在执行操作后重新加载数据的逻辑,这些网络请求是串行执行的,可以通过 Promise.all 并行化来提升性能。此外,部分函数参数使用了 any 类型,建议定义明确的接口以增强类型安全。代码中还存在一些用于调试的 console.log 语句,建议在最终合并前移除。具体的修改建议请见评论。
| // 重新加载服务详情数据(饼状图会自动更新) | ||
| const serviceDetailResult = await loadServiceDetail(selectedNode.value.name) | ||
| console.log('重新加载的服务详情数据:', serviceDetailResult) | ||
| if (serviceDetailResult) { | ||
| selectedNode.value = { ...serviceDetailResult, status: getNodeStatus(serviceDetailResult) } | ||
| console.log('更新后的selectedNode.value:', selectedNode.value) | ||
| } | ||
| // 3. 重新加载可发布版本数据(这样下拉框会自动更新) | ||
| // 重新加载可发布版本数据(下拉框会自动更新) | ||
| const availableVersionsResult = await loadServiceAvailableVersions(selectedNode.value.name) | ||
| if (availableVersionsResult) { | ||
| currentServiceAvailableVersions.value = availableVersionsResult | ||
| } | ||
| // 4. 生成合理的黄金指标数值并更新表格 | ||
| const generateMetrics = () => { | ||
| return { | ||
| latency: (Math.random() * 50 + 10).toFixed(1), // 10-60ms | ||
| traffic: (Math.random() * 1000 + 100).toFixed(0), // 100-1100 req/s | ||
| errorRatio: (Math.random() * 2).toFixed(1), // 0-2% | ||
| saturation: (Math.random() * 20 + 60).toFixed(0) // 60-80% | ||
| } | ||
| // 重新加载服务指标数据 | ||
| const metricsDataResult = await loadServiceMetrics(selectedNode.value.name) | ||
| if (metricsDataResult) { | ||
| currentServiceMetrics.value = metricsDataResult | ||
| } | ||
| const newMetrics = generateMetrics() | ||
| // 直接更新当前服务的指标数据 | ||
| if (currentServiceMetrics.value) { | ||
| // 添加新版本的指标数据 | ||
| const newVersionMetrics = { | ||
| version: selectedVersion.value, | ||
| metrics: [ | ||
| { name: 'latency', value: parseFloat(newMetrics.latency) }, | ||
| { name: 'traffic', value: parseFloat(newMetrics.traffic) }, | ||
| { name: 'errorRatio', value: parseFloat(newMetrics.errorRatio) }, | ||
| { name: 'saturation', value: parseFloat(newMetrics.saturation) } | ||
| ] | ||
| } | ||
| // 检查是否已存在该版本,如果存在则更新,否则添加 | ||
| const existingIndex = currentServiceMetrics.value.items.findIndex(item => item.version === selectedVersion.value) | ||
| if (existingIndex >= 0) { | ||
| currentServiceMetrics.value.items[existingIndex] = newVersionMetrics | ||
| } else { | ||
| currentServiceMetrics.value.items.push(newVersionMetrics) | ||
| } | ||
| // 更新summary数据(使用所有版本的平均值) | ||
| const allVersions = currentServiceMetrics.value.items | ||
| const avgLatency = allVersions.reduce((sum, v) => sum + (v.metrics.find(m => m.name === 'latency')?.value || 0), 0) / allVersions.length | ||
| const avgTraffic = allVersions.reduce((sum, v) => sum + (v.metrics.find(m => m.name === 'traffic')?.value || 0), 0) / allVersions.length | ||
| const avgErrorRatio = allVersions.reduce((sum, v) => sum + (v.metrics.find(m => m.name === 'errorRatio')?.value || 0), 0) / allVersions.length | ||
| const avgSaturation = allVersions.reduce((sum, v) => sum + (v.metrics.find(m => m.name === 'saturation')?.value || 0), 0) / allVersions.length | ||
| currentServiceMetrics.value.summary.metrics = [ | ||
| { name: 'latency', value: avgLatency }, | ||
| { name: 'traffic', value: avgTraffic }, | ||
| { name: 'errorRatio', value: avgErrorRatio }, | ||
| { name: 'saturation', value: avgSaturation } | ||
| ] | ||
| // 重新加载发布计划列表 | ||
| const deploymentPlansDataResult = await loadServiceDeploymentPlans(selectedNode.value.name) | ||
| if (deploymentPlansDataResult) { | ||
| currentServiceDeploymentPlans.value = deploymentPlansDataResult | ||
| } | ||
| // 5. 重新加载服务数据以更新拓扑图 | ||
| // 重新加载服务数据以更新拓扑图 | ||
| await loadServicesData() | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里的多个 await 会导致数据串行加载,影响性能。建议使用 Promise.all 来并行加载这些数据,可以有效减少等待时间。
// 并行重新加载数据以提升性能
const serviceName = selectedNode.value.name;
const [
serviceDetailResult,
availableVersionsResult,
metricsDataResult,
deploymentPlansDataResult
] = await Promise.all([
loadServiceDetail(serviceName),
loadServiceAvailableVersions(serviceName),
loadServiceMetrics(serviceName),
loadServiceDeploymentPlans(serviceName)
]);
if (serviceDetailResult) {
selectedNode.value = { ...serviceDetailResult, status: getNodeStatus(serviceDetailResult) }
}
if (availableVersionsResult) {
currentServiceAvailableVersions.value = availableVersionsResult
}
if (metricsDataResult) {
currentServiceMetrics.value = metricsDataResult
}
if (deploymentPlansDataResult) {
currentServiceDeploymentPlans.value = deploymentPlansDataResult
}
// 重新加载服务数据以更新拓扑图
await loadServicesData()
| editForm.value.scheduleTime = '' | ||
| } | ||
| const confirmCancel = async (plan: any) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
参数 plan 的类型被定义为 any,这会降低代码的可读性和类型安全性。建议为 deploymentPlansForDisplay 计算属性返回的计划对象定义一个明确的 interface,并在使用它的函数(如 confirmCancel, togglePauseResume, rollbackRelease)中应用该类型。
例如:
interface DisplayDeploymentPlan {
id: string;
service: string;
version: string;
status: string;
time: string;
originalStatus: 'Schedule' | 'InDeployment' | 'Finished';
isPaused: boolean;
scheduleTime?: string;
}
const confirmCancel = async (plan: DisplayDeploymentPlan) => {
// ...
}| // 刷新发布计划列表和服务详情 | ||
| if (selectedNode.value) { | ||
| const deploymentPlansDataResult = await loadServiceDeploymentPlans(selectedNode.value.name) | ||
| if (deploymentPlansDataResult) { | ||
| currentServiceDeploymentPlans.value = deploymentPlansDataResult | ||
| } | ||
| // 刷新服务详情数据(饼图会自动更新) | ||
| const serviceDetailResult = await loadServiceDetail(selectedNode.value.name) | ||
| if (serviceDetailResult) { | ||
| selectedNode.value = { ...serviceDetailResult, status: getNodeStatus(serviceDetailResult) } | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里的两个 await 会导致数据串行加载。建议使用 Promise.all 来并行加载,以提升性能。
// 并行刷新发布计划列表和服务详情以提升性能
if (selectedNode.value) {
const [deploymentPlansDataResult, serviceDetailResult] = await Promise.all([
loadServiceDeploymentPlans(selectedNode.value.name),
loadServiceDetail(selectedNode.value.name)
])
if (deploymentPlansDataResult) {
currentServiceDeploymentPlans.value = deploymentPlansDataResult
}
if (serviceDetailResult) {
selectedNode.value = { ...serviceDetailResult, status: getNodeStatus(serviceDetailResult) }
}
}
| } | ||
| // 版本表格中的操作 | ||
| const togglePauseResumeForVersion = async (version: any) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
参数 version 的类型被定义为 any。为了提高代码质量,建议为 getVersionTableData 返回的版本对象定义一个明确的 interface,并在 togglePauseResumeForVersion 和 rollbackVersion 函数中使用它。
例如:
interface VersionTableItem {
version: string;
latency: number;
traffic: number;
errors: string;
saturation: number;
status: string;
isPaused: boolean;
deployId: string;
}
const togglePauseResumeForVersion = async (version: VersionTableItem) => {
// ...
}| // 重新加载服务详情数据以更新UI | ||
| if (selectedNode.value) { | ||
| await loadServiceDetail(selectedNode.value.name) | ||
| const serviceDetailResult = await loadServiceDetail(selectedNode.value.name) | ||
| if (serviceDetailResult) { | ||
| selectedNode.value = { ...serviceDetailResult, status: getNodeStatus(serviceDetailResult) } | ||
| } | ||
| // 重新加载发布计划列表 | ||
| const deploymentPlansDataResult = await loadServiceDeploymentPlans(selectedNode.value.name) | ||
| if (deploymentPlansDataResult) { | ||
| currentServiceDeploymentPlans.value = deploymentPlansDataResult | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
与其它地方类似,这里的数据加载也是串行的。建议使用 Promise.all 并行加载以优化性能。
// 并行重新加载服务详情和发布计划以更新UI和提升性能
if (selectedNode.value) {
const [serviceDetailResult, deploymentPlansDataResult] = await Promise.all([
loadServiceDetail(selectedNode.value.name),
loadServiceDeploymentPlans(selectedNode.value.name)
])
if (serviceDetailResult) {
selectedNode.value = { ...serviceDetailResult, status: getNodeStatus(serviceDetailResult) }
}
if (deploymentPlansDataResult) {
currentServiceDeploymentPlans.value = deploymentPlansDataResult
}
}
| // 重新加载服务详情数据(饼状图会自动更新) | ||
| if (selectedNode.value) { | ||
| const serviceDetailResult = await loadServiceDetail(selectedNode.value.name) | ||
| if (serviceDetailResult) { | ||
| selectedNode.value = { ...serviceDetailResult, status: getNodeStatus(serviceDetailResult) } | ||
| } | ||
| } | ||
| // 3. 重新加载可发布版本数据(这样下拉框会自动更新) | ||
| // 重新加载可发布版本数据(下拉框会自动更新) | ||
| if (selectedNode.value) { | ||
| const availableVersionsResult = await loadServiceAvailableVersions(selectedNode.value.name) | ||
| if (availableVersionsResult) { | ||
| currentServiceAvailableVersions.value = availableVersionsResult | ||
| } | ||
| } | ||
| // 4. 从指标数据中移除该版本 | ||
| if (currentServiceMetrics.value) { | ||
| const versionIndex = currentServiceMetrics.value.items.findIndex(item => item.version === version.version) | ||
| if (versionIndex >= 0) { | ||
| currentServiceMetrics.value.items.splice(versionIndex, 1) | ||
| // 更新summary数据(使用剩余版本的平均值) | ||
| const remainingVersions = currentServiceMetrics.value.items | ||
| if (remainingVersions.length > 0) { | ||
| const avgLatency = remainingVersions.reduce((sum, v) => sum + (v.metrics.find(m => m.name === 'latency')?.value || 0), 0) / remainingVersions.length | ||
| const avgTraffic = remainingVersions.reduce((sum, v) => sum + (v.metrics.find(m => m.name === 'traffic')?.value || 0), 0) / remainingVersions.length | ||
| const avgErrorRatio = remainingVersions.reduce((sum, v) => sum + (v.metrics.find(m => m.name === 'errorRatio')?.value || 0), 0) / remainingVersions.length | ||
| const avgSaturation = remainingVersions.reduce((sum, v) => sum + (v.metrics.find(m => m.name === 'saturation')?.value || 0), 0) / remainingVersions.length | ||
| currentServiceMetrics.value.summary.metrics = [ | ||
| { name: 'latency', value: avgLatency }, | ||
| { name: 'traffic', value: avgTraffic }, | ||
| { name: 'errorRatio', value: avgErrorRatio }, | ||
| { name: 'saturation', value: avgSaturation } | ||
| ] | ||
| } else { | ||
| // 如果没有剩余版本,清空summary数据 | ||
| currentServiceMetrics.value.summary.metrics = [ | ||
| { name: 'latency', value: 0 }, | ||
| { name: 'traffic', value: 0 }, | ||
| { name: 'errorRatio', value: 0 }, | ||
| { name: 'saturation', value: 0 } | ||
| ] | ||
| } | ||
| // 重新加载服务指标数据 | ||
| if (selectedNode.value) { | ||
| const metricsDataResult = await loadServiceMetrics(selectedNode.value.name) | ||
| if (metricsDataResult) { | ||
| currentServiceMetrics.value = metricsDataResult | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里的多个 if 判断和串行 await 可以合并优化。使用 Promise.all 并行加载数据,并整合 if (selectedNode.value) 判断,可以使代码更简洁高效。
// 并行重新加载数据以提升性能
if (selectedNode.value) {
const serviceName = selectedNode.value.name
const [serviceDetailResult, availableVersionsResult, metricsDataResult] = await Promise.all([
loadServiceDetail(serviceName),
loadServiceAvailableVersions(serviceName),
loadServiceMetrics(serviceName)
])
if (serviceDetailResult) {
selectedNode.value = { ...serviceDetailResult, status: getNodeStatus(serviceDetailResult) }
}
if (availableVersionsResult) {
currentServiceAvailableVersions.value = availableVersionsResult
}
if (metricsDataResult) {
currentServiceMetrics.value = metricsDataResult
}
}
变更背景和解决方案
关联issue: #
文档更新(架构文档、API文档、升级文档)
Checklist