feat(frontend): adapt delivery form to single root account and credential_available

- Remove mysql_admin_password from CreateMySQLDeliveryPayload;
  the delivery form submits a single root password only
- Wire the task's credential_available boolean into the Catalog
  workbench: sync on create/poll/restore, and hide the one-time
  credential entry once it has been claimed
- Preview mock credential account_host changed from localhost to %
This commit is contained in:
Hungerdream
2026-07-29 18:07:49 +08:00
parent ef6508938c
commit 2de6a1f498
2 changed files with 13 additions and 5 deletions
-1
View File
@@ -45,7 +45,6 @@ export interface CreateMySQLDeliveryPayload {
binlog_expire_logs_seconds?: number binlog_expire_logs_seconds?: number
max_binlog_size?: string max_binlog_size?: string
mysql_root_password?: string mysql_root_password?: string
mysql_admin_password?: string
} }
export interface DeliveryTask { export interface DeliveryTask {
+13 -4
View File
@@ -788,6 +788,7 @@ const taskStateLoading = ref(false)
const credentialRevealed = ref(false) const credentialRevealed = ref(false)
const credentialDismissed = ref(false) const credentialDismissed = ref(false)
const credentialRevealing = ref(false) const credentialRevealing = ref(false)
const credentialAvailable = ref<boolean>()
const revealedCredentials = ref<DeploymentCredential[]>([]) const revealedCredentials = ref<DeploymentCredential[]>([])
const deliveryHistory = ref<DeliveryHistoryItem[]>(loadDeliveryHistory()) const deliveryHistory = ref<DeliveryHistoryItem[]>(loadDeliveryHistory())
let workbenchReady = false let workbenchReady = false
@@ -912,7 +913,10 @@ const runnerPreview = computed(() => {
].join('\n') ].join('\n')
}) })
const connectionReady = computed(() => Boolean(deliveredHost.value && deliveredPort.value)) const connectionReady = computed(() => Boolean(deliveredHost.value && deliveredPort.value))
const credentialEligible = computed(() => connectionReady.value && ['finished', 'register_failed'].includes(lastDeliveryStatus.value)) const credentialEligible = computed(() => {
if (!connectionReady.value || !['finished', 'register_failed'].includes(lastDeliveryStatus.value)) return false
return credentialAvailable.value !== false
})
const revealedRootCredential = computed(() => revealedCredentials.value.find((item) => item.username === 'root')) const revealedRootCredential = computed(() => revealedCredentials.value.find((item) => item.username === 'root'))
const resultReady = computed(() => !taskStateLoading.value && !running.value && isTerminalDeliveryStatus(lastDeliveryStatus.value)) const resultReady = computed(() => !taskStateLoading.value && !running.value && isTerminalDeliveryStatus(lastDeliveryStatus.value))
const previewAddress = computed(() => `${selectedHost.value?.ip || 'AWX 自动分配'}:${deliveryForm.port || '自动端口'}`) const previewAddress = computed(() => `${selectedHost.value?.ip || 'AWX 自动分配'}:${deliveryForm.port || '自动端口'}`)
@@ -1130,6 +1134,7 @@ async function restoreWorkbench() {
steps.value = snapshot.steps?.length ? snapshot.steps : defaultSteps() steps.value = snapshot.steps?.length ? snapshot.steps : defaultSteps()
credentialRevealed.value = false credentialRevealed.value = false
credentialDismissed.value = Boolean(snapshot.deploymentId) credentialDismissed.value = Boolean(snapshot.deploymentId)
credentialAvailable.value = undefined
if (snapshot.deploymentId) { if (snapshot.deploymentId) {
taskStateLoading.value = true taskStateLoading.value = true
@@ -1138,6 +1143,7 @@ async function restoreWorkbench() {
deliveredHost.value = data.task.target_host_ip || deliveredHost.value deliveredHost.value = data.task.target_host_ip || deliveredHost.value
deliveredPort.value = data.task.mysql_port || deliveredPort.value deliveredPort.value = data.task.mysql_port || deliveredPort.value
lastDeliveryStatus.value = data.task.status lastDeliveryStatus.value = data.task.status
credentialAvailable.value = data.task.credential_available
deliveryError.value = data.task.error_message || deliveryError.value deliveryError.value = data.task.error_message || deliveryError.value
seenEventIds.value = new Set(data.events.map((event) => event.id)) seenEventIds.value = new Set(data.events.map((event) => event.id))
applyDeliveryStatus(data.task.status, data.task.error_message || '') applyDeliveryStatus(data.task.status, data.task.error_message || '')
@@ -1220,6 +1226,7 @@ function resetExecutionState() {
deliveryFailed.value = false deliveryFailed.value = false
credentialRevealed.value = false credentialRevealed.value = false
credentialDismissed.value = false credentialDismissed.value = false
credentialAvailable.value = undefined
revealedCredentials.value = [] revealedCredentials.value = []
deliveryError.value = '' deliveryError.value = ''
lastDeliveryStatus.value = '' lastDeliveryStatus.value = ''
@@ -1345,6 +1352,7 @@ async function createTask() {
try { try {
const task = await deliveryApi.createMySQL(mysqlDeliveryPayload(businessLineId)) const task = await deliveryApi.createMySQL(mysqlDeliveryPayload(businessLineId))
deploymentId.value = task.id deploymentId.value = task.id
credentialAvailable.value = task.credential_available
deliveryForm.rootPassword = '' deliveryForm.rootPassword = ''
upsertDeliveryHistory(task.id, task.status, task.error_message || '', task.created_at) upsertDeliveryHistory(task.id, task.status, task.error_message || '', task.created_at)
deliveryLog.value += `\n[task] ${task.id} created by ${currentName.value}` deliveryLog.value += `\n[task] ${task.id} created by ${currentName.value}`
@@ -1402,9 +1410,8 @@ function mysqlDeliveryPayload(businessLineId: number) {
long_query_time: deliveryForm.longQueryTime, long_query_time: deliveryForm.longQueryTime,
binlog_expire_logs_seconds: deliveryForm.binlogExpireSeconds, binlog_expire_logs_seconds: deliveryForm.binlogExpireSeconds,
max_binlog_size: deliveryForm.maxBinlogSize, max_binlog_size: deliveryForm.maxBinlogSize,
// root 密码以表单为准;后端要求 root/admin 成对传入,平台管理账号密码随机生成 // 交付只提供一个允许远程访问的 root 管理员账号。
mysql_root_password: deliveryForm.rootPassword, mysql_root_password: deliveryForm.rootPassword,
mysql_admin_password: generateRootPassword(),
} }
return payload return payload
} }
@@ -1440,6 +1447,7 @@ async function pollTask(id: string) {
const data = await deliveryApi.getTask(id) const data = await deliveryApi.getTask(id)
deliveredHost.value = data.task.target_host_ip || deliveredHost.value deliveredHost.value = data.task.target_host_ip || deliveredHost.value
deliveredPort.value = data.task.mysql_port || deliveredPort.value deliveredPort.value = data.task.mysql_port || deliveredPort.value
credentialAvailable.value = data.task.credential_available
upsertDeliveryHistory(id, data.task.status, data.task.error_message || '', data.task.created_at) upsertDeliveryHistory(id, data.task.status, data.task.error_message || '', data.task.created_at)
applyTaskEvents(data.events) applyTaskEvents(data.events)
applyDeliveryStatus(data.task.status, data.task.error_message || '') applyDeliveryStatus(data.task.status, data.task.error_message || '')
@@ -1533,6 +1541,7 @@ function setupCredentialPreview() {
deliveredPort.value = 13306 deliveredPort.value = 13306
credentialRevealed.value = false credentialRevealed.value = false
credentialDismissed.value = false credentialDismissed.value = false
credentialAvailable.value = true
revealedCredentials.value = [] revealedCredentials.value = []
upsertDeliveryHistory(deploymentId.value, 'finished', '', new Date().toISOString()) upsertDeliveryHistory(deploymentId.value, 'finished', '', new Date().toISOString())
if (deliveryHistory.value.length < 3) { if (deliveryHistory.value.length < 3) {
@@ -1679,7 +1688,7 @@ async function revealCredential() {
host: deliveredHost.value || '10.24.18.21', host: deliveredHost.value || '10.24.18.21',
port: deliveredPort.value || 13306, port: deliveredPort.value || 13306,
username: 'root', username: 'root',
account_host: 'localhost', account_host: '%',
password: deliveryForm.rootPassword, password: deliveryForm.rootPassword,
}] }]
} else { } else {