fix(ui):修复管理端的页面显示问题

This commit is contained in:
qian committed 2026-08-01 23:55:27 +08:00
1 parent ec4a4682e5
commit 14b9bbd4e9
6 files changed
+38 -28

No files matched your search

@@ -1,7 +1,8 @@
<script setup lang="ts">
import { onErrorCaptured, ref } from 'vue'
import { useRouter } from 'vue-router'
import { onErrorCaptured, ref, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
const route = useRoute()
const router = useRouter()
const error = ref<unknown>(null)
@@ -11,6 +12,12 @@ onErrorCaptured((caughtError, _instance, info) => {
return false
})
// 边界不再随路由 :key 重建,需在路由切换时主动清除上一个页面的错误状态,
// 避免新页面继续展示错误兜底。
watch(() => route.fullPath, () => {
error.value = null
})
function reloadPage() {
window.location.reload()
}
+5 -5
View File
@@ -614,11 +614,11 @@ onUnmounted(() => {
<!-- Content -->
<main class="admin-content page-bg">
<router-view v-slot="{ Component, route: currentRoute }">
<Transition name="page-fade" mode="out-in">
<RouteErrorBoundary :key="currentRoute.fullPath">
<component :is="Component" />
</RouteErrorBoundary>
</Transition>
<RouteErrorBoundary>
<Transition name="page-fade" mode="out-in">
<component :is="Component" :key="currentRoute.fullPath" />
</Transition>
</RouteErrorBoundary>
</router-view>
</main>
</div>
+2 -1
View File
@@ -2,6 +2,7 @@
import { ref, reactive, onMounted, h } from 'vue'
import { useRouter } from 'vue-router'
import { Tag, Button, Space, Popconfirm, Message, Radio } from '@arco-design/web-vue'
import { IconInfoCircle } from '@arco-design/web-vue/es/icon'
import type { TableColumnData } from '@arco-design/web-vue'
import type { FormInstance } from '@arco-design/web-vue'
import PageHeader from '@/components/PageHeader.vue'
@@ -312,7 +313,7 @@ const { exporting, exportFile } = useExport({
<!-- 渠道调度说明(点击弹窗) -->
<div class="scheduling-hint" @click="showSchedulingGuide = true">
<icon-info-circle /> 了解优先级、权重、亲和与容量如何共同调度 →
<IconInfoCircle /> 了解优先级、权重、亲和与容量如何共同调度 →
</div>
<!-- 调度说明弹窗 -->
@@ -66,7 +66,7 @@
<!-- Regenerate Backup Codes Modal -->
<a-modal v-model:visible="showRegenerateModal" title="重新生成恢复码" @ok="handleRegenerate" :maskClosable="false">
<a-form layout="vertical">
<a-form :model="{ code: regenerateCode }" layout="vertical">
<a-form-item label="输入验证码">
<a-input v-model="regenerateCode" placeholder="6位数字验证码" maxlength="6" />
</a-form-item>
+13 -11
View File
@@ -367,8 +367,10 @@ function manualCleanup() {
// ============================================================
const exportVisible = ref(false)
const exportLoading = ref(false)
const exportTenantID = ref<number | undefined>(undefined)
const exportScopes = ref<string[]>(['members', 'usage', 'billing', 'logs'])
const exportForm = reactive<{ tenant_id: number | undefined; scopes: string[] }>({
tenant_id: undefined,
scopes: ['members', 'usage', 'billing', 'logs'],
})
const SCOPE_OPTIONS = [
{ label: '成员信息', value: 'members' },
@@ -378,25 +380,25 @@ const SCOPE_OPTIONS = [
]
function openExportDialog() {
exportTenantID.value = undefined
exportScopes.value = ['members', 'usage', 'billing', 'logs']
exportForm.tenant_id = undefined
exportForm.scopes = ['members', 'usage', 'billing', 'logs']
exportVisible.value = true
}
async function submitExport() {
if (!exportTenantID.value || exportTenantID.value <= 0) {
if (!exportForm.tenant_id || exportForm.tenant_id <= 0) {
Message.warning('请输入租户 ID')
return
}
if (exportScopes.value.length === 0) {
if (exportForm.scopes.length === 0) {
Message.warning('请至少选择一项导出范围')
return
}
exportLoading.value = true
try {
const res: any = await request.post('/admin/data-governance/export', {
tenant_id: exportTenantID.value,
scopes: exportScopes.value,
tenant_id: exportForm.tenant_id,
scopes: exportForm.scopes,
})
const taskID = res.data?.data?.task_id
Message.success(`导出任务已创建(任务 #${taskID}),文件生成后将在列表中显示(约 1 分钟内)`)
@@ -528,17 +530,17 @@ onMounted(() => {
@ok="submitExport"
@cancel="exportVisible = false"
>
<AForm layout="vertical">
<AForm :model="exportForm" layout="vertical">
<AFormItem label="租户 ID" required>
<AInputNumber
v-model="exportTenantID"
v-model="exportForm.tenant_id"
:min="1"
placeholder="输入要导出数据的租户 ID"
style="width:100%"
/>
</AFormItem>
<AFormItem label="导出范围" required>
<Checkbox.Group v-model="exportScopes">
<Checkbox.Group v-model="exportForm.scopes">
<Space direction="vertical">
<Checkbox v-for="opt in SCOPE_OPTIONS" :key="opt.value" :value="opt.value">
{{ opt.label }}
+8 -8
View File
@@ -27,7 +27,7 @@ const editingId = ref<number | null>(null)
const showResetModal = ref(false)
const resetTarget = ref<any>(null)
const resetPasswordValue = ref('')
const resetForm = reactive({ new_password: '' })
const resetLoading = ref(false)
const form = reactive({
@@ -202,25 +202,25 @@ function generateRandomPassword(length = 16) {
function openResetPassword(row: any) {
resetTarget.value = row
resetPasswordValue.value = ''
resetForm.new_password = ''
showResetModal.value = true
}
function fillRandomPassword() {
resetPasswordValue.value = generateRandomPassword()
resetForm.new_password = generateRandomPassword()
}
async function handleResetPassword(done: () => void) {
if (!resetPasswordValue.value || resetPasswordValue.value.length < 8) {
if (!resetForm.new_password || resetForm.new_password.length < 8) {
Message.warning('请输入新密码(至少8位)')
return false
}
resetLoading.value = true
try {
await request.put(`/admin/users/${resetTarget.value.id}/reset-password`, {
new_password: resetPasswordValue.value,
new_password: resetForm.new_password,
})
const pwd = resetPasswordValue.value
const pwd = resetForm.new_password
done()
Modal.success({
title: '密码重置成功',
@@ -338,10 +338,10 @@ const { exporting, exportFile } = useExport({
:ok-loading="resetLoading"
ok-text="确认重置"
>
<AForm :auto-label-width="true" layout="vertical">
<AForm :model="resetForm" :auto-label-width="true" layout="vertical">
<AFormItem field="new_password" label="新密码">
<AInput
v-model="resetPasswordValue"
v-model="resetForm.new_password"
placeholder="请输入新密码(至少8位),或点击随机生成"
>
<template #append>