gongxiangp2/PROJECT_INTRODUCTION.md
chenpei f7d9ebe1ab docs: Update PROJECT_INTRODUCTION.md with PSD auto-preview and dimension updates
- Add v2.6.0 changelog for PSD auto-preview and 300x500 dimensions
- Update upload flow to include PSD auto-preview generation
- Update card display specs to 300x500 vertical format
- Add ag-psd to technology stack
- Update image processing documentation
- Update user guide for PSD file uploads
2025-10-26 16:32:28 +08:00

56 KiB
Raw Blame History

由壹点3D素材 - 项目完整介绍

Logo

现代化的3D素材共享管理平台

Next.js React TypeScript PostgreSQL License

在线演示 | 快速开始 | 功能特性 | 技术文档


📖 目录


🎯 项目简介

项目概述

由壹点3D素材是一个现代化、企业级的3D素材共享管理平台,专为设计团队和创意工作者打造。平台提供了完整的素材上传、管理、分享和下载解决方案,采用苹果官方设计规范,提供优雅流畅的用户体验。

核心价值

  • 🎨 高效管理 - 集中管理团队的3D素材资源,提升工作效率
  • 🚀 快速分享 - 一键分享链接,团队协作更便捷
  • 📊 智能统计 - 实时追踪下载量和点赞数,洞察热门素材
  • 🔒 安全可靠 - 企业级安全防护,数据加密传输存储
  • 🎯 精准筛选 - 多维度筛选系统,快速找到所需素材
  • 💡 智能体验 - 拖拽上传、自动网络切换等智能功能

适用场景

  • 设计工作室 - 集中管理和分享3D设计素材
  • 电商团队 - 管理产品效果图和场景素材
  • 教育机构 - 教学素材的收集和分享
  • 创意团队 - 项目素材的协作和管理
  • 个人创作者 - 个人作品集的展示和管理

✨ 核心功能

1. 用户系统

完善的认证机制

  • ✅ 用户注册 - 邮箱+用户名+密码注册
  • ✅ 安全登录 - NextAuth.js会话管理,JWT令牌
  • ✅ 角色管理 - USER和ADMIN双角色体系
  • ✅ 账户激活 - 管理员审核机制,确保用户质量
  • ✅ 权限控制 - 细粒度的下载权限管理

用户特性

用户属性:
├── 基础信息(邮箱、用户名、部门)
├── 角色权限(普通用户/管理员)
├── 激活状态(待激活/已激活)
├── 下载权限(允许/禁止)
└── 使用统计(上传数、下载数)

2. 素材上传与管理

智能上传功能

  • 🎯 拖拽上传 - 全窗口拖拽,自动识别文件类型
  • 📸 预览图上传 - 支持JPG、PNG、WebP等格式
  • 🤖 PSD自动预览 - PSD文件无需手动上传预览图
    • 自动从PSD文件提取预览图
    • 智能裁剪长图(保留顶部1200px)
    • 自动压缩优化到300KB以内
    • 转换为WebP格式节省空间
  • 📦 文件上传 - 支持压缩包和源文件
    • 压缩包格式:ZIP、RAR、7Z
    • 源文件格式:MAX、PSD、AI、CAD、DWG、C4D
  • 🤖 智能识别 - 根据文件扩展名自动识别素材类型
    • .max → 自动设置为3DMAX
    • .psd → 自动设置为PSD并自动生成预览图
    • .ai → 自动设置为AI
    • .cad/.dwg → 自动设置为CAD
    • .c4d → 自动设置为C4D
    • 压缩包 → 需手动选择类型
  • 📊 实时进度 - 上传进度和网络速度实时显示
  • 🚀 大文件支持 - 最高支持10GB文件上传
  • 🔄 智能压缩 - 预览图自动优化(最大600x1000px)
  • 🏷️ 多类型支持 - 支持3DMAX、PSD、AI、CAD、C4D等多种素材类型
  • 🎨 条件显示 - 根据素材类型智能显示相关选项

丰富的元数据

素材信息:
├── SPU(商品型号)
├── 使用店铺(一级分类)
├── 场景类别(二级分类)
├── 素材类型(3DMAX/PSD/AI/CAD/C4D/其他)
├── 渲染器(CR/VR/其它,仅3DMAX类型)
├── 作者花名(自动获取)
├── 文件信息(大小、格式)
├── 统计数据(下载次数、点赞数)
└── 时间戳(上传时间、更新时间)

上传流程

1. 输入商品型号 → SPU标识
2. 选择使用店铺 → 支持新建分类
3. 选择场景类别 → 支持新建场景
4. 选择/拖拽文件 → 支持压缩包或源文件
   ↓
   智能识别文件格式:
   - .max → 自动识别为3DMAX,显示渲染器选项
   - .psd → 自动识别为PSD,预览图可选(自动生成)
   - .ai → 自动识别为AI
   - .cad/.dwg → 自动识别为CAD
   - .c4d → 自动识别为C4D
   - .zip/.rar/.7z → 需手动选择素材类型
   ↓
5. 上传预览图(根据文件类型):
   - PSD文件 → 可选(系统自动从PSD提取)
   - 其他文件 → 必选(手动上传预览图)
   ↓
6. 选择素材类型 → 已自动识别或手动选择
7. 选择渲染器 → CR/VR/其它(仅3DMAX类型显示)
8. 开始上传 → 实时显示进度和速度
   ↓
   如果是PSD文件且未上传预览图:
   - 保存PSD临时文件
   - 使用ag-psd解析PSD
   - 提取合成图像
   - 裁剪长图(>1200px保留顶部)
   - 压缩优化(600x1000px, 300KB)
   - 上传到MinIO S3
   - 清理临时文件
   ↓
9. 上传完成 → 自动返回首页展示

3. 素材浏览与筛选

多维度筛选系统

搜索功能

  • 🔍 全文搜索:SPU、店铺、场景、作者
  • 🎯 实时过滤:输入即刻响应
  • ❌ 快速清除:一键清空搜索条件

分类筛选

  • 🏪 使用店铺筛选 - 一级分类按钮式筛选
  • 🎬 场景类别筛选 - 二级分类快速切换
  • 📅 月份筛选 - 按上传月份查看素材
  • 🔢 统计显示 - 每个分类显示素材数量

组合筛选

  • 支持多条件组合使用
  • 当前筛选条件标签显示
  • 单独移除或一键清除
  • 筛选结果实时更新

卡片式展示

┌──────────────────────────┐
│   [预览图 300x500px]     │
│   SPU标签 (左上角)       │
│   放大提示 (hover)       │
├──────────────────────────┤
│ [店铺] [场景] [类型]     │
│ [渲染器] (仅3DMAX)       │
│ 作者:XXX               │
│ 文件:xxx.zip           │
│ 大小:450.23 MB         │
│ 时间:2025-10-26        │
├──────────────────────────┤
│ 📥 125次  ❤️ 45次      │
├──────────────────────────┤
│ [❤️] [🔗] [📥 下载]    │
└──────────────────────────┘

