详情页右上角增加刷新和删除图标
This commit is contained in:
parent
a7bcc7f06f
commit
026ee28248
@ -8,14 +8,14 @@
|
|||||||
<h1 class="page-title">{{ pageTitle }}</h1>
|
<h1 class="page-title">{{ pageTitle }}</h1>
|
||||||
<p class="page-description">{{ pageDescription }}</p>
|
<p class="page-description">{{ pageDescription }}</p>
|
||||||
</div>
|
</div>
|
||||||
<n-space>
|
<n-space align="center">
|
||||||
<!-- 侧边栏位置切换按钮 -->
|
<!-- 侧边栏位置切换按钮 -->
|
||||||
<n-button
|
<n-button
|
||||||
type="default"
|
type="default"
|
||||||
size="small"
|
size="medium"
|
||||||
@click="toggleSidebarPosition"
|
@click="toggleSidebarPosition"
|
||||||
:title="sidebarPosition === 'left' ? '切换到右侧' : '切换到左侧'"
|
:title="sidebarPosition === 'left' ? '切换到右侧' : '切换到左侧'"
|
||||||
class="sidebar-position-toggle-btn"
|
class="header-action-btn"
|
||||||
>
|
>
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<n-icon>
|
<n-icon>
|
||||||
@ -24,6 +24,38 @@
|
|||||||
</template>
|
</template>
|
||||||
</n-button>
|
</n-button>
|
||||||
|
|
||||||
|
<!-- 刷新按钮 -->
|
||||||
|
<n-button
|
||||||
|
type="default"
|
||||||
|
size="medium"
|
||||||
|
@click="handleRefresh"
|
||||||
|
:disabled="loading || isNew"
|
||||||
|
:title="t('Refresh')"
|
||||||
|
class="header-action-btn"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<Icon icon="tabler:refresh" />
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
|
||||||
|
<!-- 删除按钮 -->
|
||||||
|
<n-button
|
||||||
|
type="default"
|
||||||
|
size="medium"
|
||||||
|
@click="handleDelete"
|
||||||
|
:disabled="loading || isNew"
|
||||||
|
:title="t('Delete')"
|
||||||
|
class="header-action-btn"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<n-icon>
|
||||||
|
<Icon icon="tabler:trash" />
|
||||||
|
</n-icon>
|
||||||
|
</template>
|
||||||
|
</n-button>
|
||||||
|
|
||||||
<component
|
<component
|
||||||
v-if="toolbarComponent"
|
v-if="toolbarComponent"
|
||||||
:is="toolbarComponent"
|
:is="toolbarComponent"
|
||||||
@ -38,13 +70,13 @@
|
|||||||
t
|
t
|
||||||
}"
|
}"
|
||||||
/>
|
/>
|
||||||
<n-button type="default" @click="goBack" :disabled="loading">
|
<n-button type="default" size="medium" @click="goBack" :disabled="loading">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<n-icon><Icon icon="tabler:arrow-left" /></n-icon>
|
<n-icon><Icon icon="tabler:arrow-left" /></n-icon>
|
||||||
</template>
|
</template>
|
||||||
{{ t('Back') }}
|
{{ t('Back') }}
|
||||||
</n-button>
|
</n-button>
|
||||||
<n-button type="primary" :disabled="loading" @click="handleSave" v-if="canEdit">
|
<n-button type="primary" size="medium" :disabled="loading" @click="handleSave" v-if="canEdit">
|
||||||
{{ t('Save') }}
|
{{ t('Save') }}
|
||||||
</n-button>
|
</n-button>
|
||||||
</n-space>
|
</n-space>
|
||||||
@ -257,7 +289,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { onMounted, onUnmounted, ref, shallowRef, markRaw, computed, watch } from 'vue'
|
import { onMounted, onUnmounted, ref, shallowRef, markRaw, computed, watch } from 'vue'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { NButton, NSpace, NIcon, useMessage, NLayout, NLayoutSider, NLayoutContent } from 'naive-ui'
|
import { NButton, NSpace, NIcon, useMessage, useDialog, NLayout, NLayoutSider, NLayoutContent } from 'naive-ui'
|
||||||
import FieldRenderer from '@/core/components/form/FieldRenderer.vue'
|
import FieldRenderer from '@/core/components/form/FieldRenderer.vue'
|
||||||
import { Icon } from '@iconify/vue'
|
import { Icon } from '@iconify/vue'
|
||||||
import { resolveSidebarPanel } from '@/core/registry/sidebarOverride'
|
import { resolveSidebarPanel } from '@/core/registry/sidebarOverride'
|
||||||
@ -281,7 +313,7 @@ const TagSection = defineAsyncComponent(async () => {
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { t } from '@/shared/i18n'
|
import { t } from '@/shared/i18n'
|
||||||
import { get_session_api_headers } from '@/shared/api/auth'
|
import { get_session_api_headers } from '@/shared/api/auth'
|
||||||
import { updateRecord, getRecord, getRecordAttachments, deleteAttachment, uploadAttachment } from '@/shared/api/common'
|
import { updateRecord, getRecord, getRecordAttachments, deleteAttachment, uploadAttachment, deleteRecords } from '@/shared/api/common'
|
||||||
import { downloadImageToLocal } from '@/shared/api/common'
|
import { downloadImageToLocal } from '@/shared/api/common'
|
||||||
import { usePageTypeSlug } from '@/shared/utils/slug'
|
import { usePageTypeSlug } from '@/shared/utils/slug'
|
||||||
import { resolvePagetypeDetailOverride, resolvePagetypeToolbarOverride } from '@/core/registry/pagetypeOverride'
|
import { resolvePagetypeDetailOverride, resolvePagetypeToolbarOverride } from '@/core/registry/pagetypeOverride'
|
||||||
@ -289,6 +321,7 @@ import { resolvePagetypeDetailOverride, resolvePagetypeToolbarOverride } from '@
|
|||||||
const route = useRoute()
|
const route = useRoute()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const message = useMessage()
|
const message = useMessage()
|
||||||
|
const dialog = useDialog()
|
||||||
|
|
||||||
// 使用组合式函数处理URL slug
|
// 使用组合式函数处理URL slug
|
||||||
const { pagetypeSlug, entity } = usePageTypeSlug(route)
|
const { pagetypeSlug, entity } = usePageTypeSlug(route)
|
||||||
@ -1051,6 +1084,54 @@ function goBack() {
|
|||||||
router.push({ name: 'PageTypeList', params: { entity: pagetypeSlug.value } })
|
router.push({ name: 'PageTypeList', params: { entity: pagetypeSlug.value } })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 刷新详情数据
|
||||||
|
async function handleRefresh() {
|
||||||
|
if (loading.value || isNew.value) return
|
||||||
|
|
||||||
|
try {
|
||||||
|
await loadDetail()
|
||||||
|
} catch (error) {
|
||||||
|
message.error(t('Failed to refresh'))
|
||||||
|
console.error('Refresh error:', error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除记录
|
||||||
|
async function handleDelete() {
|
||||||
|
if (loading.value || isNew.value) return
|
||||||
|
|
||||||
|
const recordName = record.value.name || id.value
|
||||||
|
if (!recordName) {
|
||||||
|
message.error(t('Cannot delete record without name'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.warning({
|
||||||
|
title: t('Delete Record'),
|
||||||
|
content: t('Are you sure you want to delete this record? This action cannot be undone.'),
|
||||||
|
positiveText: t('Delete'),
|
||||||
|
negativeText: t('Cancel'),
|
||||||
|
onPositiveClick: async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const result = await deleteRecords(entity.value, [recordName])
|
||||||
|
if (result.success) {
|
||||||
|
message.success(result.message || t('Deleted successfully'))
|
||||||
|
// 删除成功后跳转到列表页
|
||||||
|
router.push({ name: 'PageTypeList', params: { entity: pagetypeSlug.value } })
|
||||||
|
} else {
|
||||||
|
message.error(result.message || t('Failed to delete'))
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
message.error(t('Failed to delete'))
|
||||||
|
console.error('Delete error:', error)
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
// 注册快捷键监听
|
// 注册快捷键监听
|
||||||
window.addEventListener('keydown', handleKeydownSave, { capture: true })
|
window.addEventListener('keydown', handleKeydownSave, { capture: true })
|
||||||
@ -1543,11 +1624,11 @@ watch(() => route.params.entity, async (newEntity, oldEntity) => {
|
|||||||
background: #d1d5db !important;
|
background: #d1d5db !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 侧边栏位置切换按钮样式 */
|
/* 头部操作按钮统一样式 */
|
||||||
.sidebar-position-toggle-btn {
|
.header-action-btn {
|
||||||
height: 32px !important;
|
display: inline-flex;
|
||||||
min-width: 32px !important;
|
align-items: center;
|
||||||
padding: 0 8px !important;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 响应式设计 - Naive UI Layout 自动处理 */
|
/* 响应式设计 - Naive UI Layout 自动处理 */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user