优化领取页角色绑定校验

This commit is contained in:
yml
2026-05-31 23:39:15 +08:00
parent 9172e1f98e
commit 60cf7c2bbd
10 changed files with 398 additions and 65 deletions
@@ -248,6 +248,16 @@ export function mapClaimKuaishouCloudFulfillment(task: TaskRow, order: OrderRow)
const dispatch = source.dispatch && typeof source.dispatch === 'object' ? source.dispatch : {}
const returnNumber = source.returnNumber && typeof source.returnNumber === 'object' ? source.returnNumber : {}
const consume = source.consume && typeof source.consume === 'object' ? source.consume : {}
const roleName = String(role.name || binding.roleName || '').trim()
const roleId = String(role.rid || binding.roleId || '').trim()
const defaultRoleName = String(role.defaultName || role.defaultRoleName || '').trim()
const defaultRoleId = String(role.defaultRid || role.defaultRoleId || '').trim()
const isDefaultRole =
Boolean(roleName || roleId) &&
isSameClaimKuaishouCloudRole(
{ name: roleName, rid: roleId },
{ name: defaultRoleName, rid: defaultRoleId },
)
return {
flowType: 'kuaishou_cloud',
@@ -288,10 +298,16 @@ export function mapClaimKuaishouCloudFulfillment(task: TaskRow, order: OrderRow)
},
role: {
status: String(role.status || 'pending').trim() || 'pending',
name: String(role.name || binding.roleName || '').trim(),
rid: String(role.rid || binding.roleId || '').trim(),
name: roleName,
rid: roleId,
refreshedAt: role.refreshedAt || null,
errorMessage: String(role.errorMessage || '').trim(),
defaultName: defaultRoleName,
defaultRid: defaultRoleId,
defaultCapturedAt: role.defaultCapturedAt || null,
defaultCaptureStatus: String(role.defaultCaptureStatus || '').trim(),
defaultErrorMessage: String(role.defaultErrorMessage || '').trim(),
isDefaultRole,
},
purchase: {
autoBuyEnabled: purchase.autoBuyEnabled !== false,
@@ -351,6 +367,28 @@ function isPlainObject(value: unknown): value is JsonObject {
return Object.prototype.toString.call(value) === '[object Object]'
}
function isSameClaimKuaishouCloudRole(
left: { name?: unknown; rid?: unknown },
right: { name?: unknown; rid?: unknown },
) {
const leftRid = String(left.rid || '').trim()
const rightRid = String(right.rid || '').trim()
if (leftRid && rightRid) {
return leftRid === rightRid
}
const leftName = normalizeClaimRoleNameForCompare(left.name)
const rightName = normalizeClaimRoleNameForCompare(right.name)
return Boolean(leftName && rightName && leftName === rightName)
}
function normalizeClaimRoleNameForCompare(value: unknown) {
return String(value || '')
.trim()
.toLowerCase()
.replace(/\s+/g, '')
}
function normalizeClaimDeliveryItems(value: unknown, binding: JsonObject) {
const rawItems = Array.isArray(value) ? value : []
const items = rawItems
@@ -26,6 +26,8 @@ import {
import { isKuaishouEticketMockTicketCode } from '../platforms/kuaishou-eticket/mock-ticket-service.js'
import {
dispatchKuaishouCloudFulfillmentTask,
hasKuaishouCloudCustomerRole,
hasKuaishouCloudDefaultRoleSnapshot,
maskCode,
normalizeKuaishouCloudFlow,
prepareKuaishouCloudFulfillmentTask,
@@ -478,6 +480,19 @@ export async function confirmKuaishouCloudClaimRole(token: unknown) {
})
}
const hasDefaultRoleSnapshot = hasKuaishouCloudDefaultRoleSnapshot(flow)
if (!mockMode && !hasKuaishouCloudCustomerRole(flow)) {
const message = hasDefaultRoleSnapshot
? '当前仍是虚拟机默认角色,请先重新绑定自己的角色信息'
: '系统还未获取到虚拟机默认角色信息,请稍后刷新角色信息后再试'
throw createHttpError(message, {
statusCode: 409,
errorCode: hasDefaultRoleSnapshot
? 'claim_kuaishou_cloud_default_role_not_rebound'
: 'claim_kuaishou_cloud_default_role_not_ready',
})
}
await updateTask(context.task.id, {
task_status: TASK_STATUS.ROLE_CONFIRMED,
role_id: flow.binding.roleId,
@@ -36,6 +36,7 @@ export async function syncKuaishouCloudRoleInfo(task: TaskRow) {
source: 'claim_page_polling',
actor: { source: 'system' },
recordEvent: false,
forceProbe: flow.role.isDefaultRole === true,
})
return result.task || task
} catch {
@@ -0,0 +1,46 @@
import assert from 'node:assert/strict'
import test from 'node:test'
import {
hasKuaishouCloudCustomerRole,
normalizeKuaishouCloudFlow,
} from './domain.js'
test('hasKuaishouCloudCustomerRole 要求当前角色不同于虚拟机默认角色', () => {
const defaultRoleFlow = normalizeKuaishouCloudFlow({
binding: {
vnPhone: '13800000000',
roleName: '默认角色',
roleId: '10001',
},
role: {
name: '默认角色',
rid: '10001',
defaultName: '默认角色',
defaultRid: '10001',
defaultCapturedAt: '2026-05-31T00:00:00.000Z',
isDefaultRole: false,
},
})
assert.equal(defaultRoleFlow.role.isDefaultRole, true)
assert.equal(hasKuaishouCloudCustomerRole(defaultRoleFlow), false)
const customerRoleFlow = normalizeKuaishouCloudFlow({
...defaultRoleFlow,
binding: {
...defaultRoleFlow.binding,
roleName: '用户角色',
roleId: '20002',
},
role: {
...defaultRoleFlow.role,
name: '用户角色',
rid: '20002',
isDefaultRole: true,
},
})
assert.equal(customerRoleFlow.role.isDefaultRole, false)
assert.equal(hasKuaishouCloudCustomerRole(customerRoleFlow), true)
})
@@ -25,6 +25,16 @@ export function normalizeKuaishouCloudFlow(value: unknown) {
const roleName = String(role.name || binding.roleName || '').trim()
const roleId = String(role.rid || binding.roleId || '').trim()
const defaultRoleName = String(role.defaultName || role.defaultRoleName || '').trim()
const defaultRoleId = String(role.defaultRid || role.defaultRoleId || '').trim()
const hasDefaultRole = Boolean(defaultRoleName || defaultRoleId)
const isDefaultRole =
Boolean(roleName || roleId) &&
hasDefaultRole &&
isSameKuaishouCloudRoleIdentity(
{ name: roleName, rid: roleId },
{ name: defaultRoleName, rid: defaultRoleId },
)
const bindPreparedAt = binding.bindPreparedAt || null
const bindExpiresAt =
binding.bindExpiresAt || resolveKuaishouCloudBindUrlExpiresAt(bindPreparedAt)
@@ -72,6 +82,12 @@ export function normalizeKuaishouCloudFlow(value: unknown) {
refreshedAt: role.refreshedAt || null,
errorMessage: String(role.errorMessage || '').trim(),
rawInfo: role.rawInfo && typeof role.rawInfo === 'object' ? role.rawInfo : null,
defaultName: defaultRoleName,
defaultRid: defaultRoleId,
defaultCapturedAt: role.defaultCapturedAt || null,
defaultCaptureStatus: String(role.defaultCaptureStatus || '').trim(),
defaultErrorMessage: String(role.defaultErrorMessage || '').trim(),
isDefaultRole,
},
purchase: {
autoBuyEnabled: purchase.autoBuyEnabled !== false,
@@ -113,6 +129,49 @@ export function normalizeKuaishouCloudFlow(value: unknown) {
}
}
export function hasKuaishouCloudDefaultRoleSnapshot(flowLike: unknown) {
const flow = normalizeKuaishouCloudFlow(flowLike)
return Boolean(flow.role.defaultName || flow.role.defaultRid)
}
export function hasKuaishouCloudCustomerRole(flowLike: unknown) {
const flow = normalizeKuaishouCloudFlow(flowLike)
if (!flow.binding.vnPhone || !flow.binding.roleName || !flow.binding.roleId) {
return false
}
if (!hasKuaishouCloudDefaultRoleSnapshot(flow)) {
return false
}
return !isSameKuaishouCloudRoleIdentity(
{ name: flow.binding.roleName, rid: flow.binding.roleId },
{ name: flow.role.defaultName, rid: flow.role.defaultRid },
)
}
export function isSameKuaishouCloudRoleIdentity(
left: { name?: unknown; rid?: unknown },
right: { name?: unknown; rid?: unknown },
) {
const leftRid = String(left.rid || '').trim()
const rightRid = String(right.rid || '').trim()
if (leftRid && rightRid) {
return leftRid === rightRid
}
const leftName = normalizeRoleNameForCompare(left.name)
const rightName = normalizeRoleNameForCompare(right.name)
return Boolean(leftName && rightName && leftName === rightName)
}
function normalizeRoleNameForCompare(value: unknown) {
return String(value || '')
.trim()
.toLowerCase()
.replace(/\s+/g, '')
}
export function normalizeKuaishouCloudDeliveryItems(value: unknown) {
const source: JsonObject = value && typeof value === 'object' ? (value as JsonObject) : {}
const binding = source.binding && typeof source.binding === 'object' ? source.binding : {}
@@ -15,8 +15,11 @@ import { nowIso } from '../../../utils/time.js'
import { TASK_STATUS, normalizeTaskStatus } from '../../../domain/task-status.js'
import {
KUAISHOU_CLOUD_FIXED_VN_KEY,
hasKuaishouCloudCustomerRole,
hasKuaishouCloudDefaultRoleSnapshot,
isKuaishouCloudBindUrlFresh,
isKuaishouCloudTask,
isSameKuaishouCloudRoleIdentity,
maskPhone,
normalizeKuaishouCloudFlow,
normalizeKuaishouCloudRoleInfo,
@@ -51,17 +54,125 @@ type CloudDeliveryPlanItem = {
missingCount: number
}
type KuaishouCloudDefaultRoleSnapshot = {
defaultName: string
defaultRid: string
defaultCapturedAt: string | null
defaultCaptureStatus: string
defaultErrorMessage: string
}
export {
isKuaishouCloudBindUrlFresh,
isKuaishouCloudTask,
hasKuaishouCloudCustomerRole,
hasKuaishouCloudDefaultRoleSnapshot,
maskCode,
maskPhone,
normalizeKuaishouCloudFlow,
normalizeKuaishouCloudRoleInfo,
isSameKuaishouCloudRoleIdentity,
resolveKuaishouCloudBindUrlExpiresAt,
} from './domain.js'
export { resolvePersistedCloudtentaclesContextBySourceKeys } from './cloudtentacles-context.js'
async function captureKuaishouCloudDefaultRoleSnapshot({
cloudContext,
preparedBinding,
now,
}: {
cloudContext: JsonObject
preparedBinding: JsonObject
now: string
}): Promise<KuaishouCloudDefaultRoleSnapshot> {
try {
const bindInfoResult = await getCloudtentaclesBindInfo({
...cloudContext,
key: preparedBinding.vnKey,
id: preparedBinding.vnId,
})
const roleInfo = normalizeKuaishouCloudRoleInfo(bindInfoResult.bindInfo)
const hasRole = Boolean(roleInfo.name || roleInfo.rid)
return {
defaultName: roleInfo.name,
defaultRid: roleInfo.rid,
defaultCapturedAt: hasRole ? now : null,
defaultCaptureStatus: hasRole ? 'captured' : 'empty',
defaultErrorMessage: hasRole ? '' : '未获取到虚拟机默认角色信息,请稍后刷新',
}
} catch (error) {
return {
defaultName: '',
defaultRid: '',
defaultCapturedAt: null,
defaultCaptureStatus: 'failed',
defaultErrorMessage:
error instanceof Error ? error.message : '获取虚拟机默认角色信息失败,请稍后刷新',
}
}
}
function buildPendingRoleWithDefaultSnapshot(snapshot: KuaishouCloudDefaultRoleSnapshot) {
return {
status: 'pending',
name: '',
rid: '',
refreshedAt: null as null,
errorMessage: snapshot.defaultErrorMessage || '',
rawInfo: null as null,
defaultName: snapshot.defaultName,
defaultRid: snapshot.defaultRid,
defaultCapturedAt: snapshot.defaultCapturedAt,
defaultCaptureStatus: snapshot.defaultCaptureStatus,
defaultErrorMessage: snapshot.defaultErrorMessage,
isDefaultRole: false,
}
}
function buildRoleStateFromCurrentInfo({
flow,
roleInfo,
now,
emptyMessage,
}: {
flow: ReturnType<typeof normalizeKuaishouCloudFlow>
roleInfo: { name: string; rid: string; rawInfo?: unknown }
now: string
emptyMessage: string
}) {
const hasRoleInfo = Boolean(roleInfo.name || roleInfo.rid)
const hasDefaultRole = hasKuaishouCloudDefaultRoleSnapshot(flow)
const isDefaultRole =
hasRoleInfo &&
hasDefaultRole &&
isSameKuaishouCloudRoleIdentity(
{ name: roleInfo.name, rid: roleInfo.rid },
{ name: flow.role.defaultName, rid: flow.role.defaultRid },
)
return {
hasRoleInfo,
isDefaultRole,
bindingRoleName: hasRoleInfo ? roleInfo.name : '',
bindingRoleId: hasRoleInfo ? roleInfo.rid : '',
role: {
...flow.role,
status: hasRoleInfo && !isDefaultRole ? 'ready' : 'pending',
name: hasRoleInfo ? roleInfo.name : '',
rid: hasRoleInfo ? roleInfo.rid : '',
refreshedAt: now,
errorMessage: hasRoleInfo
? isDefaultRole
? '当前仍是虚拟机默认角色,请重新绑定自己的角色信息'
: ''
: emptyMessage,
rawInfo: roleInfo.rawInfo || null,
isDefaultRole,
},
}
}
export async function ensureTaskClaimLink(task: TaskRow) {
const tokenStatus = String(task?.primary_claim_token_status || '').trim()
const token = String(task?.primary_claim_token || task?.claim_token || '').trim()
@@ -201,6 +312,11 @@ export async function prepareKuaishouCloudFulfillmentTask(task: TaskRow, options
cloudContext,
vnKeyCandidates,
})
const defaultRoleSnapshot = await captureKuaishouCloudDefaultRoleSnapshot({
cloudContext,
preparedBinding,
now,
})
const nextContext = {
...taskContext,
@@ -222,14 +338,7 @@ export async function prepareKuaishouCloudFulfillmentTask(task: TaskRow, options
roleName: '',
roleId: '',
},
role: {
status: 'pending',
name: '',
rid: '',
refreshedAt: null as null,
errorMessage: '',
rawInfo: null as null,
},
role: buildPendingRoleWithDefaultSnapshot(defaultRoleSnapshot),
purchase: {
...flowWithResolvedBinding.purchase,
usedKnapsack,
@@ -281,6 +390,9 @@ export async function prepareKuaishouCloudFulfillmentTask(task: TaskRow, options
})),
resolvedByName: resolvedBinding.resolvedByName,
accountSelection: buildCloudtentaclesSourceSelectionEventDetail(selectedCloud),
defaultRoleName: defaultRoleSnapshot.defaultName,
defaultRoleId: defaultRoleSnapshot.defaultRid,
defaultRoleCaptureStatus: defaultRoleSnapshot.defaultCaptureStatus,
actor,
},
now,
@@ -377,6 +489,14 @@ export async function refreshKuaishouCloudTaskBindUrl(task: TaskRow, options: Js
}
}
const defaultRoleSnapshot =
normalizeTaskStatus(task.task_status) === TASK_STATUS.ROLE_CONFIRMED
? null
: await captureKuaishouCloudDefaultRoleSnapshot({
cloudContext,
preparedBinding,
now,
})
const nextContext = {
...taskContext,
kuaishouCloudFulfillment: {
@@ -405,14 +525,7 @@ export async function refreshKuaishouCloudTaskBindUrl(task: TaskRow, options: Js
role:
normalizeTaskStatus(task.task_status) === TASK_STATUS.ROLE_CONFIRMED
? flow.role
: {
status: 'pending',
name: '',
rid: '',
refreshedAt: null,
errorMessage: '',
rawInfo: null,
},
: buildPendingRoleWithDefaultSnapshot(defaultRoleSnapshot!),
},
}
@@ -648,6 +761,11 @@ export async function rebindKuaishouCloudTaskRole(task: TaskRow, options: JsonOb
const claimLinkState = await ensureTaskClaimLink(task)
const nextBindExpiresAt = resolveKuaishouCloudBindUrlExpiresAt(now)
const defaultRoleSnapshot = await captureKuaishouCloudDefaultRoleSnapshot({
cloudContext,
preparedBinding,
now,
})
const nextContext = {
...taskContext,
kuaishouCloudFulfillment: {
@@ -667,14 +785,7 @@ export async function rebindKuaishouCloudTaskRole(task: TaskRow, options: JsonOb
roleName: '',
roleId: '',
},
role: {
status: 'pending',
name: '',
rid: '',
refreshedAt: null,
errorMessage: '',
rawInfo: null,
},
role: buildPendingRoleWithDefaultSnapshot(defaultRoleSnapshot),
rebind: {
...previousRebind,
currentAttempt: attempt,
@@ -723,6 +834,9 @@ export async function rebindKuaishouCloudTaskRole(task: TaskRow, options: JsonOb
vnId: preparedBinding.vnId,
vnPhoneMasked: maskPhone(preparedBinding.vnPhone),
bindUrl: preparedBinding.bindUrl,
defaultRoleName: defaultRoleSnapshot.defaultName,
defaultRoleId: defaultRoleSnapshot.defaultRid,
defaultRoleCaptureStatus: defaultRoleSnapshot.defaultCaptureStatus,
actor,
},
now,
@@ -787,6 +901,14 @@ export async function probeKuaishouCloudTaskBindUrl(task: TaskRow, options: Json
const probeRoleInfo = normalizeKuaishouCloudRoleInfo(probe.roleInfo)
const hasRoleInfo = Boolean(probeRoleInfo.name || probeRoleInfo.rid)
const roleState = hasRoleInfo
? buildRoleStateFromCurrentInfo({
flow,
roleInfo: probeRoleInfo,
now,
emptyMessage: '当前还没有查询到角色信息,请完成绑定后稍等片刻再试',
})
: null
const nextContext = {
...taskContext,
kuaishouCloudFulfillment: {
@@ -796,24 +918,16 @@ export async function probeKuaishouCloudTaskBindUrl(task: TaskRow, options: Json
bindProbeAt: now,
bindProbeStatus: probe.valid ? 'valid' : 'invalid',
bindProbeMessage: String(probe.message || probe.reason || '').trim(),
roleName: hasRoleInfo ? probeRoleInfo.name : flow.binding.roleName,
roleId: hasRoleInfo ? probeRoleInfo.rid : flow.binding.roleId,
},
role: {
...flow.role,
status: hasRoleInfo ? 'ready' : flow.role.status,
name: hasRoleInfo ? probeRoleInfo.name : flow.role.name,
rid: hasRoleInfo ? probeRoleInfo.rid : flow.role.rid,
refreshedAt: hasRoleInfo ? now : flow.role.refreshedAt,
errorMessage: hasRoleInfo ? '' : flow.role.errorMessage,
rawInfo: hasRoleInfo ? probeRoleInfo.rawInfo : flow.role.rawInfo,
roleName: roleState ? roleState.bindingRoleName : flow.binding.roleName,
roleId: roleState ? roleState.bindingRoleId : flow.binding.roleId,
},
role: roleState ? roleState.role : flow.role,
},
}
const updatedTask = await updateTask(task.id, {
role_id: hasRoleInfo ? probeRoleInfo.rid : task.role_id,
role_name: hasRoleInfo ? probeRoleInfo.name : task.role_name,
role_id: roleState && !roleState.isDefaultRole ? probeRoleInfo.rid : task.role_id,
role_name: roleState && !roleState.isDefaultRole ? probeRoleInfo.name : task.role_name,
context_json: JSON.stringify(nextContext),
updated_at: now,
})
@@ -956,30 +1070,28 @@ export async function refreshKuaishouCloudTaskRoleInfo(task: TaskRow, options: J
})
const bindInfo = normalizeKuaishouCloudRoleInfo(bindInfoResult.bindInfo)
const hasRoleInfo = Boolean(bindInfo.name || bindInfo.rid)
const roleState = buildRoleStateFromCurrentInfo({
flow,
roleInfo: bindInfo,
now,
emptyMessage: '当前还没有查询到角色信息,请完成绑定后稍等片刻再试',
})
const nextContext = {
...taskContext,
kuaishouCloudFulfillment: {
...flow,
binding: {
...flow.binding,
roleName: hasRoleInfo ? bindInfo.name : '',
roleId: hasRoleInfo ? bindInfo.rid : '',
},
role: {
status: hasRoleInfo ? 'ready' : 'pending',
name: hasRoleInfo ? bindInfo.name : '',
rid: hasRoleInfo ? bindInfo.rid : '',
refreshedAt: now,
errorMessage: hasRoleInfo ? '' : '当前还没有查询到角色信息,请完成绑定后稍等片刻再试',
rawInfo: bindInfo.rawInfo,
roleName: roleState.bindingRoleName,
roleId: roleState.bindingRoleId,
},
role: roleState.role,
},
}
const updatedTask = await updateTask(task.id, {
role_id: hasRoleInfo ? bindInfo.rid : '',
role_name: hasRoleInfo ? bindInfo.name : '',
role_id: roleState.hasRoleInfo && !roleState.isDefaultRole ? bindInfo.rid : '',
role_name: roleState.hasRoleInfo && !roleState.isDefaultRole ? bindInfo.name : '',
context_json: JSON.stringify(nextContext),
updated_at: now,
})
+6
View File
@@ -93,6 +93,12 @@ export interface ClaimKuaishouCloudFlowInfo {
rid: string
refreshedAt: string | null
errorMessage: string
defaultName: string
defaultRid: string
defaultCapturedAt: string | null
defaultCaptureStatus: string
defaultErrorMessage: string
isDefaultRole: boolean
}
purchase: {
autoBuyEnabled: boolean
@@ -51,7 +51,8 @@ const claim = useKuaishouCloudClaim(() => props.token)
:qr-code-data-url="claim.qrCodeDataUrl.value"
:is-binding-prepared="claim.isBindingPrepared.value"
:is-binding-preparing="claim.isBindingPreparing.value"
:is-role-ready="claim.isRoleReady.value"
:is-customer-role-ready="claim.isCustomerRoleReady.value"
:confirm-role-disabled-reason="claim.confirmRoleDisabledReason.value"
:role-name="claim.roleName.value"
:role-id="claim.roleId.value"
:refreshing-role="claim.refreshingRole.value"
@@ -7,7 +7,8 @@ defineProps<{
qrCodeDataUrl: string
isBindingPrepared: boolean
isBindingPreparing: boolean
isRoleReady: boolean
isCustomerRoleReady: boolean
confirmRoleDisabledReason: string
roleName: string
roleId: string
refreshingRole: boolean
@@ -41,7 +42,7 @@ defineEmits<{
<span>系统正在准备绑定资源请稍后自动刷新</span>
</div>
<div class="role-panel" :class="{ pending: !isRoleReady }">
<div class="role-panel" :class="{ pending: !isCustomerRoleReady }">
<div class="role-panel__item">
<span>当前角色</span>
<strong>{{ roleName || '待识别' }}</strong>
@@ -52,6 +53,10 @@ defineEmits<{
</div>
</div>
<div v-if="flow.role.isDefaultRole" class="status-banner warning">
<span>当前仍是虚拟机默认角色请重新绑定自己的角色信息</span>
</div>
<div class="action-row">
<el-button size="large" plain :loading="refreshingRole" @click="$emit('refreshRole')">
<el-icon><RefreshRight /></el-icon>
@@ -66,15 +71,23 @@ defineEmits<{
>
换绑角色
</el-button>
<el-button
type="primary"
size="large"
:loading="confirmingRole"
:disabled="!isBindingPrepared || !isRoleReady || rebindingRole"
@click="$emit('confirmRole')"
<el-tooltip
:disabled="!confirmRoleDisabledReason"
:content="confirmRoleDisabledReason"
placement="top"
>
我已完成绑定下一步
</el-button>
<span class="action-tooltip-wrap">
<el-button
type="primary"
size="large"
:loading="confirmingRole"
:disabled="Boolean(confirmRoleDisabledReason)"
@click="$emit('confirmRole')"
>
我已完成绑定下一步
</el-button>
</span>
</el-tooltip>
</div>
<div class="meta-footer">
@@ -127,6 +140,11 @@ defineEmits<{
color: #1d4ed8;
}
.status-banner.warning {
background: #fff7ed;
color: #c2410c;
}
.qr-block {
display: flex;
flex-direction: column;
@@ -239,6 +257,10 @@ defineEmits<{
flex-wrap: wrap;
}
.action-tooltip-wrap {
display: inline-flex;
}
.action-row :deep(.el-button) {
margin-left: 0;
}
@@ -76,6 +76,31 @@ export function useKuaishouCloudClaim(token: () => string) {
const isBindingPreparing = computed(() => flow.value?.binding.prepareStatus === 'pending')
const canEnterBindingStep = computed(() => isTicketVerified.value)
const isRoleReady = computed(() => Boolean(roleName.value || roleId.value))
const hasDefaultRoleSnapshot = computed(() =>
Boolean(flow.value?.role.defaultName || flow.value?.role.defaultRid),
)
const isDefaultRole = computed(() => flow.value?.role.isDefaultRole === true)
const isCustomerRoleReady = computed(
() => isRoleReady.value && hasDefaultRoleSnapshot.value && !isDefaultRole.value,
)
const confirmRoleDisabledReason = computed(() => {
if (!isBindingPrepared.value) {
return '绑定二维码还在准备中,请稍后自动刷新'
}
if (!hasDefaultRoleSnapshot.value) {
return flow.value?.role.defaultErrorMessage || '系统还未获取到虚拟机默认角色信息,请稍后刷新'
}
if (!isRoleReady.value) {
return '请先扫码绑定自己的角色,并刷新角色信息'
}
if (isDefaultRole.value) {
return '当前仍是虚拟机默认角色,请重新绑定自己的角色信息'
}
if (rebindingRole.value) {
return '正在换绑角色,请稍候'
}
return ''
})
const isRoleConfirmed = computed(() => isKuaishouCloudRoleConfirmedStatus(task.value?.status))
const isDispatched = computed(
() => String(flow.value?.dispatch.status || '').trim() === 'success',
@@ -239,11 +264,15 @@ export function useKuaishouCloudClaim(token: () => string) {
refreshingRole.value = true
try {
await loadDetail({ silent: true })
if (isRoleReady.value) {
if (isCustomerRoleReady.value) {
showSuccess('角色信息已刷新')
} else if (isDefaultRole.value) {
showError('当前仍是虚拟机默认角色,请重新绑定自己的角色信息')
} else {
showError(
flow.value?.role.errorMessage || '暂时还没有识别到角色信息,请完成绑定后稍等片刻再试',
flow.value?.role.errorMessage ||
flow.value?.role.defaultErrorMessage ||
'暂时还没有识别到角色信息,请完成绑定后稍等片刻再试',
)
}
} finally {
@@ -441,6 +470,10 @@ export function useKuaishouCloudClaim(token: () => string) {
isBindingPreparing,
canEnterBindingStep,
isRoleReady,
hasDefaultRoleSnapshot,
isDefaultRole,
isCustomerRoleReady,
confirmRoleDisabledReason,
isRoleConfirmed,
isDispatched,
isRedeemFailed,