# chen-dynasty **Repository Path**: chenzhanxu/chen-dynasty ## Basic Information - **Project Name**: chen-dynasty - **Description**: 晨之博客(Chen Blog):Go + Vue 3 全栈个人博客系统(前后端分离)。Markdown 文章编写与阅读统计、多级分类标签、全文搜索、用户中心(头像/登录日志)、公告、数据可视化、系统监控、亮暗双主题;管理后台 8 大模块(仪表盘/用户/分类/标签/媒体分类管理/站点设置/公告/数据库)。SQLite 零配置开箱即用,内置演示数据,支持 Docker 一键部署。 - **Primary Language**: Go - **License**: MulanPSL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-04-17 - **Last Updated**: 2026-09-20 ## Categories & Tags **Categories**: Uncategorized **Tags**: 个人博客 ## README
# 🌸 Chen Blog **A clean & elegant personal blog system · Go + Vue 3 · Frontend/Backend separated · Zero-config ready** ![Go](https://img.shields.io/badge/Go-1.21%2B-00ADD8?style=flat-square&logo=go) ![Vue](https://img.shields.io/badge/Vue-3.4%2B-4FC08D?style=flat-square&logo=vuedotjs) ![Gin](https://img.shields.io/badge/Gin-v1.9-00ADC6?style=flat-square&logo=go) ![Naive UI](https://img.shields.io/badge/Naive%20UI-2.38-green?style=flat-square) ![SQLite](https://img.shields.io/badge/SQLite-3-003B57?style=flat-square&logo=sqlite) ![Docker](https://img.shields.io/badge/Docker-Ready-2496ED?style=flat-square&logo=docker) ![Version](https://img.shields.io/badge/Version-1.6.0-4FC08D?style=flat-square) ![License](https://img.shields.io/badge/License-MIT-yellow?style=flat-square) ![Stars](https://img.shields.io/gitee/stars/chenzhanxu/chen-dynasty?style=flat-square&logo=gitee) ![Forks](https://img.shields.io/gitee/forks/chenzhanxu/chen-dynasty?style=flat-square&logo=gitee) [中文文档](README.md) · [🚀 Live Demo](https://blog.chenzhanxu.top/) · [HTTP Entry](http://blog.chenzhanxu.top/) · [Gitee Repository](https://gitee.com/chenzhanxu/chen-dynasty) · [Report Issue](https://gitee.com/chenzhanxu/chen-dynasty/issues)
--- ## 📑 Quick Navigation | 📂 Section | 📄 Content | |---|---| | [✨ Features](#-features) | Complete frontend & admin feature list | | [🛠️ Tech Stack](#️-tech-stack) | Backend & frontend technology tables | | [🏗️ Architecture](#️-architecture) | System architecture diagram & data flow | | [🚀 Quick Start](#-quick-start) | Three ways to run (Script / Docker / Local) | | [📁 Project Structure](#-project-structure) | Directory tree & key file descriptions | | [⚙️ Configuration](#️-configuration) | Core config items & env var overrides | | [📖 API Documentation](#-api-documentation) | Swagger online & offline docs | | [🧑‍💻 Development Guide](#-development-guide) | Demo data, utility scripts, DB switching | | [🔨 Build & Deploy](#-build--deploy) | Local build, Docker, 1Panel deployment | | [❓ FAQ](#-faq) | 5 high-frequency questions | --- ## ✨ Features ### 🌍 Frontend | Module | Core Capabilities | Highlights | |---|---|---| | 📝 **Articles** | Markdown edit/render · Auto-save drafts · Pinning · Soft delete · Related posts | Code highlight, TOC, reading progress | | 📊 **Reading Stats** | PV / UV · Reading time estimate · Auto default cover for missing images | ECharts real-time visualization | | 🏷️ **Categories & Tags** | Multi-level category tree · Tag aggregation pages · Multi-dimension filtering | Drag-drop tree sorting | | 🔍 **Full-Text Search** | Keyword search · Suggestions · Hot keywords · Search history | Local index, millisecond response | | 👤 **User Center** | Register/Login (remember me, 7-day session, fail-lock) · Profile · Login history · My articles | JWT + bcrypt, secure | | 📢 **Announcements** | Sidebar announcement card, published from admin panel | Markdown rendering | | 🖥️ **System Monitor** | Server resources · Go runtime (GC/Goroutines) · DB pool · QPS real-time metrics | Auto-refresh + history trends | | 📈 **Data Visualization** | Visit trends · Hot articles · Category/tag distribution | ECharts 6 interactive charts | | 📱 **Responsive Design** | Desktop/Tablet/Mobile breakpoints | Mobile-first | | 🌙 **Dark Mode** | Instant light/dark toggle, all components themed for both | localStorage persistence | > 📦 **Built-in Demo Data**: The repo ships with a SQLite demo database (`backend/blog.db`) containing **12 real tech articles, 7 categories, 12 tags, 9 comments, 4 friend links, 4 users** — clone and go, ready for public deployment. --- ### 🔐 Admin Panel (`/admin`) | Module | Core Capabilities | Highlights | |---|---|---| | 📊 **Dashboard** | Time-based greeting · Stat cards (articles/users/PV/UV/comments) · Category pie chart · Hot articles TOP5 · Quick actions | Real-time data refresh | | 👥 **User Management** | Stat bar · Avatar rendering · Search · Ban/Unban · Role change · Delete | Batch operations | | 🗂️ **Category Management** | Tree view · Search & filter · Multi-level CRUD | Drag-drop sorting | | 🏷️ **Tag Management** | Colorful tag cloud · Stat bar · Search & filter · CRUD (with color picker) | Live color preview | | 🖼️ **Media Management** | Card grid preview · **Category upload/filter** (avatar/wallpaper/article/screenshot/other) · Batch delete · Inline preview | Auto thumbnail generation | | ⚙️ **Site Settings** | ICP/Police record · Site start date · Custom key-values · Footer live preview (same source as frontend) | WYSIWYG | | 📢 **Announcement Management** | Publish frontend announcements (title + Markdown) · Live preview · Stat bar | Instant effect | | 🗄️ **Database Management** | DB overview · Table data distribution · TOP10 tables · Table list · Driver switching | One-click SQLite/MySQL switch | > 💡 The backend still provides APIs for **friend links, custom pages, notifications, reports** (see [API Documentation](#-api-documentation)). Since the frontend has no consuming scenarios yet, the corresponding admin pages have been removed. --- ## 🛠️ Tech Stack ### Backend | Technology | Description | Version | Purpose | |---|---|---|---| | **Go** | Server language | 1.21+ | High performance, strong typing, simple deployment | | **Gin** | HTTP web framework | v1.9+ | Blazing fast routing, middleware ecosystem | | **GORM** | ORM library | v2 | Eager loading, migrations, hooks | | **SQLite** | Default DB (zero-config) | 3.x | Out-of-the-box, single-file deployment | | **MySQL** | Production database | 8.0+ | High concurrency, replication | | **JWT** | Authentication (custom expiry) | go-jwt | Stateless auth | | **bcrypt** | Password hashing | - | Adaptive cost factor | | **gin-swagger** | API documentation | - | Auto-generate OpenAPI 3.0 | ### Frontend | Technology | Description | Version | Purpose | |---|---|---|---| | **Vue 3** | Frontend framework | 3.4+ | Composition API, composables | | **TypeScript** | Type system | 5.4+ | Type safety, refactor-friendly | | **Vite** | Build tool | 5.2+ | Instant cold start, on-demand compilation | | **Naive UI** | UI library (light/dark theme) | 2.38+ | TypeScript-first, tree-shaking | | **md-editor-v3** | Markdown editor | 6.4+ | Toolbar, live preview, image upload | | **marked + DOMPurify** | Markdown rendering + XSS protection | - | Secure rendering | | **ECharts** | Data visualization | 6.0+ | Interactive charts, theme adaptation | | **Vue Router** | Routing | 4.3+ | Nested routes, guards, lazy loading | | **Axios** | HTTP client | 1.6+ | Unified auth, 401 auto-redirect, request cancellation | --- ## 🏗️ Architecture ``` ┌─────────────────────────────────────────────────────────────────┐ │ Client (Browser) │ └─────────────────────────────┬───────────────────────────────────┘ │ HTTPS / HTTP ▼ ┌─────────────────────────────────────────────────────────────────┐ │ Nginx (Frontend Container) │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ Static │ │ /api → │ │ /uploads → │ │ │ │ Assets │ │ Backend │ │ Backend │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ └─────────────────────────────┬───────────────────────────────────┘ │ Internal Network ▼ ┌─────────────────────────────────────────────────────────────────┐ │ Backend (Gin + GORM) │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ Article │ │ User │ │ Media │ │ Monitor │ ... │ │ │ Module │ │ Module │ │ Module │ │ Module │ │ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │ │ │ │ │ │ │ └──────────┴──────────┴──────────┘ │ │ │ │ │ ┌─────────┴─────────┐ │ │ │ Database Layer │ │ │ │ SQLite / MySQL │ │ │ └───────────────────┘ │ └─────────────────────────────────────────────────────────────────┘ ``` > 📌 **Key Design Decisions**: > - **Full frontend/backend separation**: Static assets served by Nginx, API requests reverse-proxied to backend > - **Dual database mode**: Default SQLite for zero-config; production MySQL with **auto-fallback to SQLite** on connection failure, ensuring availability > - **Auth flow**: JWT Access Token (default 24h) + bcrypt password hash + login failure lockout (per username+IP, 5 min) --- ## 🚀 Quick Start > 🖥️ **Live Demo** (accessible via HTTPS or HTTP): > - **HTTPS**: > - **HTTP**: > > Frontend & admin included — see "Default Account" below for login ### Option 1: One-Click Start in Container (Recommended ⭐) ```bash # Clone the repo git clone https://gitee.com/chenzhanxu/chen-dynasty.git cd chen-dynasty # One-click start (readiness checks, logs, process guard) bash start_blog.sh ``` | Service | URL | Description | |---|---|---| | Frontend | http://localhost:5173 | Vite Dev Server (HMR) | | Backend API | http://localhost:8080 | Gin Server | | Swagger Docs | http://localhost:8080/swagger/index.html | Interactive API testing | --- ### Option 2: Docker Compose (Production Recommended 🐳) ```bash # 1. Copy env template and customize cp .env.example .env # 2. Start (frontend Nginx includes /api /uploads /swagger reverse proxy) docker-compose up -d ``` | Service | Port | Description | |---|---|---| | Frontend | 80 (container) → host configurable | Nginx static + reverse proxy | | Backend | 8080 (container) → host configurable | API service | | Volume | `blog-data` | SQLite persistence (`blog.db`) | > 💡 `docker-compose.yml` frontend Nginx already configures `/api`, `/uploads`, `/swagger` locations proxying to backend container — **single port access, no extra CORS config needed**. --- ### Option 3: Local Development (Dev/Debug 🛠️) ```bash # Terminal 1: Backend cd backend export PATH=$PATH:/usr/local/go/bin # If Go not in PATH go mod download go run main.go # http://localhost:8080 # Terminal 2: Frontend cd frontend npm install npm run dev # http://localhost:5173 ``` --- ### Default Account | Item | Value | Note | |---|---|---| | Username | `admin` | Admin role | | Password | `Admin123` | Case-sensitive, **must change before production!** | > 💡 Repo includes demo database `backend/blog.db` (tracked in Git) with admin account and 12 real articles — clone and log in. > > Docker deployments can set initial admin password via `ADMIN_INITIAL_PASSWORD` env var (defaults to `Admin123`). --- ## 📁 Project Structure ``` chen-dynasty/ ├── backend/ # 🐹 Go Backend │ ├── main.go # Entry point │ ├── config.example.yaml # Config template (copy to config.yaml) │ ├── cmd/ # CLI entry │ ├── config/ # Config loading (config.yaml + env overrides) │ ├── database/ # DB init, auto-migration, default admin │ ├── handlers/ # HTTP handlers (incl. login_guard) │ ├── middleware/ # Middleware (JWT auth, CORS, logging, recovery) │ ├── models/ # GORM data models │ ├── router/ # Route registration (article/user/media/statistics/monitor…) │ ├── services/ # Business logic layer │ ├── tools/ # Demo data / migration / utility scripts (standalone main) │ ├── utils/ # Utilities (JWT, password, response, logging) │ ├── docs/ # Swagger generated docs │ └── uploads/ # Upload directory ├── frontend/ # 🖖 Vue 3 Frontend │ ├── nginx.conf # Nginx config (with reverse proxy) │ └── src/ │ ├── api/ # Axios API wrappers (unified error handling) │ ├── components/ # Shared components (NavBar, Footer, Layout, etc.) │ ├── router/ # Route config (lazy loading, auth guards) │ ├── views/ # Frontend pages │ │ ├── Home.vue │ │ ├── Article.vue │ │ ├── Search.vue │ │ ├── Profile.vue │ │ └── MyArticles.vue │ └── views/admin/ # Admin pages (8 modules) │ ├── Dashboard.vue │ ├── UserManage.vue │ ├── CategoryManage.vue │ ├── TagManage.vue │ ├── MediaManage.vue │ ├── SiteSettings.vue │ ├── AnnouncementManage.vue │ └── DatabaseManage.vue ├── start_blog.sh # One-click startup script ├── docker-compose.yml # Docker orchestration ├── .env.example # Docker env template ├── README.md # Chinese documentation └── README.en.md # English documentation ``` --- ## ⚙️ Configuration ### Dual Database Modes | Driver | Use Case | Key Config | |---|---|---| | `sqlite` (default) | Dev, test, lightweight deploy | `database.sqlite.path` → local file | | `mysql` | Production, high concurrency | `database.mysql.*` connection info, **auto-fallback to SQLite on failure** | ### Config File Config lives in `backend/config.yaml` (copy from `config.example.yaml`). **Every option can be overridden by an environment variable** (UPPER_SNAKE_CASE): ```bash # Common env vars JWT_SECRET=your-super-secret-key # JWT secret (MUST change in production!) DATABASE_DRIVER=sqlite # Database driver: sqlite / mysql ADMIN_INITIAL_PASSWORD=your-password # Admin initial password APP_PORT=8080 # Backend port ``` Core config example: ```yaml app: port: "8080" mode: debug # debug / release database: driver: sqlite # sqlite / mysql sqlite: path: ./blog.db jwt: secret: "" # Production: strong random string (≥32 chars) expire_hour: 24 log: level: info filename: ./logs/blog.log max_size: 100 # Per-file size (MB), auto rotation & compression cors: allow_origins: - "http://localhost:5173" - "https://your-domain.com" media: upload_path: ./uploads max_file_size: 10 # MB thumbnail: enabled: true # Auto-generate thumbnails ``` --- ## 📖 API Documentation | Format | URL | Description | |---|---|---| | 🌐 **Online Swagger UI** | `http://localhost:8080/swagger/index.html` | Interactive testing, auth, export OpenAPI JSON | | 📄 **Offline Markdown** | [backend/API_DOC.md](backend/API_DOC.md) | Full endpoint list, request/response examples | > 💡 Swagger docs auto-generated via `swag init` from code annotations (`// @Summary`, `@Param`, etc.). --- ## 🧑‍💻 Development Guide ### Demo Data Repo includes a real demo database `backend/blog.db` (tracked in Git — **no manual init needed**): | Data | Count | Description | |---|---|---| | Articles | 12 | 3 pinned; covering Go / Vue / Docker / K8s / MySQL / Redis / writing, etc. | | Categories | 7 | Tech / Life / Project Experience / DevOps / Database / Dev Tools / Career | | Tags | 12 | Go, Docker, Kubernetes, MySQL, Redis, Vue.js, Git, CI/CD, etc. | | Comments | 9 | Real comment content | | Friend Links | 4 | Go 语言中文网, Vue.js official, Gitee, 阮一峰的网络日志 | | Users | 4 | `admin` + 3 demo users | To regenerate demo data or inspect row counts, use standalone tools under `backend/tools/` (**each is an independent `main` program** — compile & run individually): ```bash cd backend # Generate article demo data go run tools/seed_data.go # Generate tags + article associations go run tools/seed_tags.go # Generate categories + article mapping fixes go run tools/seed_categories.go # Inspect DB row counts go run tools/check_sqlite_data.go ``` > ⚠️ Tools under `tools/` are independent `main` programs — **do not run `go build ./...`** for the whole directory; run each with `go run` separately. --- ### Utility Scripts ```bash # Generate default cover placeholder images (101~104.png) python3 backend/tools/gen_covers.py # Precisely stop blog-server process (avoids accidental kills) python3 backend/tools/stop_backend.py ``` --- ### Database Switching (SQLite ↔ MySQL) 1. Change `database.driver` to `mysql` in `backend/config.yaml` and fill in connection info 2. Restart backend (migration runs automatically via GORM AutoMigrate) 3. Detailed guides: - [DATABASE_SWITCH_GUIDE.md](backend/DATABASE_SWITCH_GUIDE.md) — Driver switching - [DATA_MIGRATION_GUIDE.md](backend/DATA_MIGRATION_GUIDE.md) — Data migration --- ### Logging Level-based logging with size rotation, auto-compression, structured output. See [LOG_USAGE.md](backend/LOG_USAGE.md). --- ## 🔨 Build & Deploy ### Local Build ```bash # Backend cd backend go build -o blog-server main.go ./blog-server # Frontend (output in dist/, served by Nginx) cd frontend npm run build ``` --- ### Docker Compose Deploy ```bash docker-compose up -d ``` **Frontend Nginx (`frontend/nginx.conf`) includes three reverse-proxy locations**: | Location | Proxy Target | Purpose | |---|---|---| | `/api/` | `http://backend:8080` | All API requests | | `/uploads/` | `http://backend:8080` | Static file access | | `/swagger/` | `http://backend:8080` | API documentation | > Single-port access, no extra CORS config needed. --- ### 1Panel Deployment (Chinese Ops Panel 🇨🇳) #### Option A: Compose Deployment (Recommended ⭐) 1. **Upload code** ```bash git clone https://gitee.com/chenzhanxu/chen-dynasty.git # or upload & extract archive to server directory ``` 2. **(Optional) Adjust port mappings** Edit `docker-compose.yml` — **only change the host port (left of `:`)**, never the container ports (`8080` / `80`). 3. **Create Compose** 1Panel → **Containers → Compose → Create Compose** - Name: `chen-blog` - Source: "Server local" - Select project root (where `docker-compose.yml` lives) - Confirm (first pull + build ~5–15 min) 4. **Verify** Containers `chen-blog-backend` and `chen-blog-frontend` appear with `healthy` status; visit `http://SERVER_IP:port` 5. **(Production, Optional) Domain + HTTPS** 1Panel → **Websites → Create Website → Reverse Proxy** → bind domain to frontend port → issue SSL cert for HTTPS --- #### Option B: Static Deployment (No Docker) | Step | Action | |---|---| | 1. Build backend | `cd backend && go build -o blog-server main.go` → upload, run via 1Panel **Process Guard** or systemd (on :8080) | | 2. Build frontend | `cd frontend && npm run build` → upload `dist/` | | 3. Create static site | 1Panel → **Websites → Create Website → Static Website** → point to `dist/` | | 4. Add reverse proxy | Add `/api`, `/uploads`, `/swagger` locations from `nginx.conf`, change `proxy_pass` to `http://127.0.0.1:8080` | --- ### ⚠️ 3 Must-Dos for Production | # | Item | Action | Priority | |---|---|---|---| | 1 | 🔑 **JWT Secret** | Add `JWT_SECRET=` to backend container env | 🔴 Critical | | 2 | 👤 **Admin Password** | Change immediately after login (default `admin / Admin123`) | 🔴 Critical | | 3 | 💾 **Data Backup** | SQLite data in volume `blog-data` (`blog.db`); schedule volume backups in 1Panel | 🟡 Important | --- ## ❓ FAQ
1. http://localhost:8080 returns 404? **Expected** — the backend is a pure API service with no root page. Use: - API docs: `http://localhost:8080/swagger/index.html` - Frontend: `http://localhost:5173`
2. Blank frontend page? Check backend is running, open browser DevTools → Console/Network for errors. Common causes: - Backend not started or port conflict - CORS missing frontend origin - Build output path incorrect
3. Image upload fails? Verify `backend/uploads` directory is writable (Docker: confirm volume mount).
4. CORS errors? Ensure `cors.allow_origins` in `config.yaml` includes the actual frontend origin (protocol, domain, port).
5. "Too many attempts" on login? Repeated login failures from same username + IP trigger a **5-minute lock** (security policy, in-memory counter). Fix: wait for unlock, or restart backend to clear in-memory counter.
--- ## 📄 License This project is open-sourced under the [MIT License](LICENSE). ---
### 💖 Like this project? **Give it a ⭐ Star!** Every star fuels ongoing maintenance. [![Star History Chart](https://api.star-history.com/svg?repos=chenzhanxu/chen-dynasty&type=Date)](https://star-history.com/#chenzhanxu/chen-dynasty&Date) --- **Made with ❤️ by [chenzhanxu](https://gitee.com/chenzhanxu)**