| Tầng | Công nghệ | Phiên bản | Vai trò |
|---|---|---|---|
| Framework UI | Vue 3 | ^3.4.31 | Core framework, Composition API với <script setup> |
| Bundler | Vite | ^5.3.3 | Build tool và dev server, dùng ESBuild |
| Ngôn ngữ | TypeScript | ~5.5.2 | Kiểu dữ liệu tĩnh toàn bộ mã nguồn |
| State management | Pinia | ^2.1.7 | Thay thế Vuex, hỗ trợ Composition API |
| Persist store | pinia-plugin-persistedstate | ^3.2.1 | Đồng bộ store với localStorage |
| UI library | Naive UI | ^2.38.2 | Bộ component UI cho Vue 3 |
| Biểu đồ chính | Apache ECharts + vue-echarts | ^5.5.1 / ^7.0.3 | Biểu đồ thống kê và phân tích hiệu suất |
| Biểu đồ phụ | Chart.js | ^4.5.1 | Biểu đồ bổ sung cho một số màn hình |
| Trực quan hóa | D3.js | ^7.9.0 | Trực quan hóa dữ liệu phức tạp |
| HTTP client | Axios | ^1.7.2 | Giao tiếp với Backend API Engine |
| CSS utilities | Tailwind CSS | ^3.4.4 | Utility-first CSS |
| CSS preprocessor | SASS | ^1.77.8 | SCSS cho các style phức tạp |
| Xuất Excel | xlsx + xlsx-js-style | ^0.18.5 / ^1.2.0 | Xuất báo cáo .xlsx có định dạng màu sắc |
| Vue utilities | @vueuse/core | ^10.11.0 | Composables: clipboard, event bus, URL params |
| Đa ngôn ngữ | vue-i18n | ^9.13.1 | Tiếng Việt và Tiếng Anh |
| Router | vue-router | ^4.4.0 | Điều hướng SPA với History Mode |
| Icon | @iconify/vue | ^4.1.2 | Thư viện icon đa dạng |
| Validation | zod | ^3.23.8 | Schema validation cho form data |
| Utilities | lodash | ^4.17.21 | Xử lý mảng, object, chuỗi |
| Công cụ | File cấu hình | Chức năng |
|---|---|---|
| ESLint | .eslintrc.cjs | Phân tích tĩnh, phát hiện lỗi cú pháp và anti-pattern. |
| Prettier | .prettierrc.json | Tự động định dạng code theo chuẩn nhất quán. |
| Husky | .husky/ | Git hooks — chặn commit nếu code không qua lint. |
| lint-staged | .husky/lintstagedrc.js | Chỉ lint các file đã thay đổi, tối ưu thời gian commit. |
| Commitizen + cz-git | cz.config.js | Enforce chuẩn Conventional Commits. |
| commitlint | commitlint.config.ts | Kiểm tra format commit message theo Angular convention. |
| vue-tsc | — | Kiểm tra kiểu TypeScript cho file .vue với <script setup>. |
src/views/ ← Màn hình nghiệp vụ
|
| sử dụng
v
src/composables/ ← Logic tái sử dụng
|
+---------------------------+
| |
v v
src/stores/ ← Pinia state src/services/api/ ← Axios API calls
| |
+---------------------------+
|
v
src/configs/axios.ts ← HTTP layer (interceptors, auth headers)
|
v
Backend API Engine/login, /signup và các trang lỗi (404, 403). Không dùng LayoutDefault, không yêu cầu xác thực. Định nghĩa trong src/router/modules/remaining.ts.LayoutDefault.vue và chịu sự kiểm soát của router.beforeEach. Các route module được tự động nạp:/auto-search → google-search, coccoc-search, server-performance, location/system-management → server-management, proxy-management, backup-proxy-management, proxy-package-management, proxy-provider-management/dashboard1 → click-ads, negative-seo, search-ads, traffic-natural/user-management → users, activitiessrc/services/api/, tất cả dùng Axios instance từ src/configs/axios.ts:| File service | API prefix | Các phương thức chính |
|---|---|---|
auth.ts | /user | login, getMe, refreshToken, signup, generateGoogleAuthenticator, verifyGoogleAuthenticator |
autoSearch.ts | /keywords | getList, getDetail, create, update, updateStatus, autoFire, reset, delete, exportExcel, historyKeyword |
servers.ts | /server | getList, getDetail, create, update, changeStatus, delete, bulkDelete |
serverPerformance.ts | /server/report | getList, getDetail |
proxies.ts | /proxy | getList, getDetail, create, update, delete, updateActive, uploadProxy, bulkDelete |
backup-proxies.ts | /backup-proxy | getList, create, update, delete, testProxy, importFromProxifly, healthCheck, bulkDelete |
package.ts | /proxy-packages | getList, getDetail, create, update, delete, bulkDelete |
provider.ts | /proxy-providers | getList, getDetail, create, update, delete, updateSort, getDataUsage, bulkDelete |
campain.ts | /campaign | getList, getDetail, create, update, delete, getStatistics, exportData |
users.ts | /user | getList, getDetail, create, update, delete, updateActive, changePassword |
activities.ts | /activity | getList |
location.ts | /location | getList, getDetail, create, update, delete |
profiles.ts | /profile | getList, getDetail, create, update, delete |
task.ts | /project | getList, getDetail, create, update, delete, updateStatus, updateDomainStatus |
reports.ts | Nhiều endpoint | Class ReportApiService với các phương thức static |
src/stores/
├── authStore.ts ← Token, Profile, 2FA logic, logout
├── appStore.ts ← UI settings (locale, sidebar, breadcrumbs)
└── reportStore.ts ← Dữ liệu tạm cho màn hình báo cáo
report/
└── (các store con cho module báo cáo)| Trường | Kiểu | Persist | Mô tả |
|---|---|---|---|
authToken | Auth.AuthToken | null | Có (localStorage) | JWT token, refresh token và device token. |
profile | Auth.UserProfile | null | Không | Thông tin người dùng đang đăng nhập. |
is_2fa | boolean | Không | Trạng thái 2FA từ server. |
message | string | Không | Thông điệp phản hồi từ API. |
| Action | API endpoint | Mô tả |
|---|---|---|
login(data) | POST /api/user/login | Đăng nhập, nhận AuthToken, cập nhật is_2fa. |
getMe() | GET /api/user/profile | Lấy thông tin profile. Tự kiểm tra localStorage nếu store trống. |
signUp(data) | POST /api/user/register | Đăng ký tài khoản mới (chỉ dùng ở môi trường dev). |
logout() | — | Xóa token, profile, sessionStorage và redirect về login. |
refreshToken() | POST /api/user/refresh | Làm mới token, cập nhật store và localStorage. |
sideBarCollapsed: boolean — Trạng thái thu gọn sidebar. Mặc định false.i18nLocale: I18nLocalesKey — Ngôn ngữ hiện tại. Mặc định 'vi-VN'.isLoadingWebsite: boolean — Cờ loading toàn trang.breadcrumbs: Breadcrumb[] — Cập nhật sau mỗi lần chuyển route.setLocale(locale) — Cập nhật i18nLocale và đồng bộ i18n.global.locale.value.init() phải được gọi trong src/main.ts sau khi Pinia khởi tạo để interceptor có thể truy cập useAuthStore()./import-all: 300,000ms (5 phút) — import proxy hàng loạt từ Excel./get-data-report: 60,000ms (1 phút) — tổng hợp báo cáo lớn.this.requests. Sau khi có token mới, tất cả request trong hàng đợi được thực thi lại. Cờ this.isRefreshing ngăn gọi refresh token nhiều lần đồng thời.| Mã HTTP | Xử lý trong Admin |
|---|---|
| 400 | Reject Promise, component gọi showMessageError() để hiển thị lỗi validation. |
| 401 | Interceptor tự động gọi authStore.logout() và redirect về login. |
| 403 | Reject Promise, component hiển thị thông báo không có quyền. |
| 404 | Reject Promise, component hiển thị thông báo không tìm thấy. |
| 408 / Timeout | Axios tự reject sau khi vượt quá timeout. |
| 500 | Reject Promise, component hiển thị lỗi server. |
| Network Error | Axios reject với error.message = 'Network Error'. |
src/composables/utils.ts:| Hàm | Mô tả |
|---|---|
useHelper() | Trả về getCatchMsg() và showMessageError() để xử lý lỗi API. |
useEnv(key) | Đọc biến môi trường từ window.configs trước, fallback về import.meta.env. |
useDownload(blob, fileName) | Tạo link tải file từ Blob response và kích hoạt download. |
useDownloadUrl(url, fileName) | Tải file từ URL bên ngoài bằng Axios rồi kích hoạt download. |
useCopyToClipboard() | Copy text vào clipboard với fallback cho trình duyệt cũ. |
useEnsureHttp() | Đảm bảo URL luôn có tiền tố http:// hoặc https://. |
src/composables/useBulkSelection.ts:useBulkSelection<T> quản lý chọn nhiều bản ghi trong bảng:getRowKey(row) — Bắt buộc. Lấy key định danh duy nhất của mỗi dòng.onBulkDelete(selectedRows) — Callback xử lý xóa hàng loạt.onBulkExport(selectedRows) — Callback xử lý xuất dữ liệu hàng loạt.onBulkUpdate(selectedRows, updates) — Callback xử lý cập nhật hàng loạt.selectedRowKeys, isProcessing, hasSelection, selectionCount.format.ts — Định dạng số, ngày tháng, trạng thái cho bảng và biểu đồ.render.ts — Tạo cột bảng Naive UI Data Table dạng động (button, tag màu, tooltip).toggle.ts — Quản lý isOpen, isLoading, isEditing trong modal và form.router.ts — replaceParamsInPath() để thay thế tham số động trong đường dẫn route.BulkActions.vue — Thanh công cụ hiển thị khi có bản ghi được chọn (xóa, xuất, cập nhật hàng loạt).pagination/ — Component phân trang tùy chỉnh tích hợp với Naive UI Pagination.common/ — DateRangePicker, SearchInput, StatusTag dùng trên nhiều màn hình.| Lệnh | Môi trường | Mô tả |
|---|---|---|
npm run dev | Development | Khởi động Vite Dev Server với HMR. |
npm run build:dev | Development | Build tĩnh cho môi trường Development. |
npm run build:stg | Staging | Build tĩnh cho môi trường Staging. |
npm run build:release | Release | Build tĩnh cho môi trường Release. |
npm run build:prod | Production | Build tĩnh cho Production, chạy typecheck sau khi build. |
npm run build:prod:docker | Production | Build cho Production trong Docker, không chạy typecheck riêng. |
npm run typecheck | — | Chạy vue-tsc --build --force kiểm tra kiểu dữ liệu. |
npm run lint | — | Chạy ESLint và tự sửa lỗi trên toàn bộ file .vue, .ts. |
dist/ với:index.html — Entry point HTML.assets/ — Các file .js, .css, hình ảnh đã được hash tên file để cache-busting tự động.assets/[name].[hash].js. Hash thay đổi mỗi khi nội dung thay đổi.naiveUI — Toàn bộ Naive UI (~1MB, ít thay đổi).lodash — Lodash và lodash-es.vue — Vue core (ổn định nhất).http://localhost:5173.src/services/api/reports/:src/services/api/reports/
├── useReportRequest.ts ← Hàm request() wrapper với base URL riêng
├── useReportEndpoints.ts ← Các endpoint đặc thù của module báo cáo
├── useReportCrud.ts ← CRUD cơ bản: getReports, createReport, deleteReport
└── useReportStats.ts ← Thống kê: getDashboardStats, getPlatformPerformanceReportApiService trong reports.ts là class static tổng hợp tất cả phương thức, cung cấp interface thống nhất cho các component.locales/
├── vi-VN.json ← Chuỗi Tiếng Việt (mặc định)
├── en-US.json ← Chuỗi Tiếng Anh
└── _schema.json ← Schema kiểm tra cấu trúc file ngôn ngữsrc/configs/webhook-axios.ts cung cấp một Axios instance riêng cho các request đến webhook endpoint, tách biệt với instance chính để tránh ảnh hưởng về cấu hình timeout và header. Dùng để gửi thông báo đến các hệ thống bên ngoài (Slack, Telegram) khi có sự kiện quan trọng.<script setup lang="ts"> thay vì Options API để có type inference tốt hơn.import.meta.glob để tự động nạp route modules.window.configs injection để override biến môi trường mà không cần build lại.pinia-plugin-persistedstate để đồng bộ store với localStorage theo cách khai báo.