Chia sẻ Mã nguồn KMN Crowdfunding - Nền tảng Gọi vốn Cộng đồng

Giới thiệu chung
Chia sẻ tới mọi người mã nguồn đầy đủ KMN Crowdfunding - một nền tảng gọi vốn cộng đồng (crowdfunding) dành cho những người sáng tạo tại Việt Nam, giúp các ý tưởng, sản phẩm và dự án mới tìm được những người ủng hộ đầu tiên (mô hình tương tự Kickstarter thu nhỏ). Đây là dự án full stack chuẩn 3 lớp: Backend Spring Boot xử lý nghiệp vụ và bảo mật, Frontend Vue 3 render giao diện SPA, và MySQL 8 lưu trữ dữ liệu - toàn bộ được đóng gói sẵn bằng Docker Compose nên chỉ cần một lệnh duy nhất là dựng được cả hệ thống.
Điểm đặc biệt của source này là hỗ trợ song ngữ Việt/Anh (i18n) ở cả hai tầng: giao diện chuyển ngữ qua vue-i18n, còn dữ liệu nghiệp vụ (tiêu đề chiến dịch, mô tả, câu hỏi thường gặp, nội dung cập nhật tiến độ...) được lưu song song hai cột *_vi / *_en ngay trong database, tự động fallback sang ngôn ngữ còn lại nếu một bên thiếu dữ liệu.
Gói chia sẻ gồm đầy đủ:
Toàn bộ source code backend (Java 8 + Spring Boot 2.3.3) và frontend (Vue 3 + Vite 2 + TypeScript)
Script SQL khởi tạo database kmn_v2 (schema + dữ liệu mẫu song ngữ, 3 tài khoản demo dùng ngay)
docker-compose.yml dựng toàn bộ 3 container (MySQL, Backend, Frontend) chỉ bằng 1 lệnh duy nhất
Swagger UI tích hợp sẵn để tự khám phá và test toàn bộ REST API
README song ngữ Việt/Anh hướng dẫn cài đặt chi tiết
Demo giao diện
Toàn bộ ảnh chụp màn hình dưới đây lấy trực tiếp từ thư mục doc/imgs của source gốc.
Trang chủ

Thông tin chi tiết chiến dịch

Bắt đầu khởi tạo chiến dịch (bước 1)

Soạn nội dung chiến dịch (video/ảnh/câu chuyện/FAQ)

Thiết lập cấp độ phần thưởng (Perk)

Thiết lập mục tiêu gọi vốn

Hoàn tất khởi tạo chiến dịch

Trang cá nhân người dùng

Danh sách chiến dịch của tôi

Lịch sử ủng hộ

Cập nhật tiến độ chiến dịch (Journal)

Trang chủ - giao diện di động

