fix(ui):修复管理端的页面显示问题
This commit is contained in:
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()
|
||||
}
|
||||
|
||||
@@ -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,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>
|
||||
|
||||
@@ -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 }}
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in new issue
Block a user