显示特性

  • 📐 3:5竖版比例 - 更适合展示纵向素材
  • 🖼️ 高质量预览 - 自动优化至600x1000像素
  • 📏 等比缩放 - 保持原图比例,无变形
  • 🎨 响应式布局 - 网格自动适配屏幕尺寸

4. 互动功能

点赞系统

  • ❤️ 一键点赞 - 表达对优质素材的认可
  • 🔴 状态标识 - 已点赞红色,未点赞灰色
  • 📊 实时统计 - 点赞数实时更新
  • 🚫 防重复 - 每个用户每个素材只能点赞一次
  • 💡 取消点赞 - 再次点击即可取消

分享功能

  • 🔗 一键分享 - 生成专属分享链接
  • 📋 自动复制 - 链接自动复制到剪贴板
  • ✅ 成功提示 - 复制成功通知
  • 👁️ 公开访问 - 无需登录即可查看分享内容
  • 📱 二维码 - 支持生成二维码分享(规划中)

下载功能

  • 📥 一键下载 - 点击即下载原始压缩包
  • 📊 下载进度 - 实时显示下载进度条
  • 📈 统计追踪 - 自动记录下载次数
  • 🔒 权限控制 - 支持禁止下载功能
  • 💾 文件完整 - 保持原始文件名和格式

5. 排行榜系统

实时排行

┌─────────────────────────────┐
│   🏆 素材排行榜             │
├─────────────────────────────┤
│ 🥇 下载榜                   │
│   1. SPU001  📥 256次      │
│   2. SPU002  📥 198次      │
│   3. SPU003  📥 167次      │
├─────────────────────────────┤
│ 🥈 点赞榜                   │
│   1. SPU004  ❤️ 89次       │
│   2. SPU005  ❤️ 76次       │
│   3. SPU006  ❤️ 65次       │
└─────────────────────────────┘

排行特性

  • 📊 实时更新 - 根据最新数据动态排名
  • 🏅 双榜并列 - 下载榜和点赞榜
  • 🔝 TOP 5展示 - 展示前5名热门素材
  • 🎯 快速跳转 - 点击直接查看素材详情

6. 管理员后台

用户管理

  • 👥 用户列表 - 查看所有注册用户
  • 👤 用户详情 - 邮箱、用户名、角色、状态
  • 🔓 激活控制 - 一键激活/禁用用户
  • 🚫 下载权限 - 控制用户下载权限
  • 👑 角色设置 - 普通用户/管理员切换
  • 🗑️ 删除用户 - 级联删除用户及其素材

素材管理

  • 📋 素材列表 - 查看所有上传的素材
  • ✏️ 编辑素材 - 修改SPU、分类、场景等信息
  • 🖼️ 更换预览图 - 重新上传预览图
  • 🗑️ 删除素材 - 彻底删除素材文件
  • 📊 统计数据 - 查看下载次数和点赞数
  • 👤 上传者信息 - 显示素材上传者

分类管理

  • 🏪 店铺管理 - 添加/删除使用店铺
  • 🎬 场景管理 - 添加/删除场景类别
  • 📊 使用统计 - 查看每个分类的素材数量
  • 🔄 批量操作 - 支持批量修改分类

部门管理

  • 🏢 部门列表 - 查看所有部门
  • ➕ 新增部门 - 添加新的部门
  • 🗑️ 删除部门 - 删除不需要的部门
  • 👥 用户关联 - 用户注册时选择所属部门
  • 📊 部门统计 - 查看各部门用户数量

系统设置(外观设置)

  • 🎨 导航栏颜色 - 自定义顶部导航栏背景色
    • 颜色选择器实时预览
    • 10种预设颜色快速选择
    • 支持十六进制色值输入
    • 一键恢复默认颜色
  • 🖼️ LOGO管理 - 自定义网站LOGO
    • 支持上传图片到MinIO S3
    • 实时预览上传效果
    • 建议尺寸200x200px
    • 支持PNG、JPG、SVG格式
    • 文件大小限制5MB
  • 🏷️ 网站名称 - 自定义站点名称
    • 应用于顶部导航栏
    • 应用于登录页面
    • 实时保存更新
  • 💾 一键保存 - 所有设置统一保存并应用
  • 🔄 自动刷新 - 保存后自动刷新页面应用新设置

7. 智能特性

智能网络切换

用户场景:
├── 办公室访问公网地址
│   └→ 自动检测内网可达
│       └→ 自动切换到内网模式 🏠
│           └→ 享受高速访问
│
├── 外网访问
│   └→ 检测内网不可达
│       └→ 使用公网模式 🌍
│           └→ 稳定访问
│
└── 直接访问内网
    └→ 无需检测
        └→ 直接使用内网 🏠

特点:

  • ⚡ 自动检测(2秒超时)
  • 🎯 智能切换(优先内网)
  • 👻 无感知(后台运行)
  • 📊 状态提示(实时显示)

文件格式自动识别

  • 🤖 智能识别 - 根据文件扩展名自动识别素材类型
    • 上传.max文件 → 自动设置为3DMAX类型
    • 上传.psd文件 → 自动设置为PSD类型
    • 上传.ai文件 → 自动设置为AI类型
    • 上传.cad/.dwg文件 → 自动设置为CAD类型
    • 上传.c4d文件 → 自动设置为C4D类型
  • 🎯 准确高效 - 减少手动选择步骤,提升上传效率
  • 🔄 灵活调整 - 自动识别后仍可手动修改类型
  • 📦 压缩包支持 - 压缩包需手动选择类型(内容未知)
  • 🎨 联动显示 - 识别为3DMAX时自动显示渲染器选项

拖拽上传

  • 🎯 全窗口拖拽区域 - 整个上传窗口都支持拖拽
  • 🎨 视觉反馈 - 拖入时显示蓝色覆盖层提示
  • 🧠 智能识别 - 自动区分图片和文件
  • 📁 多格式支持 - 支持压缩包和源文件拖拽
  • ✨ 传统兼容 - 保留点击选择文件方式

图片预览

  • 🔍 点击放大 - 点击卡片预览图查看大图
  • 🖼️ 全屏展示 - 黑色背景全屏查看
  • ❌ 轻松关闭 - 点击背景或关闭按钮
  • 📱 响应式 - 适配各种屏幕尺寸

8. 分页系统

智能分页

功能特性:
├── 每页20条数据
├── 页码智能显示(最多7页)
├── 上一页/下一页按钮
├── 当前页高亮显示
├── 总页数/总条数统计
├── 切换自动滚动到顶部
└── 保持筛选条件

用户体验

  • 快速跳转到指定页
  • 禁用状态智能处理
  • 平滑滚动动画
  • 加载状态提示

🏗️ 技术架构

技术栈总览

前端框架
├── Next.js 14.2          # React全栈框架,App Router
├── React 18.3            # UI组件库
├── TypeScript 5.5        # 类型安全
└── TailwindCSS 3.4       # 原子化CSS框架

