Giao diện POS (Renderer)
1. Kiểm soát Tài liệu
| Thuộc tính | Giá trị |
|---|---|
| Gói | @nx-app/sale-renderer |
| Phiên bản | 0.0.0 |
| Loại | Ứng dụng Web (SPA) |
| Runtime | Tauri WebView / Trình duyệt |
| Framework | React 19 + Vite 7 |
2. Phạm vi & Mục tiêu
2.1. Phạm vi
Giao diện POS là lớp hình ảnh và tương tác của hệ thống Điểm bán hàng. Nó chạy bên trong WebView được cung cấp bởi tiến trình host Tauri (sale-main) và xử lý tất cả các tương tác của người dùng, luồng nghiệp vụ và phản hồi hình ảnh.
2.2. Mục tiêu
- Tối ưu hóa Cảm ứng: Các phần tử giao diện có kích thước phù hợp cho tương tác chạm (mục tiêu tối thiểu 44px).
- Tốc độ: Phản hồi tức thì cho các thao tác giỏ hàng.
- Rõ ràng: Thiết kế độ tương phản cao cho các điều kiện ánh sáng khác nhau.
- Hỗ trợ Ngoại tuyến: Các tính năng cốt lõi hoạt động không cần mạng.
- Cập nhật Thời gian thực: Tích hợp WebSocket cho trạng thái đơn hàng.
3. Ngăn xếp Công nghệ
3.1. Framework Cốt lõi
| Công nghệ | Phiên bản | Mục đích |
|---|---|---|
| React | ^19.2.0 | Thư viện Thành phần UI |
| React DOM | ^19.2.0 | Kết xuất DOM |
| React Router | ^7.11.0 | Định tuyến phía Client |
| TypeScript | ~5.9.3 | An toàn kiểu dữ liệu |
3.2. Quản lý Trạng thái
| Công nghệ | Phiên bản | Mục đích |
|---|---|---|
| Redux Toolkit | ^2.11.2 | Quản lý Trạng thái Toàn cục |
| React Redux | ^9.2.0 | Liên kết React-Redux |
| TanStack Query | ^5.90.12 | Trạng thái Server & Caching |
| ra-core | ^5.13.4 | Lõi Framework Admin |
3.3. Thành phần UI
| Công nghệ | Phiên bản | Mục đích |
|---|---|---|
| Radix UI | Various | Các thành phần cơ sở dễ tiếp cận |
| Tailwind CSS | ^4.1.18 | Utility-first Styling |
| Lucide React | ^0.562.0 | Thư viện Biểu tượng |
| shadcn | ^3.6.2 | Mẫu Thành phần |
| cmdk | ^1.1.1 | Bảng lệnh |
| vaul | ^1.1.2 | Thành phần Ngăn kéo |
| sonner | ^2.0.7 | Thông báo Toast |
3.4. Tích hợp Tauri
| Công nghệ | Phiên bản | Mục đích |
|---|---|---|
| @tauri-apps/api | ^2.9.1 | Giao tiếp IPC |
| @tauri-apps/plugin-os | ^2.3.2 | Thông tin Hệ điều hành |
| @skipperndt/plugin-machine-uid | ^0.1.3 | Nhận dạng Thiết bị |
3.5. Biểu mẫu & Xác thực
| Công nghệ | Phiên bản | Mục đích |
|---|---|---|
| React Hook Form | ^7.69.0 | Quản lý Trạng thái Biểu mẫu |
| @hookform/resolvers | ^5.2.2 | Tích hợp Schema |
| Zod | ^4.2.1 | Xác thực thời gian chạy |
3.6. Trực quan hóa Dữ liệu
| Công nghệ | Phiên bản | Mục đích |
|---|---|---|
| Recharts | 2.15.4 | Biểu đồ & Đồ thị |
| react-qr-code | ^2.0.18 | Tạo Mã QR |
| react-day-picker | ^9.13.0 | Chọn ngày |
3.7. Giao tiếp Thời gian thực
| Công nghệ | Phiên bản | Mục đích |
|---|---|---|
| socket.io-client | ^4.8.3 | Giao tiếp WebSocket |
| RxJS | ^7.8.2 | Reactive Streams |
3.8. Bố cục & Tương tác
| Công nghệ | Phiên bản | Mục đích |
|---|---|---|
| react-grid-layout | ^2.2.2 | Bố cục Dashboard |
| react-resizable | ^3.1.3 | Bảng có thể thay đổi kích thước |
| react-virtuoso | ^4.17.0 | Danh sách ảo hóa |
| @tanstack/react-virtual | ^3.13.13 | Cuộn ảo |
3.9. Build & Phát triển
| Công nghệ | Phiên bản | Mục đích |
|---|---|---|
| Vite | ^7.2.4 | Công cụ Build |
| @vitejs/plugin-react | ^5.1.1 | Tích hợp React |
| lightningcss | ^1.30.2 | Xử lý CSS |
| ESLint | ^9.39.1 | Kiểm tra lỗi mã nguồn |
| Prettier | 3.6.2 | Định dạng mã nguồn |
4. Kiến trúc
4.1. Các lớp Ứng dụng
Người dùng Chạm
→
React UI
→
Dịch vụ IPC
→
Tauri Backend
4.2. Giao tiếp IPC
Renderer giao tiếp với Tauri backend thông qua một dịch vụ IPC tùy chỉnh:
typescript
export class IpcRendererService {
async invoke<TPayload, TResponse>(opts: {
command: string;
payload: TPayload;
}): Promise<TResponse> {
const res = await invoke(command, { payload });
return { data: res } as TResponse;
}
}4.3. Mẫu Data Provider
Sử dụng TauriIpcDataProvider tùy chỉnh mở rộng mẫu REST provider:
typescript
export class TauriIpcDataProvider extends DefaultRestDataProvider {
override send<TResponse>(opts: {
resource: string;
params: ISendParams;
}): Promise<ISendResponse<TResponse>> {
return ipcService.invoke({
command: resource,
payload: params,
});
}
}5. Cấu trúc Dự án
apps/sale-renderer/
├── src/
│ ├── application/ # DI Container & Providers
│ │ ├── decorators/ # Decorator tùy chỉnh
│ │ ├── providers/ # Auth & IPC Providers
│ │ │ ├── auth.provider.ts # Provider xác thực
│ │ │ └── ipc-data.provider.ts # Tauri IPC data provider
│ │ └── services/ # Dịch vụ API
│ │ ├── apis/ # Domain API Clients (15 files)
│ │ ├── environment.service.ts
│ │ └── ipc.service.ts # Tauri IPC wrapper
│ ├── components/ # Thành phần UI tái sử dụng
│ │ └── ui/ # Thành phần shadcn/ui
│ ├── constants/ # Hằng số Ứng dụng
│ ├── helpers/ # Các hàm Tiện ích
│ ├── hooks/ # React Hooks tùy chỉnh
│ ├── interfaces/ # Giao diện TypeScript
│ ├── layout/ # Thành phần Bố cục
│ ├── libs/ # Cấu hình Thư viện ngoài
│ ├── redux/ # Redux Store
│ │ └── slices/ # Redux Slices (8 slices)
│ ├── screens/ # Thành phần Màn hình (8 modules)
│ └── socket/ # Tích hợp WebSocket
│ ├── client/ # Socket client
│ └── server/ # Socket server handlers
├── scripts/ # Script Build
└── public/ # Tài sản Tĩnh6. Màn hình & Định tuyến
6.1. Module Màn hình
| Module | Đường dẫn | Mô tả |
|---|---|---|
| home | / | Dashboard với widget và thống kê |
| sale | /sale | Giao diện POS chính với giỏ hàng |
| customer | /customer | Quản lý khách hàng |
| settings | /settings | Cài đặt ứng dụng |
| sign-in | /sign-in | Xác thực |
| errors | /401, /403, /404 | Trang lỗi |
6.2. Thành phần Màn hình Bán hàng
Màn hình bán hàng là giao diện chính với các thành phần con phức tạp:
screens/sale/
├── index.tsx # Màn hình bán hàng chính
├── fnb/ # Danh mục Thực phẩm & Đồ uống
│ ├── category/ # Điều hướng danh mục
│ └── product-variant/ # Lựa chọn biến thể sản phẩm
├── cart/ # Giỏ hàng mua sắm
│ ├── items/ # Danh sách mục giỏ hàng
│ │ ├── header/ # Tiêu đề giỏ hàng
│ │ └── item/ # Mục riêng lẻ
│ ├── detail/ # Xem chi tiết giỏ hàng
│ └── summary/ # Tóm tắt giỏ hàng
│ ├── details/ # Chi tiết giá
│ └── actions/ # Các hành động giỏ hàng
│ ├── order-checkout/ # Nút thanh toán
│ └── payment-dialog/ # Modal thanh toán
│ ├── order-detail/ # Tóm tắt đơn hàng
│ └── stepper/ # Các bước thanh toán
│ ├── methods/ # Phương thức thanh toán
│ └── actions/ # Hành động từng bước
└── manual-form/ # Form nhập thủ công7. Quản lý Trạng thái
7.1. Cấu hình Redux Store
typescript
const appReducer = combineReducers({
temporary: temporaryReducer,
common: commonReducer,
userProfile: userProfileReducer,
order: orderReducer,
sale: saleReducer,
cart: cartReducer,
product: productReducer,
payment: paymentReducer,
});7.2. Redux Slices
| Slice | Mục đích | Trạng thái Chính |
|---|---|---|
| cart | Quản lý giỏ hàng | Items, tổng cộng, thuế, phương thức thanh toán |
| order | Xử lý đơn hàng | Đơn hàng hiện tại, lịch sử đơn hàng |
| payment | Trạng thái thanh toán | Phương thức thanh toán, trạng thái, nỗ lực |
| product | Trạng thái danh mục sản phẩm | Sản phẩm đang hoạt động, lựa chọn |
| sale | Trạng thái phiên bán hàng | Phiên hoạt động, chế độ |
| userProfile | Thông tin người dùng | Hồ sơ, tùy chọn |
| common | Trạng thái UI chung | Cờ, cài đặt |
| temporary | Dữ liệu tạm thời | Bản nháp form |
7.3. Cấu trúc Trạng thái Giỏ hàng
typescript
interface ICartState {
cartList: [];
cartItems: { [id: string]: ICartItem };
productVariantToCartItemsMap: { [variantId: string]: string };
// Tính toán giá
totalPrice: number;
totalPurchaseVoucherPrice: number;
totalDiscountVoucherPrice: number;
totalTaxPrice: number;
totalPaymentPrice: number;
taxPercentage: string;
paymentMethod: PaymentMethod;
}7.4. Hành động Giỏ hàng
| Hành động | Mô tả |
|---|---|
resetCart | Đặt lại về trạng thái ban đầu |
resetCartAfterPayment | Xóa giỏ hàng sau khi thanh toán thành công |
loadCartItems | Tải các mục từ backend |
addCartItem | Thêm mục vào giỏ hàng |
removeCartItem | Xóa mục khỏi giỏ hàng |
updateQuantityCartItem | Cập nhật số lượng mục |
updateTaxPercentage | Đặt thuế suất |
8. Dịch vụ API
8.1. Dịch vụ API IPC
Tất cả các dịch vụ API giao tiếp qua Tauri IPC:
| Dịch vụ | Lệnh | Mô tả |
|---|---|---|
| AuthApi | sign_in, sign_out, who_am_i | Xác thực |
| UserApi | get_user_profile | Hồ sơ người dùng |
| CategoryApi | CRUD operations | Danh mục |
| ProductApi | CRUD operations | Sản phẩm |
| ProductVariantApi | CRUD operations | Biến thể |
| MerchantApi | CRUD operations | Merchant |
| OrganizerApi | CRUD operations | Tổ chức |
| SaleChannelApi | CRUD operations | Kênh bán hàng |
| CartApi | cart_items, add_item, clear | Quản lý giỏ hàng |
| CartItemApi | update_quantity | Thao tác mục |
| OrderApi | checkout, revert_checkout | Xử lý đơn hàng |
| PaymentApi | checkout, cancel, system_ipn | Thanh toán |
| PaymentAttemptApi | find_by_id | Thử thanh toán |
| AssetApi | i18n_file, vnpay_qr_frame | Tài sản |
9. Tích hợp WebSocket
9.1. Kiến trúc Socket
socket/
├── client/ # Client-side socket
│ ├── index.ts # Socket client exports
│ ├── socket-connection-manager.ts # Quản lý kết nối
│ └── socket-subscription-manager.ts # Xử lý đăng ký
├── server/ # Server message handlers
│ ├── base/ # Các lớp socket cơ sở
│ │ ├── base-socket.ts # Lớp socket cơ sở
│ │ └── base-socket-subscription-manager.ts
│ ├── messages/ # Trình xử lý tin nhắn
│ │ └── market-data-socket-message-handler.ts
│ └── order-socket.service.ts # Dịch vụ socket đơn hàng
├── constants.ts # Hằng số socket
├── helper.ts # Tiện ích socket
├── types.ts # Kiểu dữ liệu socket
└── index.ts # Main exports9.2. Tính năng Socket
- Cập nhật Trạng thái Đơn hàng: Thay đổi trạng thái đơn hàng thời gian thực
- Dữ liệu Thị trường: Cập nhật giá trực tiếp
- Quản lý Kết nối: Tự động kết nối lại khi mất kết nối
- Hệ thống Đăng ký: Đăng ký/hủy đăng ký các kênh
10. Thành phần Radix UI
10.1. Các Primitives đã cài đặt
| Thành phần | Phiên bản | Sử dụng |
|---|---|---|
| Accordion | ^1.2.12 | Các phần có thể thu gọn |
| Alert Dialog | ^1.1.15 | Modal xác nhận |
| Avatar | ^1.1.11 | Ảnh đại diện người dùng |
| Checkbox | ^1.3.3 | Ô chọn form |
| Collapsible | ^1.1.12 | Bảng mở rộng |
| Context Menu | ^2.2.16 | Menu chuột phải |
| Dialog | ^1.1.15 | Hộp thoại modal |
| Dropdown Menu | ^2.1.16 | Menu thả xuống |
| Label | ^2.1.8 | Nhãn biểu mẫu |
| Popover | ^1.1.15 | Bảng nổi |
| Radio Group | ^1.3.8 | Lựa chọn radio |
| Scroll Area | ^1.2.10 | Thanh cuộn tùy chỉnh |
| Select | ^2.2.6 | Lựa chọn thả xuống |
| Separator | ^1.1.8 | Phân cách trực quan |
| Slot | ^1.2.4 | Khe thành phần |
| Switch | ^1.2.6 | Công tắc chuyển đổi |
| Tabs | ^1.1.13 | Điều hướng tab |
| Tooltip | ^1.2.8 | Chú thích khi di chuột |
11. Hệ thống Giỏ hàng
11.1. Tính năng Giỏ hàng
- Gộp mục: Nhóm các mục giống hệt nhau theo biến thể
- Quản lý Số lượng: Tăng/giảm với xác thực
- Tính toán Giá: Tổng phụ thời gian thực, thuế, chiết khấu
- Phương thức Thanh toán: Hỗ trợ Tiền mặt, QR, Thẻ
- Xử lý Thuế: Phần trăm thuế có thể cấu hình
11.2. Logic Tính toán Giá
typescript
// Tính tổng
totalPrice = items.reduce((sum, item) =>
sum + item.unitPrice * item.quantity, 0);
// Áp dụng chiết khấu và thuế
const taxableAmount = Math.max(0, totalPrice - discount);
totalTaxPrice = Math.round(taxableAmount * (taxRate / 100));
totalPaymentPrice = totalPrice
- totalDiscountVoucherPrice
- totalPurchaseVoucherPrice
+ totalTaxPrice;12. Luồng Thanh toán (Checkout Flow)
12.1. Sơ đồ Luồng
Xem lại Giỏ hàng
→
Liên kết Khách hàng
→
Chọn Thanh toán
→
Xử lý Thanh toán
12.2. Các bước Thanh toán
- Xem lại Giỏ hàng: Xác minh cuối cùng các mục
- Liên kết Khách hàng: Liên kết khách hàng tùy chọn
- Lựa chọn Thanh toán: Chọn Tiền mặt, QR, hoặc Thẻ
- Thực thi Giao dịch: Xử lý qua Tauri IPC
- Tạo Biên lai: Định dạng cho máy in
- Hoàn tất Đơn hàng: Xóa giỏ hàng và cập nhật trạng thái
13. Điểm Tích hợp
13.1. Thượng nguồn (Tauri Backend)
- Lệnh IPC: Gọi các hàm Rust qua
@tauri-apps/api - Sự kiện: Lắng nghe
init_ready,init_error,migration_error - API Cửa sổ: Quản lý cửa sổ, màn hình ngoài
13.2. Ngang hàng (Các gói Dùng chung)
- @nx-app/core: Tiện ích và locales dùng chung
- @minimaltech/ra-core-infra: Cơ sở hạ tầng dịch vụ cơ bản
- @venizia/ignis-inversion: IoC container
13.3. Hạ nguồn (Backend API)
- WebSocket: Cập nhật đơn hàng thời gian thực
- Telemetry: Ghi log lỗi và phân tích
14. Build & Scripts
14.1. Các Script có sẵn
| Script | Lệnh | Mục đích |
|---|---|---|
dev | vite --mode dev | Development server |
build | sh ./scripts/build.sh | Build sản xuất |
build:develop | sh ./scripts/rebuild.sh development | Build phát triển |
build:production | sh ./scripts/rebuild.sh production | Build sản xuất |
preview | vite preview | Xem trước build |
lint | sh ./scripts/lint.sh | Kiểm tra ESLint |
prettier | prettier '**/*.{js,ts,jsx,tsx}' --write | Định dạng mã |
14.2. Đầu ra Build
Bản build được tiêu thụ bởi tiến trình host Tauri:
- Thư mục đầu ra:
dist/ - Được phục vụ bởi plugin localhost của Tauri
- Được nhúng trong ứng dụng desktop/mobile
15. Thống kê Mã nguồn
| Chỉ số | Số lượng |
|---|---|
| Tệp Nguồn | ~337 |
| Module Màn hình | 8 |
| Redux Slices | 8 |
| Dịch vụ API | 15 |
| Thành phần Radix | 18 |
| Trình xử lý Socket | 5+ |
| Custom Hooks | 10+ |