feat: 首页素材展示响应式优化
Some checks failed
CI Check / check (push) Has been cancelled

- 使用 aspect-[3/4] 固定卡片比例,解决浏览器调整大小时比例变宽问题
- 添加容器边距(px-4 sm:px-6 lg:px-8)避免卡片贴到浏览器边界
- 使用三层架构样式系统(useThemeStyles 和 cardStyles.base)
- 优化图片 sizes 属性,提升响应式性能
- 统一使用 slate 系列颜色,确保深浅色模式适配
This commit is contained in:
WuYongJie 2025-11-22 15:39:18 +08:00
parent e4dcb6260a
commit 4ca4bbd767
4 changed files with 56 additions and 47 deletions

View File

@ -10,6 +10,7 @@ import Header from '@/components/Header'
import RankingPanel from '@/components/RankingPanel' import RankingPanel from '@/components/RankingPanel'
import AIChatWidget from '@/components/AIChatWidget' import AIChatWidget from '@/components/AIChatWidget'
import ChangePasswordModal from '@/components/ChangePasswordModal' import ChangePasswordModal from '@/components/ChangePasswordModal'
import { useThemeStyles } from '@/lib/ui-styles'
interface Material { interface Material {
id: string id: string
@ -42,6 +43,7 @@ interface Material {
export default function Home() { export default function Home() {
const { data: session, status } = useSession() const { data: session, status } = useSession()
const router = useRouter() const router = useRouter()
const styles = useThemeStyles()
const [materials, setMaterials] = useState<Material[]>([]) const [materials, setMaterials] = useState<Material[]>([])
const [loading, setLoading] = useState(true) const [loading, setLoading] = useState(true)
const [showUploadModal, setShowUploadModal] = useState(false) const [showUploadModal, setShowUploadModal] = useState(false)
@ -983,43 +985,44 @@ export default function Home() {
</div> </div>
) : ( ) : (
<> <>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6"> <div className="px-4 sm:px-6 lg:px-8">
{materials.map((material) => ( <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
<div key={material.id} className="card-apple overflow-hidden dark:bg-gray-800 dark:border-gray-700"> {materials.map((material) => (
{/* Preview Image */} <div key={material.id} className={`${styles.cardStyles.base} overflow-hidden`}>
<div {/* Preview Image */}
className="relative w-full h-[400px] bg-gray-200 dark:bg-gray-700 cursor-pointer group overflow-hidden" <div
onClick={() => { className="relative w-full aspect-[3/4] bg-slate-200 dark:bg-slate-700 cursor-pointer group overflow-hidden rounded-t-2xl"
// PSD、模特和视频类型直接跳转到详情页,其他类型打开预览弹窗 onClick={() => {
if (material.materialType === 'PSD' || material.materialType === '模特' || material.materialType === '视频') { // PSD、模特和视频类型直接跳转到详情页,其他类型打开预览弹窗
router.push(`/share/${material.id}`) if (material.materialType === 'PSD' || material.materialType === '模特' || material.materialType === '视频') {
} else { router.push(`/share/${material.id}`)
setPreviewImage({ url: material.previewUrl, title: material.productModel }) } else {
} setPreviewImage({ url: material.previewUrl, title: material.productModel })
}} }
> }}
<Image >
src={material.previewUrl} <Image
alt={material.sceneName} src={material.previewUrl}
fill alt={material.sceneName}
unoptimized fill
className="object-cover transition-transform group-hover:scale-105" unoptimized
sizes="(max-width: 768px) 100vw, 300px" className="object-cover transition-transform duration-300 group-hover:scale-105"
/> sizes="(max-width: 640px) 100vw, (max-width: 1024px) 50vw, (max-width: 1280px) 33vw, 25vw"
{/* SPU标签 */} />
<div className="absolute top-2 left-2 bg-black/70 text-white px-2 py-1 rounded text-xs font-medium"> {/* SPU标签 */}
{material.productModel} <div className="absolute top-2 left-2 bg-black/70 text-white px-2 py-1 rounded text-xs font-medium">
</div> {material.productModel}
{/* 放大提示 */} </div>
<div className="absolute inset-0 bg-black/0 group-hover:bg-black/30 transition-all flex items-center justify-center"> {/* 放大提示 */}
<svg className="w-12 h-12 text-white opacity-0 group-hover:opacity-100 transition-opacity" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <div className="absolute inset-0 bg-black/0 group-hover:bg-black/30 transition-all flex items-center justify-center">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v6m3-3H7" /> <svg className="w-12 h-12 text-white opacity-0 group-hover:opacity-100 transition-opacity" fill="none" stroke="currentColor" viewBox="0 0 24 24">
</svg> <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v6m3-3H7" />
</div> </svg>
</div> </div>
</div>
{/* Info */} {/* Info */}
<div className="p-4"> <div className="p-4">
{/* 店铺、场景、素材类型和渲染器 */} {/* 店铺、场景、素材类型和渲染器 */}
<div className="flex items-center gap-2 mb-3 flex-wrap"> <div className="flex items-center gap-2 mb-3 flex-wrap">
<span className="inline-flex items-center px-2 py-1 bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 rounded text-xs font-medium"> <span className="inline-flex items-center px-2 py-1 bg-blue-100 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 rounded text-xs font-medium">
@ -1129,10 +1132,11 @@ export default function Home() {
</> </>
)} )}
</button> </button>
</div>
</div> </div>
</div> </div>
</div> ))}
))} </div>
</div> </div>
{/* 分页组件 */} {/* 分页组件 */}

View File

@ -63,17 +63,18 @@
#### 1.3 首页素材展示响应式优化 ⭐⭐⭐⭐ #### 1.3 首页素材展示响应式优化 ⭐⭐⭐⭐
**需求编号**:8 **需求编号**:8
**优先级**:高 **优先级**:高
**状态**:✅ 已完成
**原因**: **原因**:
- 修复已知UI问题(卡片比例、边界间距) - 修复已知UI问题(卡片比例、边界间距)
- 必须遵循统一UI原则 - 必须遵循统一UI原则
- 影响用户体验 - 影响用户体验
**实施要点**: **实施要点**:
- 修复卡片比例固定问题(使用 `aspect-ratio`) - ✅ 修复卡片比例固定问题(使用 `aspect-[3/4]` 替代固定高度)
- 添加合适的边距和间距(使用 `spacingStyles`) - ✅ 添加容器边距(`px-4 sm:px-6 lg:px-8`)避免卡片贴边界
- 使用三层架构样式系统 - ✅ 使用三层架构样式系统(`useThemeStyles()` 和 `cardStyles.base`)
- 响应式断点优化 - ✅ 优化响应式断点和图片 sizes 属性
- 确保深浅色模式适配 - ✅ 确保深浅色模式适配(使用 `slate` 系列颜色)
**依赖关系**:无 **依赖关系**:无
**影响范围**:首页素材展示 **影响范围**:首页素材展示
@ -449,7 +450,7 @@
### 第一阶段:基础组件与UI统一(2-3周) ### 第一阶段:基础组件与UI统一(2-3周)
1. ✅ 创建统一弹窗组件(1.1)- 已完成基础组件,待替换原生弹窗 1. ✅ 创建统一弹窗组件(1.1)- 已完成基础组件,待替换原生弹窗
2. ⏳ 素材预览面板统一(1.2) 2. ⏳ 素材预览面板统一(1.2)
3. ⏳ 首页素材展示响应式优化(1.3) 3. ✅ 首页素材展示响应式优化(1.3)- 已完成
4. ⏳ 首页UI统一到三层架构(1.4) 4. ⏳ 首页UI统一到三层架构(1.4)
5. ⏳ 统一UI三层架构通用组件库(1.5) 5. ⏳ 统一UI三层架构通用组件库(1.5)
6. ⏳ 深浅色主题适配优化(1.6) 6. ⏳ 深浅色主题适配优化(1.6)

View File

@ -299,9 +299,12 @@ export default function MyComponent() {
2. ⏳ 素材预览面板统一 2. ⏳ 素材预览面板统一
- 使用统一弹窗组件 - 使用统一弹窗组件
- 统一退出逻辑 - 统一退出逻辑
3. ⏳ 首页素材展示响应式优化 3. ✅ 首页素材展示响应式优化
- 修复卡片比例问题 - ✅ 修复卡片比例固定问题(使用 `aspect-[3/4]` 替代固定高度 `h-[400px]`)
- 优化边界间距 - ✅ 添加容器边距(`px-4 sm:px-6 lg:px-8`)避免卡片贴到浏览器边界
- ✅ 使用三层架构样式系统(`useThemeStyles()` 和 `cardStyles.base`)
- ✅ 优化图片 sizes 属性,提升响应式性能
- ✅ 统一使用 `slate` 系列颜色,确保深浅色模式适配
**优先级 2:数据一致性与核心功能** **优先级 2:数据一致性与核心功能**
4. ⏳ 用户信息修改后同步素材信息 4. ⏳ 用户信息修改后同步素材信息

View File

@ -7,6 +7,7 @@
6.用户管理增加用户头像的设置,用户可以自己设置自己的头像。对于钉钉登陆的用户,可以直接用钉钉头像,抓不到钉钉头像的话,就不抓取。对于没有头像的用户,策略和LOGO的策略一样 6.用户管理增加用户头像的设置,用户可以自己设置自己的头像。对于钉钉登陆的用户,可以直接用钉钉头像,抓不到钉钉头像的话,就不抓取。对于没有头像的用户,策略和LOGO的策略一样
7.首页上的排行榜关掉后的那个缩略按钮,也设置为可以拖动,且出现的位置是根据排行榜悬浮窗关闭前的位置 7.首页上的排行榜关掉后的那个缩略按钮,也设置为可以拖动,且出现的位置是根据排行榜悬浮窗关闭前的位置
8.首页的素材展示要改一下,现在是有个问题,就是当我拖动浏览器侧边调整浏览器大小的时候,调整浏览器界面大小,小到一个阈值时,展示素材的卡片会从4个变成3个,这个时候素材卡片的比例就会变宽,这是不对的。要保持素材卡片比例是固定的。还有就是当浏览器变窄之后素材卡片会贴到浏览器的边界,很不美观,根据统一UI原则视觉改一下 8.首页的素材展示要改一下,现在是有个问题,就是当我拖动浏览器侧边调整浏览器大小的时候,调整浏览器界面大小,小到一个阈值时,展示素材的卡片会从4个变成3个,这个时候素材卡片的比例就会变宽,这是不对的。要保持素材卡片比例是固定的。还有就是当浏览器变窄之后素材卡片会贴到浏览器的边界,很不美观,根据统一UI原则视觉改一下
✅ 已完成:使用 aspect-[3/4] 固定卡片比例,添加容器边距,使用三层架构样式系统
9.首页的素材展示可以设置素材展示卡片的大小,可以设置一个横向的滑块。素材卡片的展示形式可以设置为瀑布流,为低性能nas机器考虑,可以动态加载卡片数量,具体加载多少可以根据你的经验判断。或者你有更好的方式也可以提出建议 9.首页的素材展示可以设置素材展示卡片的大小,可以设置一个横向的滑块。素材卡片的展示形式可以设置为瀑布流,为低性能nas机器考虑,可以动态加载卡片数量,具体加载多少可以根据你的经验判断。或者你有更好的方式也可以提出建议
10.首页素材卡片中预览图下方的素材资料有点多,占用空间太大。可以优化一下,其中作者中的“作者:”可以不显示,直接显示作者的名字。可以在前面显示头像。文件名和文件大小也可以不显示。上传时间可以叠在预览图的右上角,默认隐藏,鼠标移动到卡片上亮起,要确保亮起状态的上传时间可以看清 10.首页素材卡片中预览图下方的素材资料有点多,占用空间太大。可以优化一下,其中作者中的“作者:”可以不显示,直接显示作者的名字。可以在前面显示头像。文件名和文件大小也可以不显示。上传时间可以叠在预览图的右上角,默认隐藏,鼠标移动到卡片上亮起,要确保亮起状态的上传时间可以看清
11.素材卡片可以在左上角的素材名称前面加几个标签,如点赞榜,精品榜,下载榜,收藏榜等,你可以自由发挥,样式可以参考最高权限的显示ui,更主要的是视觉要好看,偏向苹果UI设计风格,但是要注意大方向一定是统一视觉的方案。 11.素材卡片可以在左上角的素材名称前面加几个标签,如点赞榜,精品榜,下载榜,收藏榜等,你可以自由发挥,样式可以参考最高权限的显示ui,更主要的是视觉要好看,偏向苹果UI设计风格,但是要注意大方向一定是统一视觉的方案。