Đây là tài liệu hướng dẫn cài đặt, chạy và sử dụng các API của hệ thống backend.
- Yêu cầu hệ thống
- Cài đặt
- Thiết lập Cơ sở dữ liệu
- Tạo dữ liệu mẫu
- Chạy Server (hỗ trợ WebSocket realtime)
- WebSocket Thông báo realtime
- Danh sách API Endpoints
- Python 3.x
- pip (Trình quản lý gói của Python)
-
Clone repository về máy của bạn.
-
Di chuyển vào thư mục backend:
cd backend/salon -
(Khuyến nghị) Tạo và kích hoạt môi trường ảo:
# Tạo môi trường ảo (chỉ cần làm lần đầu) python -m venv venv # Kích hoạt môi trường ảo # Trên Windows .\venv\Scripts\activate # Trên macOS/Linux source venv/bin/activate
-
Cài đặt các dependencies cần thiết:
pip install -r requirements.txt
-
Cài đặt Daphne (nếu chưa có), cần cho WebSocket:
pip install daphne
- Đảm bảo bạn đang ở trong thư mục
backend/salonvà môi trường ảo đã được kích hoạt. - Tạo các migration scripts:
python manage.py makemigrations
- Áp dụng các migration để tạo bảng trong cơ sở dữ liệu:
python manage.py migrate
- (Tùy chọn) Tạo Superuser để truy cập trang admin:
Làm theo hướng dẫn trên màn hình.
python manage.py createsuperuser
Để điền dữ liệu giả vào database cho mục đích phát triển và thử nghiệm, bạn có thể sử dụng script tạo dữ liệu mẫu.
- (Nếu cần) Xóa cơ sở dữ liệu hiện tại (lưu ý: thao tác này sẽ xóa TOÀN BỘ dữ liệu):
# Đảm bảo bạn đang ở trong thư mục backend/salon # Trên Windows del db.sqlite3 # Trên macOS/Linux rm db.sqlite3
- Thực hiện lại bước 3. Thiết lập Cơ sở dữ liệu để tạo database rỗng mới.
- Chạy script tạo dữ liệu mẫu:
python create_sample_data.py
Sau khi chạy xong, database sẽ có dữ liệu mẫu cho các model như Khách hàng, Nhân viên, Dịch vụ, Lịch hẹn, Hóa đơn, Đánh giá, Thông báo.
Để chạy server với WebSocket realtime, bạn cần sử dụng Daphne:
- Đảm bảo bạn đang ở trong thư mục
backend/salonvà môi trường ảo đã được kích hoạt. - Chạy server bằng Daphne (mặc định cổng 8000):
Hoặc chỉ định cổng khác (ví dụ 8001):
daphne salon.asgi:application
daphne -p 8001 salon.asgi:application
Lưu ý quan trọng: KHÔNG dùng
python manage.py runservernếu bạn muốn sử dụng và kiểm thử chức năng WebSocket realtime, vìrunservermặc định không hỗ trợ ASGI.
Server sẽ chạy tại địa chỉ http://localhost:8000/ (hoặc cổng bạn đã chỉ định).
Backend hỗ trợ gửi thông báo realtime tới các client kết nối WebSocket.
- Endpoint:
ws://localhost:8000/ws/thongbao/(Thay 8000 bằng cổng bạn đang chạy server)
- Cách sử dụng:
- Client (frontend hoặc công cụ test như Postman/WebSocket client) kết nối tới endpoint trên.
- Khi có các sự kiện như đặt lịch hẹn mới, huỷ lịch hẹn, hoặc đánh giá mới, server sẽ gửi thông báo qua kết nối WebSocket tới tất cả các client đang kết nối.
- Định dạng thông báo nhận được:
{ "message": "Nội dung thông báo tiếng Việt có dấu và emoji ⭐" } - Thông báo được mã hóa UTF-8.
Dưới đây là danh sách các API endpoint chính mà backend cung cấp. Các API tuân thủ chuẩn RESTful.
Lưu ý: Hầu hết các API yêu cầu xác thực. Vui lòng đảm bảo bạn đã đăng nhập và gửi kèm token xác thực trong header (ví dụ: Authorization: Bearer <your_token>) trừ các endpoint đăng ký/đăng nhập.
POST /api/tai-khoan/dang-ky/: Đăng ký tài khoản mới.- Body:
{"username": "user1", "sdt": "0123456789", "password": "123456"} - Tạo user và KhachHang với thông tin ban đầu.
- Body:
POST /api/tai-khoan/dang-nhap/: Đăng nhập và nhận token.- Body:
{"username": "user1", "password": "123456"}
- Body:
POST /api/tai-khoan/doi-mat-khau/: Đổi mật khẩu tài khoản hiện tại.- Body:
{"old_password": "123456", "new_password": "654321"}
- Body:
GET /api/tai-khoan/profile/: Lấy thông tin profile của tài khoản hiện tại.PUT /api/tai-khoan/profile/: Cập nhật thông tin profile.- Body ví dụ:
{"email": "user1@example.com", "first_name": "A", "last_name": "B"}
- Body ví dụ:
GET /api/tai-khoan/dashboard-revenue/: Thống kê doanh thu.GET /api/tai-khoan/dashboard-top-services/: Top dịch vụ.GET /api/tai-khoan/dashboard-appointments/: Thống kê lịch hẹn.GET /api/tai-khoan/dashboard-revenue-by-month/: Doanh thu theo tháng.
GET /api/khach-hang/: Lấy danh sách khách hàng.POST /api/khach-hang/: Thêm khách hàng mới.- Body:
{"user": {"username": "kh1", "password": "123456"}, "HoTenKH": "Nguyễn Văn A", "SDT": "0123456789", "Email": "kh1@example.com", "DiaChi": "Hà Nội"}
- Body:
GET /api/khach-hang/{MaKH}/: Xem chi tiết khách hàng theo ID.PUT /api/khach-hang/{MaKH}/: Sửa thông tin khách hàng theo ID.- Body ví dụ:
{"HoTenKH": "Nguyễn Văn A", "SDT": "0123456789", "Email": "kh1@example.com", "DiaChi": "Hà Nội"}
- Body ví dụ:
DELETE /api/khach-hang/{MaKH}/: Xóa khách hàng theo ID.
GET /api/nhan-vien/: Lấy danh sách nhân viên.POST /api/nhan-vien/: Thêm nhân viên mới.- Body:
{"user": {"username": "nv1", "email": "nv1@example.com", "password": "123456"}, "HoTenNV": "Trần Văn B", "SDT": "0987654321", "DiaChi": "Hà Nội", "GioiTinh": "Nam"}
- Body:
GET /api/nhan-vien/{MaNV}/: Xem chi tiết nhân viên theo ID.PUT /api/nhan-vien/{MaNV}/: Sửa thông tin nhân viên theo ID.DELETE /api/nhan-vien/{MaNV}/: Xóa nhân viên theo ID.
GET /api/nhan-vien/lich-lam-viec/: Lấy danh sách lịch làm việc.POST /api/nhan-vien/lich-lam-viec/: Thêm lịch làm việc mới.- Body:
{"MaNV": 1, "NgayLam": "2024-06-01", "GioBatDau": "8:00", "GioKetThuc": "12:00"}
- Body:
GET /api/nhan-vien/lich-lam-viec/{MaLLV}/: Xem chi tiết lịch làm việc theo ID.PUT /api/nhan-vien/lich-lam-viec/{MaLLV}/: Sửa lịch làm việc theo ID.DELETE /api/nhan-vien/lich-lam-viec/{MaLLV}/: Xóa lịch làm việc theo ID.
GET /api/dich-vu/: Lấy danh sách dịch vụ.POST /api/dich-vu/: Thêm dịch vụ mới.- Body:
{"TenDV": "Cắt tóc", "MoTa": "Cắt tóc nam", "GiaTien": 100000, "ThoiGianLamDV": 30}
- Body:
GET /api/dich-vu/{MaDV}/: Xem chi tiết dịch vụ theo ID.PUT /api/dich-vu/{MaDV}/: Sửa thông tin dịch vụ theo ID.DELETE /api/dich-vu/{MaDV}/: Xóa dịch vụ theo ID.GET /api/dich-vu/dichvu_kem_danhgia/: Lấy danh sách dịch vụ kèm danh sách đánh giá liên quan.
GET /api/hoa-don/: Lấy danh sách hóa đơn.POST /api/hoa-don/: Thêm hóa đơn mới (kèm chi tiết hóa đơn).- Body:
{"MaKH": 1, "TongTien": 300000, "TrangThaiTT": "Đã thanh toán", "GhiChu": "Khách thanh toán tiền mặt", "chi_tiet": [{"MaDV": 2, "ThanhTien": 200000, "SoLuong": 1}, {"MaDV": 3, "ThanhTien": 100000, "SoLuong": 1}]}
- Body:
GET /api/hoa-don/{id}/: Xem chi tiết hóa đơn theo ID.PUT /api/hoa-don/{id}/: Sửa hóa đơn theo ID.DELETE /api/hoa-don/{id}/: Xóa hóa đơn theo ID.
GET /api/lich-hen/: Lấy danh sách lịch hẹn.POST /api/lich-hen/: Thêm lịch hẹn mới.- Body:
{"MaKH": 1, "MaDV": 2, "NgayDatLich": "2024-06-01", "GioDatLich": "09:00:00", "TrangThai": "Chờ xác nhận"}
- Body:
GET /api/lich-hen/{MaLH}/: Xem chi tiết lịch hẹn theo ID.PUT /api/lich-hen/{MaLH}/: Sửa lịch hẹn theo ID.DELETE /api/lich-hen/{MaLH}/: Xóa lịch hẹn theo ID.
GET /api/thong-bao/: Lấy danh sách thông báo.POST /api/thong-bao/: Thêm thông báo mới.- Body:
{"MaNV": 1, "LoaiThongBao": "Khuyến mãi", "NoiDung": "Giảm giá 50% cho dịch vụ mới"}
- Body:
GET /api/thong-bao/{MaTB}/: Xem chi tiết thông báo theo ID.PUT /api/thong-bao/{MaTB}/: Sửa thông báo theo ID. (Có thể dùng để cập nhậtLoaiThongBaokhi đọc)DELETE /api/thong-bao/{MaTB}/: Xóa thông báo theo ID.
GET /api/danh-gia/: Lấy danh sách đánh giá.POST /api/danh-gia/: Thêm đánh giá mới.- Body:
{"MaKH": 1, "NoiDung": "Rất hài lòng!", "DiemDanhGia": 5, "MaDV": 1, "MaHD": 3}
- Body:
GET /api/danh-gia/{MaDG}/: Xem chi tiết đánh giá theo ID.PUT /api/danh-gia/{MaDG}/: Sửa đánh giá theo ID.DELETE /api/danh-gia/{MaDG}/: Xóa đánh giá theo ID.