chore: mobile font -- task page
This commit is contained in:
@@ -64,13 +64,19 @@ const sizeClasses = {
|
||||
{{ title }}
|
||||
</DialogTitle>
|
||||
<!-- 描述 / 副标题插槽 (占满剩余宽度,截断溢出) -->
|
||||
<div class="flex-1 min-w-0 overflow-hidden">
|
||||
<DialogDescription v-if="description || $slots.description" class="truncate text-xs leading-none">
|
||||
<slot name="description">{{ description }}</slot>
|
||||
</DialogDescription>
|
||||
<DialogDescription v-else class="sr-only">
|
||||
{{ title || '提示对话框' }}
|
||||
</DialogDescription>
|
||||
<div class="flex-1 min-w-0 overflow-hidden flex items-center justify-between gap-2">
|
||||
<div class="truncate">
|
||||
<DialogDescription v-if="description || $slots.description" class="truncate text-xs leading-none">
|
||||
<slot name="description">{{ description }}</slot>
|
||||
</DialogDescription>
|
||||
<DialogDescription v-else class="sr-only">
|
||||
{{ title || '提示对话框' }}
|
||||
</DialogDescription>
|
||||
</div>
|
||||
<!-- 额外扩展插槽 -->
|
||||
<div v-if="$slots.extra" class="flex items-center shrink-0">
|
||||
<slot name="extra" />
|
||||
</div>
|
||||
</div>
|
||||
<!-- 关闭按钮 -->
|
||||
<DialogClose
|
||||
|
||||
@@ -15,6 +15,16 @@ import { useSiteSettings } from '@/composables/useSiteSettings'
|
||||
import { Switch } from '@/components/ui/switch'
|
||||
import { Tabs, TabsList, TabsTrigger } from '@/components/ui/tabs'
|
||||
import { ENV_TYPE } from '@/constants'
|
||||
import { format } from 'date-fns'
|
||||
|
||||
function formatDate(dateStr?: string) {
|
||||
if (!dateStr) return '-'
|
||||
try {
|
||||
return format(new Date(dateStr), 'yyyy-MM-dd HH:mm:ss')
|
||||
} catch {
|
||||
return dateStr
|
||||
}
|
||||
}
|
||||
|
||||
const { pageSize } = useSiteSettings()
|
||||
|
||||
@@ -292,9 +302,10 @@ onBeforeUnmount(() => {
|
||||
<div
|
||||
class="hidden sm:flex items-center gap-4 px-4 py-2 border-b bg-muted/20 text-sm text-muted-foreground font-medium">
|
||||
<span class="w-12 shrink-0 pl-1">序号</span>
|
||||
<span class="w-32 sm:w-48 shrink-0">名称</span>
|
||||
<span class="w-32 sm:w-40 shrink-0">名称</span>
|
||||
<span class="flex-1 min-w-0">值</span>
|
||||
<span class="w-32 sm:w-48 shrink-0 hidden md:block">备注说明</span>
|
||||
<span class="w-32 sm:w-40 shrink-0 hidden md:block">备注说明</span>
|
||||
<span class="w-48 shrink-0 text-left hidden lg:block">创建时间</span>
|
||||
<span class="w-32 shrink-0 text-center">操作</span>
|
||||
</div>
|
||||
|
||||
@@ -336,6 +347,10 @@ onBeforeUnmount(() => {
|
||||
<span class="w-8 shrink-0 font-medium mt-0.5 opacity-70">备注:</span>
|
||||
<span class="flex-1 text-[11px] leading-relaxed">{{ env.remark }}</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="w-8 shrink-0 font-medium opacity-70">创建:</span>
|
||||
<span class="text-[10px] text-muted-foreground">{{ formatDate(env.created_at) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-end gap-1 pt-2 border-t">
|
||||
@@ -364,9 +379,12 @@ onBeforeUnmount(() => {
|
||||
<span class="flex-1 min-w-0 text-muted-foreground truncate text-xs px-1">
|
||||
<TextOverflow :text="showValues[env.id] ? env.value : maskValue(env.value)" title="查看值" />
|
||||
</span>
|
||||
<span class="w-32 sm:w-48 shrink-0 text-muted-foreground truncate text-sm hidden md:block">
|
||||
<span class="w-32 sm:w-40 shrink-0 text-muted-foreground truncate text-sm hidden md:block">
|
||||
<TextOverflow :text="env.remark || '-'" title="备注描述" />
|
||||
</span>
|
||||
<span class="w-48 shrink-0 text-left text-muted-foreground tabular-nums text-[12px] opacity-70 hidden lg:block whitespace-nowrap">
|
||||
{{ formatDate(env.created_at) }}
|
||||
</span>
|
||||
<div class="w-32 shrink-0 flex justify-center gap-1">
|
||||
<Button variant="ghost" size="icon" class="h-7 w-7 rounded-md transition-all"
|
||||
:class="env.enabled ? 'text-green-500 bg-green-500/10 hover:bg-green-500/20' : 'text-muted-foreground bg-muted/50 hover:bg-muted'"
|
||||
|
||||
@@ -25,6 +25,7 @@ import {
|
||||
AlertDialogTitle,
|
||||
} from '@/components/ui/alert-dialog'
|
||||
import { useSiteSettings } from '@/composables/useSiteSettings'
|
||||
import BaihuDialog from '@/components/ui/BaihuDialog.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
filters: {
|
||||
@@ -259,71 +260,72 @@ function onDialogClose(open: boolean) {
|
||||
<Pagination :total="total" :page="currentPage" @update:page="handlePageChange" />
|
||||
</div>
|
||||
|
||||
<Dialog v-model:open="detailDialogProps.open" @update:open="onDialogClose">
|
||||
<DialogContent class="sm:max-w-2xl max-h-[90vh] flex flex-col p-0 overflow-hidden">
|
||||
<DialogHeader class="px-6 py-4 border-b bg-muted/20">
|
||||
<div class="flex items-center justify-between pr-8">
|
||||
<DialogTitle>日志详情</DialogTitle>
|
||||
<Badge variant="outline" :class="[
|
||||
'px-2 py-0.5 text-[10px] font-bold rounded-md border shadow-sm transition-all duration-300',
|
||||
selectedLog ? getStatusBadgeClass(selectedLog.status) : ''
|
||||
]">
|
||||
<div class="flex items-center gap-1 uppercase tracking-tighter">
|
||||
<Check v-if="selectedLog?.status === LOG_STATUS.SUCCESS" class="h-3 w-3" />
|
||||
<X v-else class="h-3 w-3" />
|
||||
<span>{{ selectedLog?.status === LOG_STATUS.SUCCESS ? 'Success' : 'Failed' }}</span>
|
||||
</div>
|
||||
<BaihuDialog v-model:open="detailDialogProps.open" title="日志详情" @update:open="onDialogClose">
|
||||
<template #extra>
|
||||
<Badge variant="outline" :class="[
|
||||
'px-2 py-0.5 text-[10px] font-bold rounded-md border shadow-sm transition-all duration-300',
|
||||
selectedLog ? getStatusBadgeClass(selectedLog.status) : ''
|
||||
]">
|
||||
<div class="flex items-center gap-1 uppercase tracking-tighter">
|
||||
<Check v-if="selectedLog?.status === LOG_STATUS.SUCCESS" class="h-3 w-3" />
|
||||
<X v-else class="h-3 w-3" />
|
||||
<span>{{ selectedLog?.status === LOG_STATUS.SUCCESS ? '发送成功' : '发送失败' }}</span>
|
||||
</div>
|
||||
</Badge>
|
||||
</template>
|
||||
|
||||
<!-- 核心内容区 (依赖 BaihuDialog 自带的 p-6) -->
|
||||
<div class="space-y-8">
|
||||
<!-- 1. 基础信息列表 (扁平化布局) -->
|
||||
<div class="grid grid-cols-1 gap-4 text-sm px-2">
|
||||
<div class="flex justify-between items-center group cursor-default">
|
||||
<span class="text-muted-foreground/60 font-medium">消息标题</span>
|
||||
<span class="font-semibold text-foreground tracking-tight">{{ detailDialogProps.title }}</span>
|
||||
</div>
|
||||
<div v-if="selectedLog?.channel_name" class="flex justify-between items-center group cursor-default">
|
||||
<span class="text-muted-foreground/60 font-medium">推送渠道</span>
|
||||
<Badge variant="secondary" class="font-normal text-[11px] bg-muted/40 hover:bg-muted/60 transition-colors">
|
||||
{{ selectedLog.channel_name }}
|
||||
</Badge>
|
||||
</div>
|
||||
</DialogHeader>
|
||||
|
||||
<div class="flex-1 overflow-y-auto">
|
||||
<!-- 基础信息区 -->
|
||||
<div class="px-6 py-4 border-b space-y-3 bg-card">
|
||||
<div class="flex justify-between items-center text-sm">
|
||||
<span class="text-muted-foreground">标题</span>
|
||||
<span class="font-medium text-foreground">{{ detailDialogProps.title }}</span>
|
||||
</div>
|
||||
<div v-if="selectedLog?.channel_name" class="flex justify-between items-center text-sm">
|
||||
<span class="text-muted-foreground">发送渠道</span>
|
||||
<span class="font-medium text-foreground">{{ selectedLog.channel_name }}</span>
|
||||
</div>
|
||||
<div class="flex justify-between items-center text-sm">
|
||||
<span class="text-muted-foreground">发生时间</span>
|
||||
<span class="font-mono text-xs text-muted-foreground">{{ selectedLog ? formatDate(selectedLog.created_at)
|
||||
: '-' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 内容输出区 -->
|
||||
<div class="flex flex-col min-h-0 bg-muted/5">
|
||||
<div
|
||||
class="px-6 py-2.5 text-xs font-semibold text-muted-foreground border-b bg-muted/10 uppercase tracking-wider">
|
||||
推送内容
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<div v-if="detailDialogProps.content"
|
||||
class="text-sm text-foreground bg-muted/20 p-5 rounded-xl border border-border/50 whitespace-pre-wrap break-all leading-relaxed shadow-sm" v-html="renderedContent">
|
||||
</div>
|
||||
<div v-else class="text-sm text-muted-foreground italic py-2">无推送内容</div>
|
||||
</div>
|
||||
|
||||
<template v-if="detailDialogProps.error">
|
||||
<div
|
||||
class="px-6 py-2.5 text-xs font-semibold uppercase tracking-wider border-y bg-muted/10 text-muted-foreground border-border/60">
|
||||
错误信息
|
||||
</div>
|
||||
<div class="p-6">
|
||||
<div v-if="detailDialogProps.error"
|
||||
class="text-sm p-5 rounded-xl border whitespace-pre-wrap break-all leading-relaxed shadow-sm bg-muted/20 border-border/60 text-foreground">
|
||||
{{ detailDialogProps.error }}
|
||||
</div>
|
||||
<div v-else class="text-sm text-muted-foreground italic py-2">无错误信息</div>
|
||||
</div>
|
||||
</template>
|
||||
<div class="flex justify-between items-center group cursor-default">
|
||||
<span class="text-muted-foreground/60 font-medium">发送时间</span>
|
||||
<span class="font-mono text-[11px] text-muted-foreground/80 tabular-nums">
|
||||
{{ selectedLog ? formatDate(selectedLog.created_at) : '-' }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<!-- 2. 推送内容展示 -->
|
||||
<div class="space-y-3">
|
||||
<div class="flex items-center gap-2 px-2">
|
||||
<div class="w-1 h-3.5 bg-primary/40 rounded-full" />
|
||||
<span class="text-xs font-bold text-muted-foreground uppercase tracking-widest">推送内容</span>
|
||||
</div>
|
||||
<div class="relative group">
|
||||
<!-- 装饰性背景,模拟高级卡片 -->
|
||||
<div class="absolute -inset-0.5 bg-gradient-to-br from-primary/5 via-transparent to-primary/5 rounded-2xl blur opacity-20 group-hover:opacity-40 transition duration-500" />
|
||||
<div v-if="detailDialogProps.content"
|
||||
class="relative bg-background/50 dark:bg-muted/10 p-5 rounded-2xl border border-border/40 whitespace-pre-wrap break-all leading-relaxed shadow-[0_2px_15px_-3px_rgba(0,0,0,0.03)] text-[13px] text-foreground/90 font-medium"
|
||||
v-html="renderedContent">
|
||||
</div>
|
||||
<div v-else class="relative bg-muted/20 p-6 rounded-2xl border border-dashed border-border/60 text-center text-sm text-muted-foreground">
|
||||
此消息无标准推送内容
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 3. 错误信息 (仅当存在时展示) -->
|
||||
<div v-if="detailDialogProps.error" class="space-y-3">
|
||||
<div class="flex items-center gap-2 px-2">
|
||||
<div class="w-1 h-3.5 bg-destructive/40 rounded-full" />
|
||||
<span class="text-xs font-bold text-destructive/80 uppercase tracking-widest">错误报告</span>
|
||||
</div>
|
||||
<div class="bg-destructive/[0.03] p-5 rounded-2xl border border-destructive/10 text-[13px] text-destructive/90 font-mono leading-relaxed break-all">
|
||||
{{ detailDialogProps.error }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BaihuDialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user