后端技术
├── Next.js API Routes    # RESTful API
├── Prisma 5.19          # 现代化ORM
├── PostgreSQL           # 关系型数据库
└── NextAuth.js 4.24     # 认证系统

图像处理
├── Sharp 0.34.4         # 高性能图像处理
├── ag-psd 28.4.1        # PSD文件解析
└── WebP压缩             # 图片格式优化

存储方案
├── MinIO S3             # 对象存储(预览图)
└── 本地文件系统          # 压缩包存储

开发工具
├── ESLint               # 代码检查
├── Prisma Studio        # 数据库管理
└── Git                  # 版本控制

系统架构图

┌─────────────────────────────────────────┐
│           客户端(浏览器)                │
│  Next.js SSR + React + TailwindCSS     │
└─────────────────┬───────────────────────┘
                  │
                  │ HTTPS
                  │
┌─────────────────▼───────────────────────┐
│         Next.js Server                  │
│  ┌────────────┐  ┌──────────────┐      │
│  │ API Routes │  │ Auth Middleware│     │
│  └──────┬─────┘  └───────┬──────┘      │
│         │                 │              │
│    ┌────▼────┐      ┌────▼────┐        │
│    │ Prisma  │      │NextAuth │        │
│    │  ORM    │      │   JWT   │        │
│    └────┬────┘      └─────────┘        │
└─────────┼──────────────────────────────┘
          │
     ┌────┴─────┬──────────────┐
     │          │              │
┌────▼───┐ ┌───▼─────┐ ┌─────▼─────┐
│ PostgreSQL│ │ MinIO S3│ │ Local FS │
│  Database │ │ Storage │ │  uploads  │
└──────────┘ └─────────┘ └───────────┘

数据库设计

核心表结构

User(用户表)

用户表
├── id (UUID, PK)              # 唯一标识
├── email (String, UNIQUE)     # 邮箱
├── username (String, UNIQUE)  # 用户名
├── password (String)          # 加密密码
├── department (String)        # 所属部门
├── role (Enum)                # USER/ADMIN
├── isActive (Boolean)         # 激活状态
├── canDownload (Boolean)      # 下载权限
├── createdAt (DateTime)       # 创建时间
└── updatedAt (DateTime)       # 更新时间

Material(素材表)

素材表
├── id (UUID, PK)              # 唯一标识
├── previewUrl (String)        # S3预览图URL
├── productModel (String)      # SPU商品型号
├── categoryName (String)      # 使用店铺(一级分类)
├── sceneName (String)         # 场景类别(二级分类)
├── materialType (String)      # 素材类型(3DMAX/PSD/AI/CAD/C4D/其他)
├── renderer (String)          # 渲染器(仅3DMAX使用)
├── authorName (String)        # 作者花名
├── zipFileName (String)       # 压缩包文件名
├── zipFilePath (String)       # 本地路径
├── zipFileSize (BigInt)       # 文件大小(字节)
├── downloadCount (Int)        # 下载次数
├── likeCount (Int)            # 点赞次数
├── userId (UUID, FK)          # 上传用户ID
├── createdAt (DateTime)       # 创建时间
└── updatedAt (DateTime)       # 更新时间

索引:
├── userId (外键索引)
├── categoryName (分类查询)
├── sceneName (场景查询)
├── materialType (类型筛选)
├── downloadCount (排行榜)
├── likeCount (排行榜)
└── createdAt (时间排序)

MaterialLike(点赞表)

点赞关系表
├── id (UUID, PK)              # 唯一标识
├── materialId (UUID, FK)      # 素材ID
├── userId (UUID, FK)          # 用户ID
└── createdAt (DateTime)       # 点赞时间

唯一约束:(materialId, userId)  # 防止重复点赞

Category(分类表)

一级分类表(使用店铺)
├── id (UUID, PK)              # 唯一标识
├── name (String, UNIQUE)      # 店铺名称
└── createdAt (DateTime)       # 创建时间

Scene(场景表)

二级分类表(场景类别)
├── id (UUID, PK)              # 唯一标识
├── name (String, UNIQUE)      # 场景名称
└── createdAt (DateTime)       # 创建时间

SystemSettings(系统设置表)

系统设置表
├── id (UUID, PK)              # 唯一标识
├── headerBgColor (String)     # 导航栏背景色
├── logoUrl (String)           # LOGO URL (S3)
├── siteName (String)          # 网站名称
├── createdAt (DateTime)       # 创建时间
└── updatedAt (DateTime)       # 更新时间

默认值:
├── headerBgColor: #1f2937 (深灰色)
├── logoUrl: 默认LOGO地址
└── siteName: 由壹点3D素材

Department(部门表)

部门表
├── id (UUID, PK)              # 唯一标识
├── name (String, UNIQUE)      # 部门名称
└── createdAt (DateTime)       # 创建时间

存储策略

混合存储方案

预览图 → MinIO S3云存储

优势:
├── ✅ 不占用服务器空间
├── ✅ 支持CDN加速
├── ✅ 高可用性(99.9%)
├── ✅ 自动备份
└── ✅ 按需扩容

配置:
├── Endpoint: https://s3.1080p.hk
├── Bucket: jsxiangche
├── Path: 由壹点AI/
└── 访问: 公开读取

压缩包 → 本地文件系统

优势:
├── ✅ 下载速度快
├── ✅ 无流量费用
├── ✅ 易于管理
└── ✅ 成本低

路径:
├── 开发环境: ./uploads/
└── 生产环境: /mnt/tank/uploads/

API设计

RESTful API端点

认证相关

POST   /api/auth/register          # 用户注册
POST   /api/auth/signin            # 用户登录
POST   /api/auth/signout           # 用户登出
GET    /api/auth/session           # 获取会话

素材相关

GET    /api/materials              # 获取素材列表
  Query参数:
  - search: 搜索关键词
  - category: 店铺筛选
  - scene: 场景筛选
  - month: 月份筛选
  - page: 页码
  - pageSize: 每页数量

POST   /api/materials/upload       # 上传素材
  Body: FormData
  - previewImage: 预览图文件
  - zipFile: 压缩包文件
  - productModel: SPU
  - categoryName: 店铺
  - sceneName: 场景
  - materialType: 素材类型
  - renderer: 渲染器

GET    /api/materials/download     # 下载素材
  Query: id (素材ID)

POST   /api/materials/like         # 点赞/取消点赞
  Body: { materialId: string }

POST   /api/materials/share        # 生成分享链接
  Body: { materialId: string }

GET    /api/materials/stats        # 统计信息
  返回: 月份统计、总数

PUT    /api/materials/update       # 更新素材信息
  Body: 素材数据

DELETE /api/materials              # 删除素材
  Query: id (素材ID)

分类相关

GET    /api/categories             # 获取店铺列表
POST   /api/categories             # 创建店铺
  Body: { name: string }

