# yao-prompt **Repository Path**: yao-coder/yao-prompt ## Basic Information - **Project Name**: yao-prompt - **Description**: 这是一个提示词资产管理与展示平台,包含图片提示词库和多种文本提示词库。 用户可以浏览、搜索、筛选、排序、收藏、评分、评论,并一键复制提示词使用。后台支持资产、分类、标签、评论、文本库和定时任务管理。 技术上是前后端分离项目:前端使用 Next.js / React,后端使用 Spring Boot,数据存储在 MySQL,并支持本地文件存储或 MinIO。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-11 - **Last Updated**: 2026-06-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Prompt Atlas · 提示词资产库 一个可检索、可复制、可运营的 **多类型 AI 提示词资产库**。前台用户浏览灵感、按分类/标签筛选、一键复制、收藏、评分、评论;管理员后台维护内容、审核评论、看数据看板。 > 项目原名 `yao-image-prompt`,最初只做「图片提示词」;现已扩展为**多库门户**——首页是一个引导页,进去后可选择 **图片 / 角色 / 写作 / 翻译 / 效率办公 …** 等多座提示词库,且后续新增库基本「只补数据、不写代码」。 产品早期方案见 [`docs/product-design.md`](docs/product-design.md)(图片库部分)。 --- ## 目录 - [界面预览](#界面预览--screenshots) - [它能做什么](#它能做什么) - [提示词库一览](#提示词库一览) - [功能特性](#功能特性) - [技术栈](#技术栈) - [目录结构](#目录结构) - [快速启动](#快速启动) - [默认账号](#默认账号) - [页面路由](#页面路由) - [数据库设计](#数据库设计) - [API 一览](#api-一览) - [「库」机制:如何新增一类提示词](#库机制如何新增一类提示词) - [前后端如何对接](#前后端如何对接) - [本地开发须知(踩坑)](#本地开发须知踩坑) - [生产部署](#生产部署) - [命名与历史说明](#命名与历史说明) --- ## 界面预览 / Screenshots > 下面是**占位图**(项目同款 brutalist 风格的 SVG 线框)。跑起来后用真实截图替换:把 PNG/JPG 放进 `docs/screenshots/`,并把本节这 5 处引用的 `.svg` 改成对应文件名即可(保留 `.svg` 名沿用矢量占位也行)。 | 门户引导页 `/` | 图片提示词库 `/image` | | :---: | :---: | | ![门户引导页](docs/screenshots/portal.svg) | ![图片提示词库](docs/screenshots/image-library.svg) | | **文本提示词库 `/library/[key]`** | **提示词详情 · 一键复制** | | ![文本提示词库](docs/screenshots/library.svg) | ![提示词详情](docs/screenshots/prompt-detail.svg) | **管理后台 `/admin`**(顶部「库」下拉切换 role/writing/translation/office…) ![管理后台](docs/screenshots/admin.svg) ## 它能做什么 - **门户引导页(`/`)**:一组提示词库的入口磁贴,由数据库注册表动态驱动,新增库自动多一块。 - **图片提示词库(`/image`)**:AI 图像提示词索引册——灵感墙、分类/标签筛选、搜索、排序、预览面板、一键复制、收藏/评分/评论、相似推荐、协同过滤「也喜欢」。 - **文本提示词库(`/library/{key}`)**:角色设定、写作文案、翻译本地化、效率办公等。内容是「长文本提示词」,详情页有醒目的**复制提示词**按钮 + 等宽正文块 + 使用方式,同样支持分类/标签筛选、搜索、收藏、评分、评论、相似推荐。 - **后台(`/admin`)**:数据看板、图片资产 CRUD + 图片上传、文本提示词 CRUD(粘贴 Markdown,按库切换管理)、分类/标签维护、评论审核、定时任务管理。 --- ## 提示词库一览 门户上的「图片库」是一套独立模块(有图片、对象存储);其余都是**文本提示词库**,共用同一套表、用 `lib_key` 区分,由 `prompt_libraries` 注册表驱动。下表为**种子示例数据**,实际条数会随运营增长: | 库 | key | 路由 | 性质 | 示例条数 | 内容方向 | | --- | --- | --- | --- | --- | --- | | 🖼️ 图片提示词 | `image` | `/image` | 独立模块(含图) | 5 | AI 绘图提示词 + 配图 | | 🎭 角色提示词 | `role` | `/library/role` | 文本库 | 9 | 代码审查官、移动端优化、英语陪练、模拟面试官、心理陪伴、旅行规划… | | ✍️ 写作文案 | `writing` | `/library/writing` | 文本库 | 14 | 小红书/公众号、营销文案、标题优化、周报、演讲稿、多平台改写… | | 🌐 翻译本地化 | `translation` | `/library/translation` | 文本库 | 5 | 中英互译、专业术语、影视字幕、文案本地化、多语种 | | 🗂️ 效率办公 | `office` | `/library/office` | 文本库 | 6 | 会议纪要、PPT 大纲、Excel 公式、头脑风暴、决策分析、任务拆解 | > 角色库的 3 条「代码审查」长提示词来自 `backend/src/main/resources/seed/role-prompts/*.md`,其余均内置在 `RolePromptSeeder` 里。 --- ## 功能特性 **前台(所有库通用)** - 列表:分类侧栏 + 热门标签 + 关键词搜索 + 分页「载入更多」。 - 详情:一键复制(复制数 +1,按访客去重)、收藏、评分(1–5,提交即重算综合分)、评论(支持 emoji、点赞、展示浏览器/系统/IP 归属地)、相似推荐。 - 浏览/复制计数按访客(登录用户或 IP)在时间窗内去重,避免刷量。 - 自动暗色模式(跟随系统)。 **后台(需 admin 角色)** - 数据看板:内容计数、互动汇总、热门榜、分类分布。 - 图片资产:列表/筛选、新增/编辑(上传图片)、上下架、删除。 - 文本提示词:列表/筛选、新增/编辑(粘贴 Markdown 正文)、上下架、删除,**顶部「库」下拉**在 role/writing/translation/office 间切换。 - 分类 / 标签 / 评论:维护与审核(含批量删除评论)。 - 定时任务:评分综合分重算、标签热度重算等的 cron 管理。 **工程能力** - 统一返回结构 `Result` / 分页 `PageResult`、全局异常处理。 - Sa-Token 鉴权(会话存 Redis)、BCrypt 密码、找回密码(邮箱验证码)。 - 反爬拦截器、登录验证码、敏感词过滤、可选的接口全量加密握手。 - 图片存储抽象 `StorageService`:开发用本地目录、生产用 MinIO,切换不改库(只存对象 key)。 --- ## 技术栈 | 端 | 选型 | | --- | --- | | 后端 | Java 21 · Spring Boot 3.3.5 · MyBatis-Plus 3.5.7 · MySQL 8/9(utf8mb4)· Redis 7 · Sa-Token 1.39(会话存 Redis)· BCrypt · MinIO SDK 8.5 · springdoc/Swagger 2.6 · ip2region 2.7 | | 前端 | Next.js 16(App Router)· React 19 · TypeScript 5 · Tailwind CSS v4 · Phosphor Icons · 自托管字体(Archivo / Space Mono,国内可用) | | 存储 | 抽象 `StorageService`:开发用本地 `local_minio/` 目录(`/files/**` 访问),生产切 MinIO(改配置即可)。文本提示词无图,正文直接存 DB(`MEDIUMTEXT`) | | 设计语言 | Swiss / Brutalist:纸白底、墨黑 2px 硬线、信号红强调、零圆角、偏移硬阴影、等宽标签、工程网格背景 | --- ## 目录结构 ``` yao-prompt/ ├── docker-compose.yml 本地依赖:MySQL + Redis(可选 MinIO)一键起 ├── docs/ 产品设计 / 上线手册 / 第三方登录部署 ├── design-previews/ 设计稿预览 ├── image/ 图片库的 5 条真实素材(原图 + prompt.txt) ├── local_minio/ 开发期本地图床(运行时生成,已 gitignore) ├── sql/ 手动建库脚本(可选;dev 会自动建库) ├── backend/ Spring Boot 后端(见 backend/README.md) │ └── src/main/ │ ├── java/com/yao/prompt/ │ │ ├── YaoPromptApplication.java │ │ ├── common/ Result / PageResult / 全局异常 / BizException │ │ ├── config/ MyBatis-Plus、Sa-Token、WebMvc(CORS)、OpenAPI、加密、OAuth │ │ ├── entity/ 实体(图片库 + 文本提示词库 + prompt_libraries) │ │ ├── mapper/ MyBatis-Plus Mapper(+ PromptAssetMapper.xml / RolePromptMapper.xml) │ │ ├── dto/ request 请求参数 / response 响应 VO │ │ ├── service/ 业务逻辑(资产 / 角色提示词 / 收藏 / 评分 / 评论 / 看板…) │ │ ├── controller/ 前台接口 + admin/ 后台接口 │ │ ├── storage/ 存储抽象:Local / MinIO 两套实现 │ │ ├── support/ 反爬、验证码、敏感词、UA 解析、IP 归属地、加密 │ │ └── bootstrap/ 启动初始化:DataInitializer(建列/迁移/默认账号)、RolePromptSeeder(文本库种子)、定时任务 │ └── resources/ │ ├── application.yml / application-dev.yml / application-prod.yml │ ├── db/schema.sql 建表(启动自动执行,IF NOT EXISTS 幂等) │ ├── db/data.sql 图片库种子(启动自动执行) │ ├── mapper/*.xml 分页等手写 SQL │ ├── seed/role-prompts/ 角色库 3 份 Markdown 种子(代码审查类) │ └── sensitive-words.txt └── frontend/ Next.js 前端(见 frontend/README.md) └── src/ ├── app/ App Router 路由(门户 / 图片库 / 通用库 / 后台 / 登录…) ├── components/ TopBar、卡片、弹窗、分页、评分、Toast… └── lib/ api.ts(接口层)、types.ts、auth、crypto、format、toast ``` --- ## 快速启动 ### 0. 前置依赖 - JDK 21、Maven 3.8+ - Node.js 20+(本机更高版本亦可)、npm - MySQL 8/9、Redis 7 可用仓库根的 `docker-compose.yml` 一键起 MySQL + Redis: ```bash docker compose up -d ``` > 没装 Docker 也行:用本机已有的 MySQL / Redis,账号端口对照 `backend/src/main/resources/application-dev.yml` 调整。 ### 1. 后端(端口 8080) ```bash cd backend # dev 默认连 root,密码默认值留空,必须用环境变量提供(不把真实密码写进仓库) MYSQL_PASSWORD=你的密码 mvn spring-boot:run # Windows PowerShell:$env:MYSQL_PASSWORD="你的密码"; mvn spring-boot:run ``` 启动时会自动:建库(JDBC `createDatabaseIfNotExist`)→ 建表(`schema.sql`)→ 轻量库结构升级(`DataInitializer` 补列/迁移唯一键,幂等)→ 灌种子(图片库 `data.sql` + 文本库 `RolePromptSeeder`)→ 创建默认账号。**全程幂等,可反复启动。** - 服务地址: - 接口文档(Swagger): **(可选)准备图片库的本地图床**:图片库的 5 张种子图需要从 `image/` 拷到 `local_minio/assets/seed/`,否则图片库的图会 404(文本库不受影响)。详见 `backend/README.md`。`application-dev.yml` 里的 `app.storage.local.base-dir` 是绝对路径,换机器要改。 ### 2. 前端(端口 3000) ```bash cd frontend npm install # 首次 npm run dev # 开发模式(注意:脚本已固定用 --webpack,见下方踩坑) # 或 npm run build && npm start 生产模式 ``` 打开 ,门户页选择任意一座库即可。 --- ## 默认账号 仅当库中**不存在任何 admin 角色用户**(全新空库)时,启动才会自动创建一个兜底管理员; 已有管理员的库不会被改动,也不再自动创建 demo 演示账号。 | 场景 | 自动创建 | | --- | --- | | dev 全新库 | `admin` / `admin123`(仅本地开发便捷用) | | prod 全新库 | `admin` / `ADMIN_INIT_PASSWORD` 环境变量(未配置则随机,密码见启动日志) | | 库中已有管理员 | 不创建任何账号 | --- ## 页面路由 | 路由 | 说明 | | --- | --- | | `/` | **门户引导页**:图片库 + 各文本库磁贴(注册表驱动) | | `/image` | 图片提示词库首页(灵感墙、筛选、排序、预览、复制/收藏/评分) | | `/assets/[id]` | 图片资产详情(大图、提示词、评分、评论、相似、也喜欢) | | `/favorites` | 图片库 · 我的收藏(需登录) | | `/library/[key]` | **通用文本库首页**(role/writing/translation/office…,一套页面服务所有库) | | `/library/[key]/[id]` | 文本提示词详情(复制、收藏、评分、评论、相似) | | `/library/[key]/favorites` | 文本库 · 我的收藏(需登录) | | `/role`、`/role/[id]`、`/role/favorites` | 旧角色库路由,已**自动重定向**到 `/library/role/*`(保留旧链接可用) | | `/login`、`/register`、`/forgot` | 登录 / 注册(邮箱选填,注册后自动登录)/ 找回密码(验证码两步重置) | | `/oauth/callback` | 第三方登录回调(Gitee / Google) | | `/admin` | 数据看板 | | `/admin/assets`、`/admin/categories`、`/admin/tags`、`/admin/comments` | 图片库管理 | | `/admin/role-prompts`、`/admin/role-categories`、`/admin/role-tags`、`/admin/role-comments` | 文本提示词管理(顶部「库」下拉切换 role/writing/…) | | `/admin/tasks` | 定时任务管理 | --- ## 数据库设计 库名 `yao_prompt`,字符集 `utf8mb4`,**不使用物理外键**(关系由应用层维护,便于软删/迁移)。两组表: **图片库(10 张)** `users` · `categories` · `tags` · `prompt_assets` · `prompt_asset_tags`(资产-标签多对多)· `favorites` · `ratings` · `comments` · `comment_likes` · `scheduled_task` - 资产状态 `status`:0 草稿 / 1 上架 / 2 下架。 - `image_url` / `thumbnail_url` 存的是**对象 key**(如 `assets/seed/1.png`),完整 URL 由存储层按当前模式拼接 → 本地 ↔ MinIO 切换不改库。 **文本提示词库(9 张,多库共用、按 `lib_key` 区分)** `prompt_libraries`(库注册表,驱动门户)· `role_prompts`(正文 `MEDIUMTEXT`)· `role_categories` · `role_tags` · `role_prompt_tags` · `role_favorites` · `role_ratings` · `role_comments` · `role_comment_likes` - `role_prompts.lib_key` / `role_categories.lib_key` / `role_tags.lib_key` 区分属于哪座库(role/writing/translation/office…)。 - 分类、标签在**库内**唯一(`uk_lib_name(lib_key, name)`),所以不同库可重名(如 writing 与 office 都能有标签「总结」)。 - 表名沿用 `role_*` 前缀(历史原因:文本库最早只有「角色」一类),现已是通用文本提示词存储,不必再改名。 > 启动时 `DataInitializer` 会对老库做幂等升级:补 `lib_key` 等列、把分类/标签唯一键从全局 `uk_name` 迁成复合 `uk_lib_name`。 --- ## API 一览 统一返回 `{ code, message, data }`,`code=200` 为成功;分页返回 `{ total, current, size, records }`。 ``` 认证 /api/auth POST /login 登录(带图形验证码 captchaId/captchaCode) POST /register 注册(用户名/密码,邮箱选填,成功后自动登录) GET /captcha 图形验证码 POST /forgot-password 申请重置验证码 {account} POST /reset-password 重置密码 {account, code, newPassword} POST /logout 登出 GET /me 当前用户 GET /oauth/{provider}/url 第三方登录授权地址(gitee/google) 图片库(前台) GET /api/assets 列表(categoryId, tagId, keyword, sort=time|score|favorite, current, size) GET /api/assets/{id} 详情(浏览+1,带收藏/评分态) POST /api/assets/{id}/copy 复制(复制+1,返回提示词) GET /api/assets/{id}/similar 相似推荐 GET /api/assets/{id}/also-liked 协同过滤「也喜欢」 POST /api/assets/{id}/favorite 收藏 [登录] DELETE 取消 POST /api/assets/{id}/rating 评分 {score:1-5} [登录] GET/POST /api/assets/{id}/comments 评论列表 / 发表[登录] POST /api/comments/{id}/like 评论点赞 [登录] DELETE 取消 GET /api/favorites 我的收藏 [登录] GET /api/categories | /api/tags | /api/tags/hot 文本提示词库(前台,?library=role|writing|translation|office) GET /api/prompt-libraries 库注册表(驱动门户磁贴,含每库条数) GET /api/role-prompts?library= 列表(library, categoryId, tagId, keyword, sort=time|score|favorite, current, size) GET /api/role-prompts/{id} 详情 POST /api/role-prompts/{id}/copy 复制 GET /api/role-prompts/{id}/similar 相似推荐 POST /api/role-prompts/{id}/favorite 收藏 [登录] DELETE 取消 POST /api/role-prompts/{id}/rating 评分 [登录] GET/POST /api/role-prompts/{id}/comments 评论列表 / 发表[登录] POST /api/role-comments/{id}/like 评论点赞 [登录] DELETE 取消 GET /api/role-favorites?library= 我的收藏 [登录] GET /api/role-categories?library= 分类(带条数) GET /api/role-tags?library= | /api/role-tags/hot?library= 后台(admin 角色) GET /api/admin/stats 数据看板 CRUD /api/admin/assets[/{id}] 图片资产;/upload 上传图片;/{id}/status 改状态 CRUD /api/admin/categories | /tags 图片分类/标签 GET/状态/删除/批量删除 /api/admin/comments CRUD /api/admin/role-prompts[/{id}]?library= 文本提示词;/{id}/status 改状态 CRUD /api/admin/role-categories | /role-tags ?library= GET/状态/删除/批量删除 /api/admin/role-comments GET/运行/启停/改 cron /api/admin/scheduled-tasks ``` > 鉴权:前台浏览/详情/复制/看评论免登录;收藏/评分/发评论需登录(`@SaCheckLogin`);`/api/admin/**` 需 admin(`@SaCheckRole("admin")`)。 --- ## 「库」机制:如何新增一类提示词 文本库共用一套表(`role_*`)+ 一张注册表(`prompt_libraries`)+ 一套动态前端路由(`/library/[key]`)。**新增一类提示词库基本只需补数据,无需写代码**: 1. 在 `RolePromptSeeder` 里: - 往 `LIBRARIES` 加一行 `new Lib(key, 中文名, 英文名, emoji, 简介, 排序)`; - 准备该库的 `XXX_CATEGORIES`、`XXX_TAGS`、`XXX_SEEDS`(每条 = 标题/适用场景/分类/图标/使用方式/正文/标签); - 在 `run()` 里加一行 `seedTextLibrary("xxx", XXX_CATEGORIES, XXX_TAGS, XXX_SEEDS)`。 2. 重启后端——种子幂等导入,**门户自动多出一块磁贴**,`/library/xxx` 页面、后台「库」下拉、各接口(带 `?library=xxx`)全部即时可用,前端无需改动。 也可以完全走后台:用 admin 在「文本提示词管理」里切到目标库新增(但门户磁贴需要 `prompt_libraries` 有对应行)。 --- ## 前后端如何对接 - **接口地址**:前端读环境变量 `NEXT_PUBLIC_API_BASE`(见 `frontend/.env.local`,默认 `http://localhost:8080`)。 - **鉴权**:登录返回 token,前端存 `localStorage`,后续请求带请求头 `satoken: `;后台页面要求 admin 角色。 - **跨域**:后端 `allowedOriginPatterns("*")` 放行,并允许 `satoken` 自定义头,前端 3000 → 后端 8080 直连无需代理。 - **图片**:后端只存对象 key,完整 URL 由存储层拼接;前端直接用返回的 `imageUrl`。 - **(可选)接口加密**:`app.crypto.enabled=true` + 前端 `NEXT_PUBLIC_CRYPTO_ENABLED=true` 开启握手后的全量请求体加密(默认关)。 --- ## 本地开发须知(踩坑) - **前端必须用 `--webpack` 跑 dev**:本仓库的 `dev` 脚本已固定为 `next dev --webpack`。该版本 Next 的 Turbopack 在本项目会 panic 导致页面无限刷新,别改回 `next dev`。 - **curl 测接口要带浏览器 UA**:后端有反爬拦截器,默认 UA 的请求会被拦成 `{"code":429,"检测到自动化访问"}`,加一个 `User-Agent: Mozilla/5.0 ... Chrome/... Safari/537.36` 头即可。 - **登录有图形验证码**:`/api/auth/login` 需要 `captchaId/captchaCode`,纯 curl 不便登录;要测需登录的写接口请走前端,或临时放开验证码。 - **文本库的库标识列叫 `lib_key` 不是 `library`**:`library` 在 MySQL 9.x 是保留字,未加反引号会语法报错;实体里字段名 `libKey`(靠下划线驼峰映射到列 `lib_key`)。 --- ## 生产部署 - 后端用 `prod` profile:`java -jar target/yao-prompt-backend.jar --spring.profiles.active=prod`(或用 `backend/run-prod.sh`,它会先 `source .env.prod`)。 - 通过环境变量注入 MySQL / Redis / MinIO 配置,`app.storage.type=minio`: ``` MYSQL_*、REDIS_*、MINIO_ENDPOINT/ACCESS_KEY/SECRET_KEY/BUCKET/PUBLIC_BASE_URL … ``` - 上线前确认目标 MySQL 里有库 `yao_prompt`(或让 `createDatabaseIfNotExist` 自动建)。 - 前端 `npm run build` 时注入正式的 `NEXT_PUBLIC_API_BASE`。 - 第三方登录(Gitee / Google OAuth):见 [`docs/部署-第三方登录.md`](docs/部署-第三方登录.md)。 - 完整上线步骤见 [`docs/上线手册-生产部署.md`](docs/上线手册-生产部署.md)。 --- ## 命名与历史说明 - 项目由 `yao-image-prompt` 改名为 **`yao-prompt`**,定位从「图片提示词」扩展为多类型提示词资产库。 - 后端 Java 包、库名、artifact 已统一为 **`com.yao.prompt`** / **`yao_prompt`** / **`yao-prompt-backend`**,主类 `YaoPromptApplication`。 - 文本库的表名仍以 **`role_*`** 为前缀(最早只有「角色」一类),现为通用文本提示词存储,不影响功能,未再改名。 --- 子模块文档:[`backend/README.md`](backend/README.md) · [`frontend/README.md`](frontend/README.md)