ngthanhvu 262836b75e refactor: update border colors and improve styling in thanh-vien.vue
- Changed border color classes for better visibility and consistency.
- Adjusted hover effects for table rows to enhance user experience.
- Modified gradient class for member initials for improved aesthetics.
- Updated select input styles for better alignment with design guidelines.
2026-08-05 05:46:40 -04:00
2026-05-17 18:42:09 +07:00
2026-05-17 18:42:09 +07:00

CineK

CineK là website xem phim Hàn Quốc online với giao diện dark theme, hệ thống admin quản lý phim, đăng ký/đăng nhập thành viên, và đồng bộ dữ liệu từ nhiều nguồn API.

Tính năng

Người dùng

  • Trang chủ với hero carousel phim Hàn Quốc
  • Duyệt phim theo loại (phim bộ, phim lẻ), tìm kiếm, phân trang
  • Trang chi tiết phim với trình phát HLS + Nhúng
  • Đăng ký / Đăng nhập tài khoản thành viên (popup modal)
  • Lịch sử xem, danh sách phim yêu thích (lưu localStorage)

Admin (/admin)

  • Dashboard tổng quan (tổng phim, đang hiển thị, chưa hiển thị)
  • Đồng bộ phim từ API (chọn nguồn: OPhim, NguonC, KKPhim)
  • Bật/tắt hiển thị từng phim
  • Chỉnh sửa phim: mô tả, poster, thumbnail, tập phim tuỳ chỉnh
  • Quản lý thành viên: đổi role, bật/tắt, xoá tài khoản
  • Xoá toàn bộ phim
  • Phân quyền: chỉ role admin mới truy cập được

Tech Stack

  • Framework: Nuxt 4 (Vue 3)
  • Styling: Tailwind CSS 4
  • Database: MySQL 8.0 + Drizzle ORM
  • Cache: Redis 7
  • Auth: JWT (bcryptjs + jsonwebtoken)
  • Icons: Lucide Vue Next
  • Player: HLS.js
  • Container: Docker + Docker Compose

Cấu trúc thư mục

