FE: module product_category — danh mục sản phẩm (cây) #
Phần chung (khởi tạo client, lỗi, danh sách, ngôn ngữ) ở tài liệu FE của Core:
docs/fe/common.md (bản đọc: xforge-documentation, ADR-0102 của xforge-core).
Sửa file này CÙNG PR khi đổi hành vi FE thấy được của module.
Danh mục là CÂY tối đa 8 cấp: mỗi dòng có parentId (null = gốc), path,
depth, sortOrder. Server trả danh sách PHẲNG — FE tự dựng cây từ parentId.
Field dịch được (name, slug…): phần chung §3.3. Ảnh: imageFileId +
imageFileInfo (module files).
Dựng cây #
sort=tree (mặc định) trả cha trước con, anh em theo sortOrder rồi mã — đọc
lần lượt và gắn vào parentId là ra cây đúng thứ tự. Lọc: parent_id (con trực
tiếp), parent_id.null=true (chỉ gốc), depth / depth.lte (giới hạn tầng),
active.
CMS / admin (XforgeClient) #
Menu: key product_category.categories (quyền product_category.read).
| Việc | Method | Quyền |
|---|---|---|
| Danh sách / cây | listProductCategories({ query }) | product_category.read |
| Picker cây | listProductCategoryOptions({ query }) — trang tới 1000 dòng, thường cả cây một lần | product_category.read |
| Chi tiết | getProductCategory({ params: { id } }) | product_category.read |
| Tạo | createProductCategory({ body }) (parentId vắng = gốc) | product_category.create |
| Sửa / chuyển nhánh | updateProductCategory({ params: { id }, body }) | product_category.update |
| Xoá | deleteProductCategory({ params: { id } }) | product_category.delete |
- Đổi
parentId= chuyển cả NHÁNH con theo (null= thành gốc). Không cho chọn chính nó / con cháu của nó làm cha (server trả 409product_category_cycle) — picker nên ẩn các mục đó. - Xoá là xoá thật (không thùng rác); còn danh mục con → 409
product_category_has_children; sản phẩm còn dùng → moduleproductchặn. translationsgửi = thay cả bộ (ngôn ngữ vắng bị xoá);slugtrống → sinh từname.
Storefront (StorefrontClient) #
Không cần đăng nhập. Chỉ danh mục đang bật, có bản dịch, VÀ mọi tổ tiên đều đang bật (cha tắt → cả nhánh ẩn).
listPublicProductCategories({ query })— menu danh mục / cây (≤ 100 / trang, theometa.nextCursortới hết nếu cây lớn).getPublicProductCategoryBySlug({ params: { slug } })— trang danh mục. Sản phẩm của danh mục VÀ mọi danh mục con:listPublicProducts({ query: { in_category: category.id } }); chỉ đúng danh mục đó:category_id(moduleproduct).
Lỗi cần xử lý #
code | Status | FE nên |
|---|---|---|
product_category_not_found | 404 | trang 404 (storefront: slug không còn / bị ẩn) |
product_category_code_exists | 409 | báo ở ô code |
product_category_slug_exists | 409 | báo ở ô slug của đúng ngôn ngữ |
product_category_parent_not_found | 400 | cha không thuộc store / đã xoá → tải lại picker |
product_category_too_deep | 409 | quá 8 cấp → chọn cha nông hơn |
product_category_cycle | 409 | chọn cha là chính nó / con cháu |
product_category_has_children | 409 | chuyển / xoá các danh mục con trước |
unsupported_language | 400 | ngôn ngữ không bật cho store |
file_not_attachable | 400 | ảnh không phải file của store này |
Màn hình dựng sẵn #
listMenu() → mục product_category.categories có screen (type: "crud"):
CMS chung vẽ được từ
getMenuScreen({ params: { key: "product_category.categories" } }) mà không cần
code riêng (tài liệu FE của Core: cms.md §3.1). Có: danh sách (ảnh, mã, tên,
danh mục cha, thứ tự, đang dùng; tìm; lọc theo trạng thái / danh mục cha), form
tạo / sửa (bản dịch, danh mục cha chọn từ listProductCategoryOptions, ảnh tải
qua uploadFile), xoá.
Màn hình chung KHÔNG có (CMS tự thêm nếu cần): hiển thị dạng CÂY (danh sách
phẳng; sắp tree của listProductCategories vẫn dùng được nếu CMS tự vẽ cây),
chặn chọn chính nó / con cháu làm cha (server trả lỗi).
Quyền ngoài module mà màn hình dùng (thiếu thì CMS ẩn / rơi về ô nhập thường):
- Ảnh: xem cần
files.read(downloadFile), tải lên cầnfiles.write(uploadFile).
Gửi translations khi sửa là THAY cả bộ bản dịch (ngôn ngữ vắng bị xoá).