GET    /api/scenes                 # 获取场景列表
POST   /api/scenes                 # 创建场景
  Body: { name: string }

排行榜

GET    /api/rankings               # 获取排行榜
  返回: 
  - downloadTop: 下载榜TOP 5
  - likeTop: 点赞榜TOP 5

管理员相关

GET    /api/admin/users            # 获取用户列表
POST   /api/admin/users/set-role   # 设置用户角色
  Body: { userId, role }

POST   /api/admin/users/toggle-active    # 切换激活状态
  Body: { userId }

POST   /api/admin/users/toggle-download  # 切换下载权限
  Body: { userId }

DELETE /api/admin/users             # 删除用户
  Query: id (用户ID)

系统设置

GET    /api/system-settings        # 获取系统设置
  返回: headerBgColor, logoUrl, siteName

PUT    /api/system-settings        # 更新系统设置(仅管理员)
  Body: { headerBgColor, siteName }

POST   /api/system-settings/upload-logo  # 上传LOGO(仅管理员)
  Body: FormData { logo: File }
  返回: { logoUrl }

部门管理

GET    /api/departments            # 获取部门列表
POST   /api/departments            # 创建部门(仅管理员)
  Body: { name: string }

DELETE /api/departments            # 删除部门(仅管理员)
  Query: id (部门ID)

健康检查

GET    /api/health                 # 服务健康状态
HEAD   /api/health                 # 网络检测

📚 功能详解

用户注册与登录

注册流程

1. 访问注册页面
2. 输入邮箱(唯一性验证)
3. 输入用户名(唯一性验证)
4. 输入密码(bcrypt加密)
5. 确认密码
6. 提交注册
7. 等待管理员激活
8. 激活后可登录使用

密码安全

  • bcrypt加密算法
  • 10轮salt处理
  • 单向哈希,无法解密
  • 数据库不存储明文密码

登录流程

1. 输入邮箱/用户名
2. 输入密码
3. NextAuth验证
4. 生成JWT Token
5. 设置Session Cookie
6. 重定向到首页

会话管理

  • JWT令牌认证
  • Cookie存储(HttpOnly, Secure)
  • 30天有效期
  • 自动刷新机制

素材上传详解

上传前验证