app/
  components/            Components dùng chung (AppHeader, AppLogo, AuthModal, AdminToggle...)
  composables/           Composables (useAuth, useMovieLibrary, useWatchHistory)
  layouts/
    admin.vue            Layout cho trang admin (sidebar + header)
  middleware/
    admin.global.ts      Middleware chặn route /admin/* nếu chưa đăng nhập admin
  pages/
    index.vue            Trang chủ
    phim/                Trang chi tiết phim
    xem/[slug].vue       Trang xem phim (player)
    thanh-vien.vue       Trang cá nhân thành viên
    yeu-thich.vue        Phim yêu thích
    lich-su.vue          Lịch sử xem
    dang-nhap.vue        Đăng nhập
    dang-ky.vue          Đăng ký
    admin/
      login.vue          Trang đăng nhập admin
      index.vue          Dashboard admin
      phim/index.vue     Quản lý phim
      phim/[id].vue      Chỉnh sửa phim
      thanh-vien.vue     Quản lý thành viên
      cai-dat.vue        Cài đặt hệ thống

server/
  api/
    movies.get.ts        API danh sách phim công khai (chỉ phim active)
    movies/[slug].get.ts API chi tiết phim công khai
    auth/                API xác thực (register, login, logout, me)
    admin/               API admin (sync, movies, thanh-vien, stats)
  database/
    schema.ts            Schema Drizzle (bảng users, movies)
    migrations/          File migration SQL
  middleware/
    auth.ts              Middleware chặn /api/admin/* nếu chưa đăng nhập admin
  utils/
    auth.ts              Tiện ích auth (hash password, JWT sign/verify)
    db.ts                Kết nối MySQL
    redis.ts             Kết nối Redis
    movies.ts            Adapter API phim + chuẩn hoá dữ liệu

Setup & Chạy dự án

Yêu cầu

  • Docker & Docker Compose
  • Node.js 22+ (nếu chạy ngoài Docker)

1. Clone & cài dependencies

git clone <repo-url>
cd kr-phim
npm install

2. Cấu hình biến môi trường

Tạo file .env:

DATABASE_URL=mysql://cinek:cinekpassword@localhost:3306/cinek
REDIS_URL=redis://localhost:6379
JWT_SECRET=your-secret-key-change-this

3. Chạy MySQL & Redis

# Chỉ bật MySQL và Redis
docker compose up -d mysql redis

Hoặc chạy tất cả (app + mysql + redis):

docker compose up -d

Thông tin kết nối mặc định

Service Host Port User Password Database
MySQL localhost 3306 cinek cinekpassword cinek
MySQL localhost 3306 root rootpassword -
Redis localhost 6379 - - -
App localhost 3002 - - -

4. Tạo bảng database (migration)

# Tạo file migration từ schema
npx drizzle-kit generate

# Áp dụng migration vào MySQL
npx drizzle-kit migrate

5. Chạy dev server

npm run dev

App chạy tại http://localhost:3002. Hot reload tự động khi sửa code.

6. Tạo tài khoản admin đầu tiên

Truy cập http://localhost:3002 → bấm Đăng nhập → chuyển sang tab Đăng ký.

Tài khoản đầu tiên đăng ký sẽ tự động được gán role admin.

Sau đó truy cập http://localhost:3002/admin để vào trang quản trị.

7. Đồng bộ phim

Vào Admin → Dashboard hoặc Admin → Phim → bấm Đồng bộ từ API.

Chọn nguồn muốn đồng bộ (OPhim, NguonC, KKPhim) → bấm Đồng bộ.

Mặc định phim mới đồng bộ sẽ ở trạng thái Ẩn. Bật từng phim để hiển thị ra trang công khai.

Docker

Dev mode (có hot reload)

docker compose up -d --build

File code được mount vào container qua volume, sửa file tự reload.

Production build

# Build image production
docker build -t cinek .

# Chạy
docker run -p 3002:3002 \
  -e DATABASE_URL=mysql://cinek:cinekpassword@host.docker.internal:3306/cinek \
  -e REDIS_URL=redis://host.docker.internal:6379 \
  cinek

Dừng & xoá containers

docker compose down          # Dừng containers
docker compose down -v       # Dừng + xoá volumes (mất dữ liệu MySQL/Redis)

Database

Schema

Bảng users:

Cột Kiểu Mô tả
id INT (PK) Tự tăng
name VARCHAR(200) Tên hiển thị
email VARCHAR(255) Email (unique)
password VARCHAR(255) Mật khẩu (bcrypt hash)
role VARCHAR(50) admin / moderator / user
avatar TEXT URL ảnh đại diện
active BOOLEAN Trạng thái tài khoản
created_at TIMESTAMP Ngày tạo
updated_at TIMESTAMP Ngày cập nhật

Bảng movies:

Cột Kiểu Mô tả
id INT (PK) Tự tăng
source VARCHAR(50) Nguồn (ophim/nguonc/kkphim)
slug VARCHAR(500) Slug phim trên nguồn
name VARCHAR(500) Tên phim
origin_name VARCHAR(500) Tên gốc
thumb/poster TEXT URL ảnh
year INT Năm sản xuất
active BOOLEAN Hiển thị trên web công khai
custom_poster TEXT Poster admin tuỳ chỉnh
custom_thumb TEXT Thumbnail admin tuỳ chỉnh
custom_content TEXT Mô tả admin tuỳ chỉnh
custom_episodes JSON Tập phim admin tuỳ chỉnh
api_updated_at TIMESTAMP Thời gian API nguồn cập nhật
synced_at TIMESTAMP Thời gian đồng bộ vào DB

Migration

# Tạo migration mới (sau khi sửa schema.ts)
npx drizzle-kit generate

# Áp dụng migration
npx drizzle-kit migrate

Kết nối MySQL trực tiếp

# Qua Docker
docker exec -it cinek-mysql mysql -ucinek -pcinekpassword cinek

# Hoặc từ host
mysql -h 127.0.0.1 -P 3306 -ucinek -pcinekpassword cinek

Kết nối Redis trực tiếp

docker exec -it cinek-redis redis-cli

API Endpoints

Công khai

Method Endpoint Mô tả
GET /api/movies Danh sách phim active (có cache)
GET /api/movies/[slug] Chi tiết phim active

Xác thực

Method Endpoint Mô tả
POST /api/auth/register Đăng ký (tài khoản đầu = admin)
POST /api/auth/login Đăng nhập (trả JWT + cookie)
POST /api/auth/logout Đăng xuất (xoá cookie)
GET /api/auth/me Thông tin user hiện tại

Admin (cần role admin)

Method Endpoint Mô tả
GET /api/admin/stats Thống kê tổng phim
POST /api/admin/sync Đồng bộ phim từ API nguồn
GET /api/admin/movies Danh sách tất cả phim
GET /api/admin/movies/:id Chi tiết 1 phim
PATCH /api/admin/movies/:id Bật/tắt phim
PUT /api/admin/movies/:id Cập nhật custom (poster, tập)
DELETE /api/admin/movies Xoá tất cả phim
GET /api/admin/thanh-vien Danh sách thành viên
PATCH /api/admin/thanh-vien/:id Đổi role / bật/tắt
DELETE /api/admin/thanh-vien/:id Xoá thành viên

Scripts

npm run dev          # Dev server (hot reload)
npm run build        # Build production
npm run preview      # Preview production build
npm run start        # Chạy production server
npm run db:generate  # Tạo migration từ schema
npm run db:migrate   # Áp dụng migration

Nguồn phim

Dữ liệu phim được lấy từ 3 API nguồn:

  • OPhim - https://ophim1.com
  • NguonC - https://phim.nguonc.com
  • KKPhim - https://phimapi.com

Chỉ lấy phim quốc gia Hàn Quốc. Dữ liệu bao gồm: tên phim, ảnh, thể loại, tập phim, link embed, link HLS.

S
Description
No description provided
Readme
4 MiB
Languages
Vue 74.7%
TypeScript 23.6%
CSS 1.7%