fix(前端): 兼容非安全上下文的任务请求键生成
crypto.randomUUID 仅在 HTTPS 或 localhost 下存在,客户内网 以 http://<内网IP> 访问时该 API 为 undefined,而新建任务 对话框在页面挂载即调用,会直接 TypeError 导致整页白屏。 新增 newRequestKey 工具:优先 randomUUID,不可用时降级为 getRandomValues 拼 v4 格式(非安全上下文仍可用)。 Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
parent
ee801652e3
commit
37eb51513f
11
frontend/src/utils/uuid.ts
Normal file
11
frontend/src/utils/uuid.ts
Normal file
@ -0,0 +1,11 @@
|
||||
// crypto.randomUUID 仅在安全上下文(HTTPS 或 localhost)存在;客户内网常以
|
||||
// http://<内网IP> 访问,此时该 API 为 undefined。降级用 getRandomValues 拼
|
||||
// v4 格式(getRandomValues 在非安全上下文仍然可用)。
|
||||
export function newRequestKey(): string {
|
||||
if (typeof crypto.randomUUID === 'function') return crypto.randomUUID()
|
||||
const bytes = crypto.getRandomValues(new Uint8Array(16))
|
||||
bytes[6] = (bytes[6] & 0x0f) | 0x40 // version 4
|
||||
bytes[8] = (bytes[8] & 0x3f) | 0x80 // variant 10x
|
||||
const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, '0'))
|
||||
return `${hex.slice(0, 4).join('')}-${hex.slice(4, 6).join('')}-${hex.slice(6, 8).join('')}-${hex.slice(8, 10).join('')}-${hex.slice(10, 16).join('')}`
|
||||
}
|
||||
@ -3,6 +3,7 @@ import { ref, watch } from 'vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import * as api from '@/api/tplus'
|
||||
import { handledError } from '@/utils/error'
|
||||
import { newRequestKey } from '@/utils/uuid'
|
||||
import { entities } from './labels'
|
||||
|
||||
const visible = defineModel<boolean>({ required: true })
|
||||
@ -11,9 +12,9 @@ const emit = defineEmits<{ created: [batch: api.TPlusDetail] }>()
|
||||
const taskType = ref<api.TaskType>('READ')
|
||||
const selected = ref<api.EntityType[]>(['personnel'])
|
||||
const pending = ref(false)
|
||||
let requestKey = crypto.randomUUID()
|
||||
let requestKey = newRequestKey()
|
||||
// 请求失败后保留键,只有意图改变或成功后才换键。
|
||||
watch([taskType, selected], () => { requestKey = crypto.randomUUID() }, { deep: true, flush: 'sync' })
|
||||
watch([taskType, selected], () => { requestKey = newRequestKey() }, { deep: true, flush: 'sync' })
|
||||
|
||||
async function submit(): Promise<void> {
|
||||
if (pending.value || !props.configured) return
|
||||
@ -21,7 +22,7 @@ async function submit(): Promise<void> {
|
||||
try {
|
||||
const batch = await api.createTask({ task_type: taskType.value,
|
||||
entity_types: taskType.value === 'AUDIT' ? [] : [...selected.value], request_key: requestKey })
|
||||
requestKey = crypto.randomUUID()
|
||||
requestKey = newRequestKey()
|
||||
visible.value = false
|
||||
ElMessage.success('任务已排队,处理完成后可刷新查看')
|
||||
emit('created', batch)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user