# devgallery **Repository Path**: unihao/devgallery ## Basic Information - **Project Name**: devgallery - **Description**: 个人技术主页 + 开源项目作品集**,面向面试官、技术同行、开源社区访客;轻量、可独立部署、低维护,重点突出项目源码、演示地址、技术栈、作品亮点。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-28 - **Last Updated**: 2026-09-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # DevGallery · 个人技术主页 + 开源项目作品集 面向面试官、技术同行与开源社区访客的个人作品集站点:集中展示个人信息、开源项目、技术文章与简历, 内容包括配置化维护(MySQL 落库 + Markdown 文档),支持标签筛选、名称搜索、热度排序、主题切换、SEO 与访问统计。 技术栈:**Vue 3 + Vite + TypeScript**(前端) / **Spring Boot 3 + MyBatis + MySQL 8**(后端,DDD 分层)。 --- ## 一、目录结构 ``` devgallery/ ├─ devgallery-server/ 后端服务(Spring Boot + MyBatis,DDD 分层) │ ├─ src/main/java/com/devgallery/ │ │ ├─ interfaces/ 接口层:Controller、DTO(VO/Request)、Assembler、全局异常处理 │ │ ├─ application/ 应用层:用例编排、命令对象 │ │ ├─ domain/ 领域层:聚合根、值对象、枚举、仓储接口 │ │ └─ infrastructure/ 基础设施层:PO、Mapper(MyBatis XML)、Converter、仓储实现、配置 │ ├─ src/main/resources/ │ │ ├─ application.yml 数据源与站点配置 │ │ ├─ mapper/*.xml SQL 映射 │ │ └─ db/init.sql 建库建表 + 示例数据 │ └─ pom.xml ├─ devgallery-web/ 前端站点(Vue 3 + Vite) │ ├─ src/ │ │ ├─ api/ 接口封装(axios 统一拆包) │ │ ├─ components/ 通用组件(导航、卡片、Markdown、骨架屏…) │ │ ├─ composables/ 主题切换、SEO、访客标识 │ │ ├─ router/ 路由表(详情页延迟上报访问) │ │ ├─ views/ 页面:首页 / 项目列表 / 项目详情 / 文章 / 简历 / 404 │ │ └─ styles/main.css 主题变量与 Markdown 排版 │ ├─ public/robots.txt 搜索引擎抓取规则 │ ├─ public/sitemap.xml 站点地图 │ └─ vite.config.ts /api 代理到 8080 └─ .github/workflows/build.yml CI:前端构建 + 后端打包 ``` ## 二、功能与 PRD 对应 | 编号 | 功能 | 实现位置 | | --- | --- | --- | | FR-01 | 个人信息主页 | `ProfileVO` + `views/HomeView.vue` 的 Hero 区(头像、职业标签、社交链接、精选项目) | | FR-02 | 项目列表:卡片/标签筛选/搜索/更新时间或 Star 排序 | `GET /projects`、`views/ProjectsView.vue` | | FR-03 | 项目详情:截图、动图、背景、核心功能、架构、难点亮点、源码与演示链接 | `GET /projects/{slug}`、`views/ProjectDetailView.vue` | | FR-04 | Markdown 文档渲染(复用 README) | `components/MarkdownView.vue`(禁原始 HTML + 代码高亮 + 外链 noopener) | | FR-05 | 深色/浅色主题切换、本地持久化、跟随系统 | `index.html` 首屏脚本 + `composables/useTheme.ts` | | FR-06 | 响应式适配(375/768/1440) | `styles/main.css` 断点 + 各组件 `@media` | | FR-07 | 技术文章列表与详情 | `GET /posts`、`views/PostsView.vue`、`views/PostDetailView.vue` | | FR-08 | 简历下载入口 | `views/ResumeView.vue`(在线简历 + 打印/导出 PDF + PDF 链接) | | FR-09 | SEO:title/description/OG/canonical/JSON-LD/sitemap/robots | `composables/useSeo.ts`、`public/sitemap.xml`、`public/robots.txt` | | FR-10 | 页面访问统计(总 PV/UV、各详情浏览排行) | `POST /visits`、`GET /visits/stat`、`GET /visits/rank` | | FR-11 | 内容为数据驱动(新增项目只需新增数据与文档) | 项目/段落/文档三张表 + 前后端均无需改动代码 | | FR-12 | 自动构建发布 | `.github/workflows/build.yml`(push main 触发) | ## 三、快速开始 ### 1. 初始化数据库 ```bash mysql -uroot -ptiger < devgallery-server/src/main/resources/db/init.sql ``` 脚本幂等执行:建表用 `CREATE TABLE IF NOT EXISTS`,示例数据用 `ON DUPLICATE KEY UPDATE`。 连接信息可在 `devgallery-server/src/main/resources/application.yml` 调整。 ### 2. 启动后端 ```bash cd devgallery-server mvn -DskipTests package java -jar target/devgallery-server.jar # 默认 http://127.0.0.1:8080/api ``` ### 3. 启动前端 ```bash cd devgallery-web npm install npm run dev # http://127.0.0.1:5173(被占用时自动顺延端口) npm run build # 产物输出 dist/ ``` `/api` 已在 `vite.config.ts` 中代理到 `http://127.0.0.1:8080`, 生产环境由 Nginx 同源部署即可(参考下方 Nginx 片段)。 ## 四、接口一览 | 方法 | 路径 | 说明 | | --- | --- | --- | | GET | `/api/profile` | 个人信息 | | GET | `/api/profile/home?limit=6` | 首页聚合(个人信息 + 精选项目 + 站点统计) | | GET | `/api/site/meta` | 站点 SEO 元信息(域名、title、description、简历地址) | | GET | `/api/projects?keyword=&tag=&sort=&featured=&pageNo=&pageSize=` | 项目分页列表,`sort` 取值 `updated` / `stars` | | GET | `/api/projects/{slug}` | 项目详情(含结构化段落与 README) | | GET | `/api/projects/tags` | 全部项目标签 | | GET | `/api/posts?keyword=&tag=&pageNo=&pageSize=` | 文章分页列表 | | GET | `/api/posts/{slug}` | 文章详情(浏览量自增) | | GET | `/api/posts/tags` | 文章标签 | | POST | `/api/visits` | 访问上报 `{ visitorId, path, referrer, targetType, targetId }` | | GET | `/api/visits/stat` | 站点 PV/UV(含今日) | | GET | `/api/visits/rank?targetType=project&limit=10` | 访问排行 | 统一响应包:`{ code, message, data, timestamp }`,`code = 0` 表示成功。 ## 五、DDD 分层约束 - **依赖方向**:`interfaces → application → domain ← infrastructure`,领域层不依赖任何框架; - **仓储倒置**:`domain.repository` 定义接口,`infrastructure.persistence.repository` 提供 MyBatis 实现; - **模型隔离**:数据库形态(PO、逗号分隔标签串、JSON 链接)在 Infrastructure 的 Converter 中完成防腐转换, 领域模型只暴露 `List`、`SocialLink` 值对象等语义化结构; - **协议隔离**:外层 VO / Request 与内层命令对象由 Assembler + 应用层分别承接,接口变更不侵入领域。 ## 六、生产部署建议 ```nginx server { listen 80; server_name your.domain; root /opt/devgallery-web/dist; index index.html; location / { try_files $uri $uri/ /index.html; # SPA 回退 } location /api/ { proxy_pass http://127.0.0.1:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } } ``` 静态资源建议托管 CDN 并开启 gzip / br 压缩;首页已合并请求(`/api/profile/home`), 配合图片懒加载与代码分包可稳定满足首屏秒开目标。