chore: opt middle screen style

This commit is contained in:
duorameng
2026-04-07 18:13:01 +08:00
parent 73c6e559d5
commit 2218d5f07e
5 changed files with 333 additions and 283 deletions
+54 -32
View File
@@ -165,16 +165,16 @@ function onDialogClose(open: boolean) {
<template>
<div class="space-y-6">
<div class="flex items-center justify-between gap-2">
<div class="flex items-center gap-2">
<div class="relative flex-1 sm:flex-none">
<Search class="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground" />
<Input v-model="filters.keyword" placeholder="搜索标题或内容..." class="h-9 pl-9 w-full sm:w-56 text-sm"
<div class="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4 w-full">
<div class="flex items-center gap-2 w-full sm:w-auto sm:ml-auto">
<div class="relative w-full sm:w-60 group">
<Search class="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-muted-foreground group-focus-within:text-primary transition-colors" />
<Input v-model="filters.keyword" placeholder="搜索标题或内容..." class="h-9 pl-9 w-full text-sm bg-muted/20 border-muted-foreground/10 focus:bg-background"
@input="handleSearch" />
</div>
<div class="relative flex-1 sm:flex-none">
<div class="relative flex-1 sm:flex-none sm:w-28">
<Select :model-value="filters.status" @update:model-value="handleStatusChange">
<SelectTrigger class="h-9 w-full sm:w-28 text-sm">
<SelectTrigger class="h-9 w-full text-sm bg-muted/20 border-muted-foreground/10">
<SelectValue placeholder="状态" />
</SelectTrigger>
<SelectContent>
@@ -184,16 +184,16 @@ function onDialogClose(open: boolean) {
</SelectContent>
</Select>
</div>
<Button variant="outline" size="icon" class="h-9 w-9 shrink-0" @click="fetchLogs" :disabled="loading"
<Button variant="outline" size="icon" class="h-9 w-9 shrink-0 sm:flex" @click="fetchLogs" :disabled="loading"
title="刷新">
<RefreshCw class="h-4 w-4" :class="{ 'animate-spin': loading }" />
</Button>
</div>
<AlertDialog :open="showClearConfirm" @update:open="showClearConfirm = $event">
<Button variant="outline"
class="h-9 px-4 shrink-0 text-sm text-destructive hover:bg-destructive/10 hover:text-destructive border-destructive/20"
class="h-9 px-4 shrink-0 text-sm text-destructive hover:bg-destructive/10 hover:text-destructive border-destructive/20 w-full sm:w-auto"
@click="showClearConfirm = true">
<Trash2 class="h-4 w-4 sm:mr-2" /> <span class="hidden sm:inline" style="padding-left: 2px;">清空记录</span>
<Trash2 class="h-4 w-4 mr-2" /> <span>清空记录</span>
</Button>
<AlertDialogContent>
<AlertDialogHeader>
@@ -213,24 +213,29 @@ function onDialogClose(open: boolean) {
</div>
<div class="rounded-lg border bg-card overflow-hidden">
<!-- 大屏表头 -->
<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">
<!-- ========== 1. 大屏表头 (Large >= 1024px) ========== -->
<div class="hidden lg:flex items-center gap-4 px-4 py-2 border-b bg-muted/20 text-sm text-muted-foreground font-medium">
<span class="w-16 shrink-0 pl-1">序号</span>
<span class="w-56 shrink-0">标题及渠道</span>
<span class="flex-1 min-w-0">内容详情</span>
<span class="w-16 shrink-0 text-center">状态</span>
<span class="w-56 shrink-0 px-2 pl-6">标题及渠道</span>
<span class="flex-1 min-w-0 px-2 font-not-medium">内容详情</span>
<span class="w-40 shrink-0 text-right">发送时间</span>
</div>
<!-- 列表 -->
<div class="divide-y">
<!-- ========== 2. 中屏表头 (Medium 640px - 1024px) ========== -->
<div class="hidden sm:flex lg:hidden items-center gap-4 px-4 py-2 border-b bg-muted/20 text-sm text-muted-foreground font-medium">
<span class="w-48 shrink-0">项目</span>
<span class="flex-1 min-w-0">内容摘要</span>
<span class="w-40 shrink-0 text-right">时间信息</span>
</div>
<!-- 列表内容 -->
<div class="divide-y text-sm">
<div v-if="logs.length === 0 && !loading" class="text-sm text-muted-foreground text-center py-8">
暂无推送记录
</div>
<!-- 小屏卡片布局 -->
<div v-for="(log, index) in logs" :key="`mobile-${log.id}`"
<!-- ========== 1. 小屏布局 (Small < 640px) - 用户调好 ========== -->
<div v-for="(log, index) in logs" :key="`small-${log.id}`"
class="sm:hidden p-3 hover:bg-muted/50 transition-colors cursor-pointer group" @click="showDetail(log)"
:class="[selectedLogId === log.id && 'bg-accent/50']">
<div class="flex items-start justify-between mb-3 border-b border-border/40 pb-2">
@@ -261,23 +266,40 @@ function onDialogClose(open: boolean) {
</div>
</div>
<!-- 大屏行布局 -->
<div v-for="(log, index) in logs" :key="`desktop-${log.id}`"
class="hidden sm:flex items-center gap-4 px-4 py-2 hover:bg-muted/50 transition-colors cursor-pointer group"
<!-- ========== 2. 中屏布局 (Medium 640px - 1024px) - 新抽取优化 ========== -->
<div v-for="log in logs" :key="`medium-${log.id}`"
class="hidden sm:flex lg:hidden items-center gap-4 px-4 py-2.5 hover:bg-muted/50 transition-colors cursor-pointer group"
:class="[selectedLogId === log.id && 'bg-accent/50']" @click="showDetail(log)">
<span class="w-16 shrink-0 text-muted-foreground text-sm pl-1">#{{ getLogIndex(index) }}</span>
<span class="w-56 shrink-0 font-medium text-sm truncate" :title="log.title">
<span v-if="log.channel_name" class="mr-1 text-muted-foreground">[{{ log.channel_name }}]</span>{{ log.title
}}
<div class="w-48 shrink-0 flex items-center gap-3 min-w-0">
<span :class="['h-2 w-2 rounded-full shrink-0', log.status === LOG_STATUS.SUCCESS ? 'bg-green-500 shadow-[0_0_8px_rgba(34,197,94,0.3)]' : 'bg-red-500 shadow-[0_0_8px_rgba(239,68,68,0.3)]']"></span>
<div class="flex flex-col gap-0.5 min-w-0">
<span class="font-medium truncate text-sm" :title="log.title">{{ log.title }}</span>
<span v-if="log.channel_name" class="text-[10px] text-muted-foreground opacity-60">[{{ log.channel_name }}]</span>
</div>
</div>
<span class="flex-1 min-w-0 text-xs text-muted-foreground line-clamp-1" :title="log.content">
{{ log.content || '-' }}
</span>
<span class="w-40 shrink-0 text-right text-xs text-muted-foreground tabular-nums opacity-60">
{{ formatDate(log.created_at) }}
</span>
</div>
<!-- ========== 3. 大屏布局 (Large >= 1024px) - 用户调好 ========== -->
<div v-for="(log, index) in logs" :key="`large-${log.id}`"
class="hidden lg:flex items-center gap-4 px-4 py-2 hover:bg-muted/50 transition-colors cursor-pointer group"
:class="[selectedLogId === log.id && 'bg-accent/50']" @click="showDetail(log)">
<span class="w-16 shrink-0 text-muted-foreground text-sm tabular-nums pl-1">#{{ getLogIndex(index) }}</span>
<div class="w-56 shrink-0 flex items-center gap-3 min-w-0 font-medium text-sm">
<span :class="['h-2 w-2 rounded-full shrink-0', log.status === LOG_STATUS.SUCCESS ? 'bg-green-500 shadow-[0_0_8px_rgba(34,197,94,0.3)]' : 'bg-red-500 shadow-[0_0_8px_rgba(239,68,68,0.3)]']"></span>
<span class="truncate" :title="log.title">
<span v-if="log.channel_name" class="mr-1 text-muted-foreground opacity-60">[{{ log.channel_name }}]</span>{{ log.title }}
</span>
</div>
<span class="flex-1 min-w-0 text-sm text-muted-foreground truncate" :title="log.content">
{{ log.content || '-' }}
</span>
<span class="w-16 shrink-0 flex justify-center">
<span
:class="['h-2 w-2 rounded-full', log.status === LOG_STATUS.SUCCESS ? 'bg-green-500' : 'bg-red-500']"></span>
</span>
<span class="w-40 shrink-0 text-right text-xs text-muted-foreground">
<span class="w-40 shrink-0 text-right text-xs text-muted-foreground tabular-nums opacity-60">
{{ formatDate(log.created_at) }}
</span>
</div>