Mô hình hoạt động và Kiến trúc hệ thống
Hệ thống theo mô hình 3 tầng cổ điển (Client - Server - Database), tách biệt hoàn toàn frontend và backend qua REST API, giao tiếp bằng JSON:
Trình duyệt (Vue 3 SPA, Nginx :5173)
| gọi API qua Axios (HTTP/JSON, kèm JWT Bearer token)
v
Backend REST API (Spring Boot, :8088/api/v1/*)
- Spring Security + JWT Filter Chain (xác thực/phân quyền COMMON, ADMIN)
- Controller -> Service -> Repository (Spring Data JPA)
- ModelMapper (Entity - DTO), Swagger/Springfox tự sinh tài liệu API
v
MySQL 8.0 (database kmn_v2) - import tự động từ doc/init.sql khi container khởi chạy lần đầu
Ba container Docker (tiền tố KMN_V2_) khởi động theo đúng thứ tự phụ thuộc: MySQL healthy -> Backend -> Frontend, đảm bảo backend không kết nối database khi chưa sẵn sàng.
Luồng xác thực (Authentication Flow)
Đăng nhập qua POST /api/v1/user/login - được xử lý ngầm bởi Spring Security Filter (ApiJWTAuthenticationFilter), không chạy qua code controller thông thường
Xác thực thành công trả về JWT token, được lưu phía client và đính kèm header Authorization ở các request tiếp theo
ApiJWTAuthorizationFilter kiểm tra và giải mã token ở mỗi request để xác lập quyền truy cập theo vai trò (ADMIN / COMMON) thông qua annotation @PreAuthorize
CustomUserDetailsService nạp thông tin người dùng từ DB; CustomAuthenticationSuccessHandler/FailureHandler xử lý phản hồi JSON tùy biến khi đăng nhập thành công/thất bại
Mô hình dữ liệu (Domain Model)
9 entity nghiệp vụ chính, quan hệ xoay quanh CampaignIntro (chiến dịch) và CampaignDetail (nội dung chi tiết chiến dịch):
Entity | Vai trò | Trường / quan hệ đáng chú ý |
|---|---|---|
User | Người dùng hệ thống | username, email, password, avatar, role (ADMIN/COMMON), danh sách chiến dịch đã tạo, danh sách đơn ủng hộ |
CampaignIntro | Thông tin giới thiệu chiến dịch | titleVi/titleEn, descriptionVi/En, locationVi/En, totalMoney, currentMoney, endTime, category, owner (User) |
CampaignDetail | Nội dung chi tiết 1-1 với CampaignIntro | danh sách Asset, Faq, Perk, Journal, PayOrder |
Category | Danh mục chiến dịch | nameVi/En, icon, descriptionVi/En, orderNum |
Perk | Cấp độ phần thưởng cho người ủng hộ | titleVi/En, price, posterImg, danh sách PayOrder |
PayOrder | Đơn ủng hộ / thanh toán | owner (User), perk (Perk), campaignDetail |
Asset | Tài nguyên media của chiến dịch | url, assetType (VIDEO/IMAGE) |
Journal | Bản tin cập nhật tiến độ / câu chuyện | titleVi/En, contentVi/En, journalType (JOURNAL/STORY), posterImg |
Faq | Câu hỏi thường gặp | questionVi/En, answerVi/En |
Chức năng chi tiết
Dành cho người dùng (COMMON)
Đăng nhập / Đăng ký - xác thực bằng JWT (Spring Security), lưu phiên đăng nhập phía client
Khởi tạo chiến dịch theo quy trình 5 bước: (1) thông tin cơ bản, (2) nội dung (video/ảnh/câu chuyện/FAQ), (3) thiết lập phần thưởng (Perk), (4) mục tiêu gọi vốn, (5) hoàn tất và xuất bản
Khám phá và tìm kiếm chiến dịch - lọc theo danh mục, trạng thái (đang diễn ra / đã kết thúc), tìm theo từ khóa
Ủng hộ chiến dịch - chọn Perk, tạo đơn ủng hộ (PayOrder), xem lại lịch sử ủng hộ tại trang cá nhân
Trang cá nhân - quản lý hồ sơ, đổi mật khẩu (buộc đăng xuất sau khi đổi), xem danh sách chiến dịch đã tạo, upload ảnh đại diện
Cập nhật tiến độ chiến dịch (Journal) - chủ chiến dịch đăng bản tin cập nhật cho người ủng hộ theo dõi
Song ngữ Việt/Anh - chuyển đổi ngay trên thanh điều hướng, lựa chọn lưu vào localStorage
Dành cho quản trị viên (ADMIN)
Trang quản trị riêng tại /admin
Quản lý người dùng: tra cứu, cập nhật, xoá tài khoản
Quản lý danh mục (Category) chiến dịch
Hạ tầng / DevOps
Docker hóa toàn bộ 3 service, build image backend bằng Maven + JDK 8, frontend bằng Node 18 + Nginx
Tự động import dữ liệu mẫu từ doc/init.sql vào MySQL trong lần chạy đầu tiên
Swagger UI tự sinh tài liệu và cho phép test trực tiếp toàn bộ API tại /swagger-ui/index.html
Danh sách API (REST Endpoints)
Toàn bộ API có tiền tố /api/v1, trả JSON, hầu hết yêu cầu JWT Bearer Token (trừ vài API public như đăng nhập/đăng ký/xem chiến dịch). Trích xuất trực tiếp từ 9 Controller trong source:
1. UserController - /api/v1/user
Method | Endpoint | Quyền | Chức năng |
|---|---|---|---|
POST | /login | Public | Đăng nhập, xử lý bởi Spring Security Filter, trả về JWT |
POST | /logout | Authenticated | Đăng xuất |
POST | /signup | Public | Đăng ký tài khoản mới |
GET | /profile | Authenticated | Lấy thông tin hồ sơ người dùng hiện tại |
POST | /profile | Authenticated | Cập nhật hồ sơ cá nhân |
POST | /password | Authenticated | Đổi mật khẩu (tự động huỷ session sau khi đổi) |
POST | /remove | ADMIN | Xoá người dùng theo danh sách ID |
POST | /query | ADMIN | Tìm kiếm/phân trang danh sách người dùng |
POST | /update | ADMIN | Cập nhật thông tin người dùng (admin thao tác) |
2. CampaignIntroController - /api/v1/campaignIntro
Method | Endpoint | Quyền | Chức năng |
|---|---|---|---|
POST | /save | COMMON | Tạo mới chiến dịch (bước khởi tạo) |
POST | /update | COMMON | Cập nhật thông tin giới thiệu chiến dịch |
POST | /remove | COMMON | Xoá chiến dịch |
POST | /query | Public | Tìm kiếm/phân trang danh sách chiến dịch (trang khám phá, trang chủ) |
POST | /me | Authenticated | Lấy danh sách chiến dịch của người dùng hiện tại |
3. CampaignDetailController - /api/v1/campaignDetail
Method | Endpoint | Quyền | Chức năng |
|---|---|---|---|
POST | /save | COMMON | Tạo nội dung chi tiết chiến dịch |
POST | /update | COMMON | Cập nhật nội dung chi tiết |
POST | /remove | COMMON | Xoá nội dung chi tiết |
POST | /query | Public | Tìm kiếm/phân trang |
POST | /{id} | Public | Lấy toàn bộ dữ liệu chi tiết 1 chiến dịch theo ID (dùng cho trang xem chiến dịch) |
4. PerkController (/api/v1/perk), 5. FaqController (/api/v1/faq), 6. JournalController (/api/v1/journal), 7. AssetController (/api/v1/asset)
Bốn controller này có cấu trúc CRUD giống nhau (quyền COMMON cho thao tác ghi):
Method | Endpoint | Quyền | Chức năng |
|---|---|---|---|
POST | /save | COMMON | Thêm mới bản ghi (phần thưởng / FAQ / bản tin / tài nguyên media) |
POST | /update | COMMON | Cập nhật bản ghi |
POST | /remove | COMMON | Xoá bản ghi (theo mảng ID) |
POST | /query | Public | Tìm kiếm/phân trang |
Riêng JournalController có thêm POST /{id} để lấy chi tiết một bản tin cập nhật theo ID.
8. PayOrderController - /api/v1/payOrder
Method | Endpoint | Quyền | Chức năng |
|---|---|---|---|
POST | /save | COMMON | Tạo đơn ủng hộ chiến dịch (chọn Perk) |
POST | /update | COMMON | Cập nhật đơn ủng hộ |
POST | /remove | COMMON | Xoá đơn ủng hộ |
POST | /query | Public | Tìm kiếm/phân trang - dùng cho "Lịch sử ủng hộ" |
9. CategoryController - /api/v1/category
Method | Endpoint | Quyền | Chức năng |
|---|---|---|---|
POST | /save | COMMON | Tạo danh mục chiến dịch mới (Admin dùng) |
POST | /update | COMMON | Cập nhật danh mục |
POST | /remove | COMMON | Xoá danh mục |
POST | /query | Public | Lấy danh sách danh mục (hiển thị trang chủ, bộ lọc khám phá) |
10. FileController - /api/v1/file
Method | Endpoint | Quyền | Chức năng |
|---|---|---|---|
POST | /upload | Authenticated | Upload nhiều file cùng lúc (ảnh đại diện, ảnh/video chiến dịch, poster Perk...) |
Mẹo: Toàn bộ danh sách API trên đều có thể xem trực quan và test thử ngay trên trình duyệt qua Swagger UI tại http://localhost:8088/swagger-ui/index.html sau khi chạy Docker - không cần Postman.
Công nghệ sử dụng
Thành phần | Công nghệ |
|---|---|
Backend | Spring Boot 2.3.3, Spring Security, Spring Data JPA, JJWT, Springfox (Swagger 2), ModelMapper |
Ngôn ngữ backend | Java 8 |
Frontend | Vue 3, Vite 2, TypeScript, Naive UI, Pinia, Vue Router, vue-i18n |
Cơ sở dữ liệu | MySQL 8.0 |
Đóng gói / triển khai | Docker, Docker Compose, Nginx (phục vụ frontend) |
Tài khoản demo có sẵn
Tất cả tài khoản mẫu dùng chung mật khẩu 123456:
Tên đăng nhập | Mật khẩu | Vai trò | Ghi chú |
|---|---|---|---|
minhnhut | 123456 | COMMON | Người dùng thường, đã tạo sẵn 3 chiến dịch mẫu |
lananh | 123456 | COMMON | Người dùng thường |
admin | 123456 | ADMIN | Truy cập trang quản trị tại /admin |
Chạy thử chỉ với 1 lệnh (Docker)
Không cần cài Java, Node hay MySQL trên máy - toàn bộ được build và chạy trong container. Chỉ cần Docker và Docker Compose:
docker compose up -d --build
Lệnh này sẽ:
Build image cho backend (Maven + JDK 8) và frontend (Node 18 + Nginx)
Khởi tạo container MySQL và tự động import dữ liệu mẫu từ doc/init.sql trong lần chạy đầu tiên
Khởi động cả 3 container theo đúng thứ tự (MySQL healthy -> Backend -> Frontend)
Theo dõi tiến trình build/chạy bằng:
docker compose logs -f
Dừng ứng dụng (giữ lại dữ liệu):
docker compose down
Reset toàn bộ dữ liệu (xoá volume, lần up kế tiếp import lại init.sql từ đầu):
docker compose down -v
Địa chỉ dịch vụ sau khi chạy
Dịch vụ | Địa chỉ |
|---|---|
Frontend (giao diện người dùng) | http://localhost:5173 |
Backend REST API | http://localhost:8088/api/v1/ |
Swagger UI (tài liệu API) | http://localhost:8088/swagger-ui/index.html |
MySQL | localhost:3306, database kmn_v2 |
Chạy không dùng Docker (chế độ phát triển)
Backend: cài MySQL, tạo database kmn_v2 rồi import doc/init.sql; mở thư mục backend bằng IntelliJ IDEA để tải dependency qua Maven; cấu hình kết nối trong application.properties (mặc định localhost:3306, user root); chạy class WeiChouApplication - backend khởi động tại http://localhost:8088.
Frontend:
cd frontend
npm install
npm run dev
Frontend chạy tại http://localhost:3000, gọi API tới địa chỉ khai báo trong biến VITE_AXIOS_URL ở file frontend/.env.
Tuỳ chọn: tạo file .env từ .env.example để đổi mật khẩu MySQL root và khoá bí mật JWT trước khi triển khai thật (production).
Cấu trúc thư mục dự án
.
├── backend/ # Spring Boot REST API
│ ├── src/main/java # Entity, DTO, Controller, Service, Security...
│ └── src/main/resources/application.properties
├── frontend/ # Vue 3 SPA
│ └── src/
│ ├── pages/ # Trang theo file-based routing (vite-plugin-pages)
│ ├── layouts/ # Header, Footer, layout khung trang
│ ├── locales/ # File dịch vi.ts / en.ts (vue-i18n)
│ ├── composables/ # useLocalizedField (chọn field song ngữ theo locale)
│ └── service/ # Lớp gọi API (axios)
├── doc/
│ ├── init.sql # Schema + dữ liệu mẫu song ngữ, tự import khi chạy Docker
│ └── imgs/ # Ảnh chụp màn hình
├── docker-compose.yml
├── backend/Dockerfile
├── frontend/Dockerfile
└── .env.example
Nội dung tải về
Full source code (backend Spring Boot + frontend Vue 3)
Script SQL khởi tạo (schema + dữ liệu mẫu song ngữ + 3 tài khoản demo)
docker-compose.yml + Dockerfile cho cả backend và frontend
README song ngữ Việt/Anh hướng dẫn cài đặt/chạy chi tiết
Lời kết
KMN Crowdfunding là một mã nguồn full stack gọn gàng, phù hợp để tham khảo cách triển khai REST API chuẩn CRUD với Spring Boot + Spring Security JWT, cách tổ chức Vue 3 SPA theo file-based routing, và đặc biệt là cách xử lý đa ngôn ngữ ở tầng dữ liệu (không chỉ dịch giao diện mà lưu song song 2 ngôn ngữ trong DB). Source đã Docker hoá sẵn nên chỉ cần Docker là chạy được ngay, không lo lỗi môi trường.