安全页重构:免密登录与活跃会话;按钮规范统一
CI / test (push) Successful in 53s

This commit is contained in:
2026-07-30 12:23:16 +08:00
parent d0fbecbd43
commit d675b950ee
43 changed files with 1944 additions and 475 deletions
+33 -3
View File
@@ -8,7 +8,9 @@ import {
mockVolAttachments,
mockVolumes,
} from './mock'
import { mockOn, mocked, request } from './request'
import { reactive } from 'vue'
import { ApiError, mockOn, mocked, request } from './request'
import type {
AttachVnicRequest,
BootVolumeAttachment,
@@ -118,13 +120,41 @@ export function updateInstance(
})
}
export function terminateInstance(
/** 终止请求飞行中的实例(instance OCID):模块级响应式集合,列表页、
* 详情页与组件重挂载共用一把锁,防「关闭重开对话框后用相反的
* preserveBootVolume 并发提交」;跨浏览器页签由服务端同键 guard 兜底 */
export const terminatingInstances = reactive(new Set<string>())
/** Instance OCID 唯一标识物理实例;cfgId 不得拆成两把终止锁 */
export function terminatingKey(_cfgId: number, instanceId: string): string {
return instanceId
}
export async function terminateInstance(
cfgId: number,
instanceId: string,
preserveBootVolume: boolean,
region?: string,
): Promise<void> {
const key = terminatingKey(cfgId, instanceId)
if (terminatingInstances.has(key)) {
throw new ApiError(409, '该实例的终止请求正在处理中')
}
terminatingInstances.add(key)
try {
if (mockOn) return await mocked(undefined, 600)
return await requestTerminate(cfgId, instanceId, preserveBootVolume, region)
} finally {
terminatingInstances.delete(key)
}
}
function requestTerminate(
cfgId: number,
instanceId: string,
preserveBootVolume: boolean,
region?: string,
): Promise<void> {
if (mockOn) return mocked(undefined, 600)
return request(`/oci-configs/${cfgId}/instances/${encodeURIComponent(instanceId)}`, {
method: 'DELETE',
query: { preserveBootVolume, region },