refactor(frontend): UI/UX改进和组件优化

- DataTable组件操作列自适应
- 优化各种Modal弹窗
- 统一API调用方式(AbortSignal)
- 添加全局订阅状态管理
- 优化各管理视图的交互和布局
- 修复国际化翻译问题
This commit is contained in:
IanShaw027
2025-12-28 01:00:06 +08:00
parent 9bbe468c91
commit 506cb21cb1
46 changed files with 1582 additions and 644 deletions

View File

@@ -223,18 +223,19 @@
:total="pagination.total"
:page-size="pagination.page_size"
@update:page="handlePageChange"
@update:pageSize="handlePageSizeChange"
/>
</template>
</TablePageLayout>
<!-- Create Group Modal -->
<Modal
<BaseDialog
:show="showCreateModal"
:title="t('admin.groups.createGroup')"
size="lg"
width="normal"
@close="closeCreateModal"
>
<form @submit.prevent="handleCreateGroup" class="space-y-5">
<form id="create-group-form" @submit.prevent="handleCreateGroup" class="space-y-5">
<div>
<label class="input-label">{{ t('admin.groups.form.name') }}</label>
<input
@@ -345,11 +346,19 @@
</div>
</div>
</form>
<template #footer>
<div class="flex justify-end gap-3 pt-4">
<button @click="closeCreateModal" type="button" class="btn btn-secondary">
{{ t('common.cancel') }}
</button>
<button type="submit" :disabled="submitting" class="btn btn-primary">
<button
type="submit"
form="create-group-form"
:disabled="submitting"
class="btn btn-primary"
>
<svg
v-if="submitting"
class="-ml-1 mr-2 h-4 w-4 animate-spin"
@@ -373,17 +382,22 @@
{{ submitting ? t('admin.groups.creating') : t('common.create') }}
</button>
</div>
</form>
</Modal>
</template>
</BaseDialog>
<!-- Edit Group Modal -->
<Modal
<BaseDialog
:show="showEditModal"
:title="t('admin.groups.editGroup')"
size="lg"
width="normal"
@close="closeEditModal"
>
<form v-if="editingGroup" @submit.prevent="handleUpdateGroup" class="space-y-5">
<form
v-if="editingGroup"
id="edit-group-form"
@submit.prevent="handleUpdateGroup"
class="space-y-5"
>
<div>
<label class="input-label">{{ t('admin.groups.form.name') }}</label>
<input v-model="editForm.name" type="text" required class="input" />
@@ -490,11 +504,19 @@
</div>
</div>
</form>
<template #footer>
<div class="flex justify-end gap-3 pt-4">
<button @click="closeEditModal" type="button" class="btn btn-secondary">
{{ t('common.cancel') }}
</button>
<button type="submit" :disabled="submitting" class="btn btn-primary">
<button
type="submit"
form="edit-group-form"
:disabled="submitting"
class="btn btn-primary"
>
<svg
v-if="submitting"
class="-ml-1 mr-2 h-4 w-4 animate-spin"
@@ -518,8 +540,8 @@
{{ submitting ? t('admin.groups.updating') : t('common.update') }}
</button>
</div>
</form>
</Modal>
</template>
</BaseDialog>
<!-- Delete Confirmation Dialog -->
<ConfirmDialog
@@ -546,7 +568,7 @@ import AppLayout from '@/components/layout/AppLayout.vue'
import TablePageLayout from '@/components/layout/TablePageLayout.vue'
import DataTable from '@/components/common/DataTable.vue'
import Pagination from '@/components/common/Pagination.vue'
import Modal from '@/components/common/Modal.vue'
import BaseDialog from '@/components/common/BaseDialog.vue'
import ConfirmDialog from '@/components/common/ConfirmDialog.vue'
import EmptyState from '@/components/common/EmptyState.vue'
import Select from '@/components/common/Select.vue'
@@ -616,6 +638,8 @@ const pagination = reactive({
pages: 0
})
let abortController: AbortController | null = null
const showCreateModal = ref(false)
const showEditModal = ref(false)
const showDeleteDialog = ref(false)
@@ -660,21 +684,33 @@ const deleteConfirmMessage = computed(() => {
})
const loadGroups = async () => {
if (abortController) {
abortController.abort()
}
const currentController = new AbortController()
abortController = currentController
const { signal } = currentController
loading.value = true
try {
const response = await adminAPI.groups.list(pagination.page, pagination.page_size, {
platform: (filters.platform as GroupPlatform) || undefined,
status: filters.status as any,
is_exclusive: filters.is_exclusive ? filters.is_exclusive === 'true' : undefined
})
}, { signal })
if (signal.aborted) return
groups.value = response.items
pagination.total = response.total
pagination.pages = response.pages
} catch (error) {
} catch (error: any) {
if (signal.aborted || error?.name === 'AbortError' || error?.code === 'ERR_CANCELED') {
return
}
appStore.showError(t('admin.groups.failedToLoad'))
console.error('Error loading groups:', error)
} finally {
loading.value = false
if (abortController === currentController && !signal.aborted) {
loading.value = false
}
}
}
@@ -683,6 +719,12 @@ const handlePageChange = (page: number) => {
loadGroups()
}
const handlePageSizeChange = (pageSize: number) => {
pagination.page_size = pageSize
pagination.page = 1
loadGroups()
}
const closeCreateModal = () => {
showCreateModal.value = false
createForm.name = ''