预览图验证:
├── 文件类型:image/*
├── 文件大小:建议 < 10MB
└── 支持格式:JPG, PNG, WebP, GIF

压缩包验证:
├── 文件类型:.zip, .rar, .7z
├── 文件大小:最大10GB
└── 命名规范:支持中文、英文、数字

上传处理流程

1. 客户端验证
   ↓
2. 创建FormData
   ↓
3. XMLHttpRequest上传
   ├→ 监听progress事件
   ├→ 计算上传速度
   └→ 更新进度条
   ↓
4. 服务器接收
   ├→ Formidable解析
   ├→ 文件大小限制检查
   └→ 临时文件存储
   ↓
5. 预览图处理
   ├→ Sharp压缩优化
   ├→ 最大尺寸1000x700
   └→ 上传到MinIO S3
   ↓
6. 压缩包处理
   ├→ 移动到uploads目录
   ├→ 记录文件大小
   └→ 生成文件路径
   ↓
7. 数据库记录
   ├→ 创建Material记录
   ├→ 关联User外键
   └→ 返回素材ID
   ↓
8. 返回成功响应

错误处理

常见错误及处理:
├── 文件过大 → 提示压缩或分割
├── 格式不支持 → 列出支持格式
├── 网络中断 → 提示重新上传
├── S3上传失败 → 重试机制
└── 数据库错误 → 事务回滚

智能筛选系统

筛选算法

筛选优先级:
1. 文本搜索(search)
   - 匹配:SPU, 店铺, 场景, 作者
   - 方式:模糊匹配(LIKE %keyword%)
   
2. 店铺筛选(category)
   - 匹配:categoryName精确匹配
   
3. 场景筛选(scene)
   - 匹配:sceneName精确匹配
   
4. 月份筛选(month)
   - 匹配:createdAt年月匹配
   
5. 结果排序
   - 默认:按创建时间倒序
   - 支持:下载量倒序、点赞量倒序

性能优化

-- 使用数据库索引加速查询
CREATE INDEX idx_materials_category ON materials(categoryName);
CREATE INDEX idx_materials_scene ON materials(sceneName);
CREATE INDEX idx_materials_created ON materials(createdAt);
CREATE INDEX idx_materials_downloads ON materials(downloadCount DESC);
CREATE INDEX idx_materials_likes ON materials(likeCount DESC);

分页实现

分页参数

默认参数:
├── page: 1              # 当前页码
├── pageSize: 20         # 每页数量
└── total: 动态计算      # 总记录数

计算逻辑:
├── offset = (page - 1) * pageSize
├── limit = pageSize
└── totalPages = Math.ceil(total / pageSize)

SQL查询

-- Prisma生成的SQL
SELECT * FROM materials
WHERE [筛选条件]
ORDER BY createdAt DESC
LIMIT 20 OFFSET 0;

-- 总数查询
SELECT COUNT(*) FROM materials
WHERE [筛选条件];

📝 更新日志

v2.6.0 - PSD自动预览与尺寸优化 (2025-10-26)

新增功能

  • 🎨 PSD自动预览生成:上传PSD文件自动生成预览图
    • 使用ag-psd库解析PSD文件
    • 自动提取合成图像作为预览图
    • 无需手动截图或导出预览图
    • 节省用户操作时间
  • ✂️ 长图智能裁剪:PSD长图自动裁剪优化
    • 检测PSD文件高度
    • 超过1200px自动裁剪顶部区域
    • 保留最重要的顶部内容
    • 减少文件大小提升加载速度
  • 📐 预览图尺寸优化:调整为300x500竖版显示
    • 卡片高度从300px增加到500px
    • 显示比例调整为3:5
    • 更适合展示纵向素材
    • 细节保留更加丰富

技术改进

  • 新增psd-processor处理器(lib/psd-processor.ts)
  • 图片处理器支持maxHeight参数
  • 优化图片压缩算法(最大600x1000px)
  • 完善错误处理和临时文件清理
  • Docker镜像包含ag-psd依赖

用户体验

  • PSD文件上传更便捷(预览图可选)
  • 首页卡片展示效果更佳
  • 纵向素材显示更完整
  • 智能提示用户操作

性能优化

  • 预览图文件更小,加载更快
  • PSD长图裁剪减少存储占用
  • 优化图片处理流程

v2.5.0 - 系统设置与部门管理 (2025-10-26)

新增功能

  • 🎨 外观设置:自定义导航栏颜色、LOGO和网站名称
    • 10种预设颜色快速选择
    • 颜色选择器实时预览
    • LOGO上传到MinIO S3存储
    • 网站名称自定义修改
  • 🏢 部门管理:完整的部门管理系统
    • 部门列表查看和管理
    • 新增/删除部门功能
    • 用户注册时选择所属部门
    • 用户信息关联部门字段
  • 🤖 文件格式自动识别:智能识别上传文件类型
    • 支持.max/.psd/.ai/.cad/.dwg/.c4d等源文件格式
    • 根据文件扩展名自动设置素材类型
    • 减少手动选择步骤,提升上传效率
    • 自动识别3DMAX文件并显示渲染器选项
  • 🔄 自动应用:设置保存后自动刷新生效

数据库变更

  • 新增SystemSettings表(系统设置)
  • 新增Department表(部门管理)
  • User表新增department字段

用户体验

  • 管理员可完全自定义平台外观
  • 更好的组织架构管理
  • 上传素材更加智能便捷
  • 设置界面直观友好

技术改进

  • 新增系统设置API接口
  • 新增部门管理API接口
  • 完善文件格式识别逻辑
  • 完善前后端类型定义

v2.4.0 - 多类型素材支持 (2025-10-26)

新增功能

  • ✨ 素材类型系统:支持3DMAX、PSD、AI、CAD、C4D、其他等多种类型
  • 🎯 智能显示:渲染器选项仅在选择3DMAX类型时显示
  • 🏷️ 类型标签:首页卡片显示素材类型标签(橙色)
  • ✏️ 编辑支持:素材编辑功能支持修改素材类型

数据库变更

  • 新增materialType字段到materials表
  • 新增materialType索引优化查询
  • 默认值设置为"3DMAX"保持兼容性

用户体验

  • 上传时清晰的类型选择
  • 条件显示优化用户流程
  • 卡片信息更加完整丰富

技术改进

  • TypeScript类型定义更新
  • API接口支持新字段
  • 前后端完整适配

v2.3.0 - 智能功能更新 (2025-10-17)

新增功能

  • ✨ 拖拽上传:全窗口拖拽支持,自动识别文件类型
  • 🌐 智能网络切换:自动检测内网,无感知切换
  • 🎯 视觉反馈:拖拽时蓝色覆盖层提示
  • 📱 响应式优化:完善移动端体验

技术改进

  • 新增网络检测模块(lib/network.ts)
  • 新增健康检查API(/api/health)
  • 优化拖拽事件处理
  • 改进错误提示机制

v2.2.0 - 素材卡片增强 (2025-10-17)

核心功能

  • ❤️ 点赞功能:用户可为素材点赞,防止重复点赞
  • 📊 下载统计:自动记录下载次数
  • 🎨 卡片优化:SPU标签、彩色分类标签
  • 📈 实时排行:下载榜和点赞榜

数据库变更

  • 新增MaterialLike表
  • Material表新增downloadCount、likeCount字段
  • 新增相关索引

UI改进

  • 卡片信息重新布局
  • 店铺和场景彩色标签
  • 统计数据展示区
  • 互动按钮优化

v2.0.0 - 分类系统重构 (2025-10-16)

重大更新

  • 🏪 一级分类:使用店铺分类系统
  • 🎬 二级分类:场景类别系统
  • 🔍 高级筛选:搜索+分类+场景组合
  • 📅 月份筛选:按上传月份查看
  • 🌙 黑暗模式:自动跟随系统设置

功能增强

  • 上传进度条和网络速度显示
  • 支持7Z压缩格式
  • 取消100MB上传限制(改为10GB)
  • 内外网模式识别和提示

数据库架构

  • 新增Category(分类)表
  • 新增Scene(场景)表
  • Material表新增categoryName字段
  • 优化索引结构

性能优化

  • 添加数据库索引
  • 实时计算上传速度
  • 减少不必要的重渲染

v1.0.0 - 初始版本 (2025-10-15)

核心功能

  • ✅ 用户注册/登录系统
  • ✅ 素材上传(预览图 + 压缩包)
  • ✅ 素材浏览与下载
  • ✅ 管理员后台
  • ✅ 苹果风格UI

技术实现

  • Next.js 14 App Router
  • PostgreSQL + Prisma ORM
  • MinIO S3存储
  • NextAuth.js认证

已修复问题

P0级(已解决)

  • ✅ 大文件上传超时问题(2025-10-20)
    • 禁用客户端超时限制
    • 智能判断实际成功情况
    • 改善错误提示

其他修复

  • ✅ 文件名中文编码问题
  • ✅ Next.js API配置警告
  • ✅ Prisma二进制目标问题
  • ✅ 图片显示404问题
  • ✅ DNS解析错误(部分解决)

🚀 快速开始

系统要求

必需环境:
├── Node.js >= 18.0.0
├── npm >= 9.0.0
├── PostgreSQL >= 14
└── MinIO S3或兼容服务

推荐配置:
├── 内存:4GB+
├── 磁盘:20GB+(取决于素材量)
└── 带宽:10Mbps+

安装步骤

方式一:一键安装(推荐)

# 1. 进入项目目录
cd /Users/lanmu/Desktop/gongxiangp2

# 2. 运行安装脚本
./install.sh

# 3. 启动项目
./start.sh

方式二:手动安装

# 1. 克隆项目
git clone https://git.1080p.hk/chenpei/gongxiangp2.git
cd gongxiangp2

# 2. 安装依赖
npm install

# 3. 配置环境变量
cp .env.example .env.local
# 编辑.env.local,填入数据库和S3配置

# 4. 生成Prisma Client
npm run prisma:generate

# 5. 推送数据库模式
npm run prisma:push

# 6. 启动开发服务器
npm run dev

环境变量配置

创建.env.local文件:

# 数据库配置
DATABASE_URL=postgresql://user:password@host:port/database

# NextAuth认证
NEXTAUTH_SECRET=your-secret-key-min-32-characters
NEXTAUTH_URL=http://localhost:3000

# MinIO S3存储
S3_ENDPOINT=https://s3.1080p.hk
S3_BUCKET=your-bucket-name
S3_ACCESS_KEY_ID=your-access-key
S3_SECRET_ACCESS_KEY=your-secret-key
S3_PUBLIC_DOMAIN=https://s3.1080p.hk/your-bucket-name
S3_FILE_PATH=your-folder/

# 本地上传目录
UPLOAD_DIR=./uploads

创建管理员账号

# 方式一:使用Prisma Studio(推荐)
npm run prisma:studio
# 访问 http://localhost:5555
# 在users表中将用户role改为ADMIN

# 方式二:使用SQL
psql $DATABASE_URL
UPDATE users SET role = 'ADMIN' WHERE email = 'your@email.com';

访问应用

开发环境: http://localhost:3000
生产环境: 根据部署配置

🌐 部署指南

Docker部署(推荐)

Dockerfile

FROM node:18-alpine AS builder

WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

COPY . .
RUN npm run build

FROM node:18-alpine AS runner
WORKDIR /app

COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/.next ./.next
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./

EXPOSE 3000
CMD ["npm", "start"]

docker-compose.yml

version: '3.8'

services:
  app:
    build: .
    container_name: youyidian-3d-material
    ports:
      - "4320:3000"
    environment:
      - DATABASE_URL=${DATABASE_URL}
      - NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
      - NEXTAUTH_URL=${NEXTAUTH_URL}
      - S3_ENDPOINT=${S3_ENDPOINT}
      - S3_BUCKET=${S3_BUCKET}
      - S3_ACCESS_KEY_ID=${S3_ACCESS_KEY_ID}
      - S3_SECRET_ACCESS_KEY=${S3_SECRET_ACCESS_KEY}
      - S3_PUBLIC_DOMAIN=${S3_PUBLIC_DOMAIN}
      - S3_FILE_PATH=${S3_FILE_PATH}
    volumes:
      - ./uploads:/app/uploads
    restart: unless-stopped

  db:
    image: postgres:14-alpine
    container_name: youyidian-db
    environment:
      POSTGRES_DB: youyidian
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: your-password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped

volumes:
  postgres_data:

部署命令

# 构建镜像
docker compose build

# 启动服务
docker compose up -d

# 查看日志
docker compose logs -f app

# 运行数据库迁移
docker compose exec app npx prisma db push

# 停止服务
docker compose down

传统部署

1. 服务器准备

# 安装Node.js
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
sudo apt-get install -y nodejs

# 安装PostgreSQL
sudo apt-get install postgresql postgresql-contrib

# 安装Nginx
sudo apt-get install nginx

# 安装PM2(进程管理)
sudo npm install -g pm2

2. 项目部署

# 克隆代码
git clone https://git.1080p.hk/chenpei/gongxiangp2.git
cd gongxiangp2

# 安装依赖
npm install

# 配置环境变量
nano .env.local

# 构建项目
npm run build

# 使用PM2启动
pm2 start npm --name "youyidian-3d" -- start

# 设置开机自启
pm2 startup
pm2 save

3. Nginx配置

server {
    listen 80;
    server_name your-domain.com;

    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        
        # 大文件上传支持
        client_max_body_size 10240M;
        proxy_request_buffering off;
    }
}

性能优化配置

Next.js配置

// next.config.js
module.exports = {
  // 生产环境优化
  compress: true,
  poweredByHeader: false,
  
  // 图片优化
  images: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: 's3.1080p.hk',
      },
    ],
    formats: ['image/webp'],
  },
  
  // API路由配置
  api: {
    bodyParser: false,
    responseLimit: false,
  },
}

📖 使用教程

普通用户

注册与登录

1. 访问注册页面
2. 填写邮箱、用户名、密码
3. 提交注册(需等待管理员激活)
4. 激活后使用账号登录

浏览素材

1. 登录后自动跳转首页
2. 查看素材网格展示
3. 使用筛选条件:
   - 搜索框:输入关键词
   - 店铺分类:点击店铺按钮
   - 场景分类:点击场景按钮
   - 月份筛选:选择上传月份
4. 查看素材详情:
   - 点击预览图放大查看
   - 查看SPU、作者、文件大小等信息

上传素材

1. 点击右上角"上传素材"按钮
2. 填写素材信息:
   - SPU:商品型号
   - 使用店铺:选择或新建
   - 场景类别:选择或新建
3. 上传文件(支持源文件和压缩包):
   - 方式1:点击选择文件
   - 方式2:拖拽文件到窗口
   - 📌 智能识别:
     * 上传.max文件 → 自动识别为3DMAX
     * 上传.psd文件 → 自动识别为PSD,预览图自动生成
     * 上传.ai文件 → 自动识别为AI
     * 上传.cad/.dwg文件 → 自动识别为CAD
     * 上传.c4d文件 → 自动识别为C4D
     * 上传压缩包 → 需手动选择类型
4. 上传预览图(根据文件类型):
   - PSD文件:预览图显示"(可选)"
     * 💡 系统会自动从PSD提取预览图
     * 也可以手动上传自定义预览图
   - 其他文件:预览图显示"*"(必填)
     * 方式1:点击选择图片
     * 方式2:拖拽图片到窗口
5. 确认素材类型(已自动识别或手动调整)
6. 选择渲染器(仅3DMAX类型显示):CR/VR/其它
7. 点击"上传"按钮
8. 等待上传完成(查看进度和速度)
   - PSD自动预览:系统后台自动处理
   - 手动预览图:即时上传到MinIO

下载素材

1. 找到需要的素材
2. 点击"下载"按钮
3. 浏览器自动下载文件
4. 下载次数+1

互动功能

点赞:
1. 点击❤️按钮
2. 按钮变红表示已点赞
3. 再次点击取消点赞

分享:
1. 点击🔗分享按钮
2. 链接自动复制到剪贴板
3. 粘贴链接分享给他人
4. 他人无需登录即可查看

管理员

用户管理

1. 点击顶部"系统设置"
2. 进入用户管理页面
3. 查看所有用户列表
4. 管理操作:
   - 激活/禁用:控制用户访问权限
   - 允许/禁止下载:控制下载权限
   - 设置管理员:提升用户为管理员
   - 删除用户:删除用户及其素材

素材管理

1. 在系统设置页面
2. 查看所有素材列表
3. 管理操作:
   - 编辑:修改SPU、分类、场景、素材类型、渲染器等
   - 删除:彻底删除素材及文件
   - 查看详情:查看完整信息

分类管理

店铺管理:
1. 查看所有店铺分类
2. 查看每个店铺的素材数量
3. 新建店铺:在上传时创建

场景管理:
1. 查看所有场景分类
2. 查看每个场景的素材数量
3. 新建场景:在上传时创建

🔒 安全特性

认证与授权

密码安全

密码处理流程:
1. 用户输入密码(明文)
2. bcrypt.hash(password, 10)
3. 生成盐值(salt)
4. 进行10轮哈希运算
5. 存储哈希结果到数据库
6. 原始密码不保存

登录验证:
1. 用户输入密码(明文)
2. 从数据库获取哈希值
3. bcrypt.compare(password, hash)
4. 比对结果验证身份

JWT会话管理

Token结构:
{
  header: {
    alg: "HS256",
    typ: "JWT"
  },
  payload: {
    sub: userId,
    email: userEmail,
    role: userRole,
    iat: issuedAt,
    exp: expireAt
  },
  signature: HMACSHA256(
    base64UrlEncode(header) + "." +
    base64UrlEncode(payload),
    secret
  )
}

安全特性:
├── HttpOnly Cookie(防XSS窃取)
├── Secure标记(HTTPS传输)
├── SameSite=Lax(防CSRF)
├── 30天有效期
└── 自动刷新机制

数据安全

SQL注入防护

// ❌ 不安全的方式
db.query(`SELECT * FROM users WHERE email = '${email}'`)

// ✅ Prisma的安全方式
prisma.user.findUnique({
  where: { email }  // 自动参数化查询
})

XSS防护

// React自动转义
// ❌ 危险的方式
<div dangerouslySetInnerHTML={{__html: userInput}} />

// ✅ 安全的方式
<div>{userInput}</div>  // React自动转义HTML

// ✅ 使用DOMPurify清理
import DOMPurify from 'dompurify'
const clean = DOMPurify.sanitize(dirty)

CSRF防护

// NextAuth.js内置CSRF保护
// 每个请求验证CSRF Token
middleware: (req) => {
  const csrfToken = req.cookies.get('csrf-token')
  const headerToken = req.headers.get('x-csrf-token')
  
  if (csrfToken !== headerToken) {
    throw new Error('CSRF validation failed')
  }
}

文件上传安全

文件类型验证

// MIME类型检查
const allowedImageTypes = ['image/jpeg', 'image/png', 'image/webp']
const allowedArchiveTypes = [
  'application/zip',
  'application/x-rar',
  'application/x-7z-compressed'
]

// 文件扩展名检查(支持压缩包和源文件)
const allowedExtensions = [
  // 压缩包格式
  '.zip', '.rar', '.7z',
  // 源文件格式
  '.max',  // 3DMAX
  '.psd',  // Photoshop
  '.ai',   // Adobe Illustrator
  '.cad', '.dwg',  // AutoCAD
  '.c4d'   // Cinema 4D
]

// 双重验证
function validateFile(file: File) {
  const fileExtension = file.name.substring(
    file.name.lastIndexOf('.')
  ).toLowerCase()
  
  const extValid = allowedExtensions.includes(fileExtension)
  
  if (!extValid) {
    throw new Error('不支持的文件格式')
  }
  
  return true
}

// 自动识别素材类型
function detectMaterialType(filename: string): string | null {
  const ext = filename.substring(
    filename.lastIndexOf('.')
  ).toLowerCase()
  
  const typeMap = {
    '.max': '3DMAX',
    '.psd': 'PSD',
    '.ai': 'AI',
    '.cad': 'CAD',
    '.dwg': 'CAD',
    '.c4d': 'C4D',
    '.zip': null, // 需要手动选择
    '.rar': null,
    '.7z': null,
  }
  
  return typeMap[ext] ?? '其他'
}

文件大小限制

// Next.js配置
export const config = {
  api: {
    bodyParser: false,
    responseLimit: false,
  },
}

// 实际限制
const MAX_PREVIEW_SIZE = 10 * 1024 * 1024      // 10MB
const MAX_ARCHIVE_SIZE = 10 * 1024 * 1024 * 1024 // 10GB

路径穿越防护

// 防止../攻击
import path from 'path'

function sanitizeFilename(filename: string) {
  // 移除路径分隔符
  const clean = filename.replace(/[\/\\]/g, '_')
  // 使用path.basename确保安全
  return path.basename(clean)
}

// 使用UUID文件名
import { v4 as uuidv4 } from 'uuid'
const safeFilename = `${uuidv4()}${ext}`

访问控制

路由保护

// middleware.ts
export function middleware(request: NextRequest) {
  const session = await getSession(request)
  
  // 未登录用户重定向到登录页
  if (!session) {
    return NextResponse.redirect('/login')
  }
  
  // 管理员路由检查
  if (request.url.includes('/admin')) {
    if (session.user.role !== 'ADMIN') {
      return NextResponse.redirect('/unauthorized')
    }
  }
  
  return NextResponse.next()
}

API权限验证

// API路由权限检查
export async function GET(request: Request) {
  const session = await getServerSession()
  
  if (!session) {
    return NextResponse.json(
      { error: 'Unauthorized' },
      { status: 401 }
    )
  }
  
  if (session.user.role !== 'ADMIN') {
    return NextResponse.json(
      { error: 'Forbidden' },
      { status: 403 }
    )
  }
  
  // 处理请求
}

数据传输安全

HTTPS强制

# Nginx配置
server {
    listen 80;
    server_name your-domain.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name your-domain.com;
    
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
}

敏感数据加密

// 环境变量加密存储
// ❌ 不要在代码中硬编码
const API_KEY = "sk_live_abc123"

// ✅ 使用环境变量
const API_KEY = process.env.API_KEY

// ✅ 生产环境使用密钥管理服务
import { SecretManagerServiceClient } from '@google-cloud/secret-manager'
const secret = await client.accessSecretVersion({ name })

安全审计

日志记录

// 记录敏感操作
logger.info('User login', {
  userId: user.id,
  email: user.email,
  ip: request.ip,
  userAgent: request.headers['user-agent'],
  timestamp: new Date().toISOString()
})

logger.warn('Failed login attempt', {
  email: attemptedEmail,
  ip: request.ip,
  reason: 'Invalid password'
})

错误处理

// ❌ 不要暴露详细错误
catch (error) {
  return NextResponse.json({
    error: error.message  // 可能泄露敏感信息
  })
}

// ✅ 返回通用错误消息
catch (error) {
  console.error('Internal error:', error)  // 服务器日志
  return NextResponse.json({
    error: 'An error occurred'  // 用户看到的
  }, { status: 500 })
}

⚡ 性能优化

前端优化

代码分割

// 动态导入组件
const UploadModal = dynamic(() => import('@/components/UploadModal'), {
  loading: () => <p>加载中...</p>,
  ssr: false  // 仅客户端渲染
})

// 路由级代码分割(Next.js自动)
pages/
├── index.tsx          → /_app.js + /index.chunk.js
├── admin/page.tsx     → /_app.js + /admin.chunk.js
└── login/page.tsx     → /_app.js + /login.chunk.js

图片优化

// 使用Next.js Image组件
import Image from 'next/image'

<Image
  src={material.previewUrl}
  alt={material.sceneName}
  width={300}
  height={300}
  quality={85}
  loading="lazy"
  placeholder="blur"
/>

// 自动优化功能
├── WebP格式转换
├── 响应式尺寸
├── 懒加载
├── 模糊占位符
└── CDN缓存

资源缓存

// next.config.js
module.exports = {
  headers: async () => [
    {
      source: '/_next/static/:path*',
      headers: [
        {
          key: 'Cache-Control',
          value: 'public, max-age=31536000, immutable',
        },
      ],
    },
  ],
}

后端优化

数据库查询优化

// ❌ N+1查询问题
const materials = await prisma.material.findMany()
for (const material of materials) {
  const user = await prisma.user.findUnique({
    where: { id: material.userId }
  })
}

// ✅ 使用include关联查询
const materials = await prisma.material.findMany({
  include: {
    user: {
      select: {
        username: true
      }
    }
  }
})

数据库索引

-- 常用查询索引
CREATE INDEX idx_materials_category ON materials(categoryName);
CREATE INDEX idx_materials_scene ON materials(sceneName);
CREATE INDEX idx_materials_created ON materials(createdAt DESC);
CREATE INDEX idx_materials_user ON materials(userId);

-- 排行榜索引
CREATE INDEX idx_materials_downloads ON materials(downloadCount DESC);
CREATE INDEX idx_materials_likes ON materials(likeCount DESC);

-- 复合索引
CREATE INDEX idx_materials_cat_scene ON materials(categoryName, sceneName);

API响应优化

// 分页查询减少数据量
const materials = await prisma.material.findMany({
  skip: (page - 1) * pageSize,
  take: pageSize,
  select: {
    // 只查询需要的字段
    id: true,
    previewUrl: true,
    productModel: true,
    // ... 其他必需字段
  }
})

// 并行查询
const [materials, total, categories] = await Promise.all([
  prisma.material.findMany({ ... }),
  prisma.material.count({ ... }),
  prisma.category.findMany({ ... })
])

文件上传优化

流式上传

// 使用流处理大文件
import { createReadStream } from 'fs'
import { Upload } from '@aws-sdk/lib-storage'

const stream = createReadStream(file.filepath)
const upload = new Upload({
  client: s3Client,
  params: {
    Bucket: bucket,
    Key: key,
    Body: stream,
    ContentType: file.mimetype
  }
})

await upload.done()

图片压缩

import sharp from 'sharp'

// 普通图片压缩(最大600x1000px)
const compressedBuffer = await sharp(file.filepath)
  .resize(600, 1000, {
    fit: 'inside',
    withoutEnlargement: true
  })
  .webp({
    quality: 80,
    effort: 4
  })
  .toBuffer()

// PSD预览图生成(自动裁剪长图)
import { generatePsdPreview } from '@/lib/psd-processor'

const result = await generatePsdPreview(
  psdFilePath,      // PSD文件路径
  outputPath,       // 输出路径
  800,              // 最大宽度
  1200              // 长图裁剪高度
)

缓存策略

浏览器缓存

// 静态资源缓存
res.setHeader('Cache-Control', 'public, max-age=31536000, immutable')

// API响应缓存
res.setHeader('Cache-Control', 'private, max-age=60')

// 不缓存敏感数据
res.setHeader('Cache-Control', 'no-store, no-cache, must-revalidate')

服务器缓存

// 使用Node.js内存缓存
const cache = new Map()

async function getCategoriesWithCache() {
  const cacheKey = 'categories'
  
  if (cache.has(cacheKey)) {
    return cache.get(cacheKey)
  }
  
  const categories = await prisma.category.findMany()
  cache.set(cacheKey, categories)
  
  // 5分钟后失效
  setTimeout(() => cache.delete(cacheKey), 5 * 60 * 1000)
  
  return categories
}

🔮 未来规划

短期目标(1-3个月)

功能增强

  • 高级搜索 - 多条件组合搜索,保存搜索历史
  • 批量操作 - 批量上传、批量下载、批量删除
  • 收藏功能 - 用户收藏夹,快速访问常用素材
  • 素材评论 - 用户评论和评分系统
  • 标签系统 - 自定义标签,多维度分类

用户体验

  • 在线预览 - 3D模型在线预览(Three.js)
  • 图片轮播 - 支持多张预览图
  • 快捷键 - 键盘快捷键操作
  • 移动端优化 - PWA支持,离线访问
  • 夜间模式 - 手动切换夜间模式

性能优化

  • CDN加速 - 全站CDN部署
  • Redis缓存 - 热门数据缓存
  • 图片懒加载 - 延迟加载优化
  • 虚拟滚动 - 长列表性能优化

中期目标(3-6个月)

协作功能

  • 团队空间 - 创建和管理团队
  • 权限体系 - 细粒度权限控制
  • 素材审核 - 上传审核工作流
  • 版本管理 - 素材版本控制
  • 消息通知 - 站内消息和邮件通知

数据分析

  • 统计面板 - 可视化数据分析
  • 用户画像 - 用户行为分析
  • 热门趋势 - 素材趋势分析
  • 导出报表 - Excel/PDF报表导出

第三方集成

  • OAuth登录 - 微信、QQ、GitHub登录
  • 云存储集成 - 阿里云OSS、腾讯云COS
  • Webhook - 事件通知接口
  • API开放 - RESTful API文档和SDK

长期目标(6-12个月)

AI智能

  • 智能分类 - AI自动分类和打标签
  • 相似推荐 - 基于内容的推荐系统
  • 智能搜索 - 语义搜索和图像搜索
  • 质量检测 - AI检测素材质量

企业功能

  • 多租户 - SaaS模式支持
  • 工作流 - 自定义审批流程
  • 数据备份 - 自动备份和恢复
  • 安全审计 - 详细的审计日志

生态建设

  • 插件系统 - 支持第三方插件
  • 模板市场 - 预设模板和主题
  • 开发者平台 - API市场和开发者社区
  • 移动应用 - iOS和Android原生应用

📞 技术支持与社区

获取帮助

文档资源

  • 📖 快速使用指南 - 快速使用指南.md
  • 🛠️ 部署指南 - SETUP.md
  • 💻 技术文档 - PROJECT_INFO.md
  • 📝 更新日志 - 本文档更新日志部分

在线资源

  • 🌐 官方网站 - [即将推出]
  • 📚 API文档 - [即将推出]
  • 💬 社区论坛 - [即将推出]
  • 📹 视频教程 - [即将推出]

常见问题

安装问题

Q: npm install失败?

A: 尝试以下解决方案:
1. 清除npm缓存:npm cache clean --force
2. 删除node_modules和package-lock.json
3. 重新安装:npm install
4. 使用国内镜像:npm config set registry https://registry.npmmirror.com

Q: 数据库连接失败?

A: 检查以下项:
1. DATABASE_URL格式正确
2. 数据库服务运行中
3. 网络连接正常
4. 防火墙允许连接

使用问题

Q: 上传大文件失败?

A: 解决方案:
1. 使用内网地址上传(更稳定)
2. 检查网络连接
3. 确认文件大小<10GB
4. 查看浏览器控制台错误

Q: 图片显示404?

A: 检查:
1. S3配置正确
2. next.config.js中配置了图片域名
3. S3存储桶权限为公开读取

贡献指南

报告问题

提交Issue时请包含:
1. 问题描述
2. 复现步骤
3. 期望行为
4. 实际行为
5. 环境信息(OS、浏览器、Node版本)
6. 截图或日志

代码贡献

1. Fork项目
2. 创建特性分支:git checkout -b feature/amazing-feature
3. 提交更改:git commit -m 'Add amazing feature'
4. 推送分支:git push origin feature/amazing-feature
5. 提交Pull Request

代码规范

// 使用ESLint和Prettier
npm run lint        # 检查代码
npm run format      # 格式化代码

// 提交规范
feat: 新功能
fix: 修复bug
docs: 文档更新
style: 代码格式
refactor: 重构
test: 测试
chore: 构建工具

📄 许可证

本项目采用 MIT License 许可证。

MIT License

Copyright (c) 2025 由壹点3D素材平台

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

🙏 鸣谢

技术栈

设计灵感


由壹点3D素材平台

现代化 | 高效率 | 易使用

Made with ❤️ by 由壹点团队

返回顶部