docs: refresh template documentation and examples
Update README and frontend layering docs to reflect the current template core structure, use relative repository links, and remove outdated demo guidance. Add expanded API response examples for common features and ignore local Codex configuration.docs: refresh template documentation and examples Update README and frontend layering docs to reflect the current template core structure, use relative repository links, and remove outdated demo guidance. Add expanded API response examples for common features and ignore local Codex configuration.
This commit is contained in:
@@ -1,16 +0,0 @@
|
||||
[mcp_servers.chrome-devtools]
|
||||
command = "npx"
|
||||
args = ["chrome-devtools-mcp@latest", "--browserUrl", "http://localhost:9222"]
|
||||
|
||||
[mcp_servers.code-review-graph]
|
||||
command = "uvx"
|
||||
args = ["code-review-graph", "serve"]
|
||||
|
||||
[mcp_servers.code-review-graph.tools.get_minimal_context_tool]
|
||||
approval_mode = "approve"
|
||||
|
||||
[mcp_servers.code-review-graph.tools.query_graph_tool]
|
||||
approval_mode = "approve"
|
||||
|
||||
[mcp_servers.code-review-graph.tools.build_or_update_graph_tool]
|
||||
approval_mode = "approve"
|
||||
@@ -38,3 +38,5 @@ output/playwright/
|
||||
/playwright/.auth/
|
||||
# Added by code-review-graph
|
||||
.code-review-graph/
|
||||
|
||||
.codex/config.toml
|
||||
|
||||
@@ -94,26 +94,10 @@ VITE_DEV_DEFAULT_PASSWORD=
|
||||
- `src/styles`:Vuetify SASS settings 與 themes。
|
||||
- `src/language`:i18n JSON。
|
||||
|
||||
## Template Core 與 Demo
|
||||
## Template Core
|
||||
|
||||
template core 是 app shell、router、layout、plugins、styles、services 基礎設施與全域 stores。一般專案會保留它們。
|
||||
|
||||
demo/example 主要是 maintenance 與學生資料範例:
|
||||
|
||||
- `src/views/Home.vue`
|
||||
- `src/components/PageIndex.vue`
|
||||
- `src/views/maint/*`
|
||||
- `src/components/maint/*`
|
||||
- `src/composables/maint/*`
|
||||
- `src/components/PageMaint.vue`
|
||||
- `src/stores/students.ts`
|
||||
- `src/stores/semesters.ts`
|
||||
- `src/views/FncPage.vue`
|
||||
- `src/views/Settings.vue`
|
||||
- `src/assets/*` 中的品牌或展示素材
|
||||
|
||||
建立正式專案時可依需求替換或刪除 demo/example。刪除時同步清理 routes、menu、language、assets 與引用。
|
||||
|
||||
## Documentation
|
||||
|
||||
- [src/README.md](./src/README.md):`src` 開發入口。
|
||||
|
||||
+83
-160
@@ -4,8 +4,6 @@
|
||||
|
||||
這份文件只描述目前 repo 已經落地的前端分層與命名規則,讓後續新增檔案、搬移檔案、或重構時有一致判斷基準。
|
||||
|
||||
重點不是追求理想化架構,而是避免把舊名稱、過渡寫法、或已刪除的結構繼續當成規則。
|
||||
|
||||
目前專案的主要責任鏈如下:
|
||||
|
||||
- `router` 決定 route 與 layout meta
|
||||
@@ -22,9 +20,9 @@
|
||||
|
||||
目前路由集中在:
|
||||
|
||||
- [routes.ts](/home/carl/git/skt-vuetify-templates/src/router/routes.ts)
|
||||
- [index.ts](/home/carl/git/skt-vuetify-templates/src/router/index.ts)
|
||||
- [guards.ts](/home/carl/git/skt-vuetify-templates/src/router/guards.ts)
|
||||
- [routes.ts](../src/router/routes.ts)
|
||||
- [index.ts](../src/router/index.ts)
|
||||
- [guards.ts](../src/router/guards.ts)
|
||||
|
||||
責任:
|
||||
|
||||
@@ -34,12 +32,12 @@
|
||||
|
||||
目前 `meta.layout` 已是 app shell 切換的正式入口:
|
||||
|
||||
- `default` 走 [MainLayout.vue](/home/carl/git/skt-vuetify-templates/src/components/layouts/MainLayout.vue)
|
||||
- `none` 走 [PlainLayout.vue](/home/carl/git/skt-vuetify-templates/src/components/layouts/PlainLayout.vue)
|
||||
- `default` 走 [MainLayout.vue](../src/components/layouts/MainLayout.vue)
|
||||
- `none` 走 [PlainLayout.vue](../src/components/layouts/PlainLayout.vue)
|
||||
|
||||
### `src/App.vue`
|
||||
|
||||
[App.vue](/home/carl/git/skt-vuetify-templates/src/App.vue) 目前不是單純掛載入口,而是實際的應用組裝層。
|
||||
[App.vue](../src/App.vue) 目前不是單純掛載入口,而是實際的應用組裝層。
|
||||
|
||||
目前承擔的責任包含:
|
||||
|
||||
@@ -61,23 +59,25 @@
|
||||
|
||||
目前較薄的 view:
|
||||
|
||||
- [Home.vue](/home/carl/git/skt-vuetify-templates/src/views/Home.vue)
|
||||
- [Login.vue](/home/carl/git/skt-vuetify-templates/src/views/Login.vue)
|
||||
- [EditableGrid.vue](/home/carl/git/skt-vuetify-templates/src/views/maint/EditableGrid.vue)
|
||||
- [Forbidden.vue](/home/carl/git/skt-vuetify-templates/src/views/errors/Forbidden.vue)
|
||||
- [ServerError.vue](/home/carl/git/skt-vuetify-templates/src/views/errors/ServerError.vue)
|
||||
- [ServiceUnavailable.vue](/home/carl/git/skt-vuetify-templates/src/views/errors/ServiceUnavailable.vue)
|
||||
- [NetworkError.vue](/home/carl/git/skt-vuetify-templates/src/views/errors/NetworkError.vue)
|
||||
- [Maintenance.vue](/home/carl/git/skt-vuetify-templates/src/views/errors/Maintenance.vue)
|
||||
- [NotFound.vue](/home/carl/git/skt-vuetify-templates/src/views/errors/NotFound.vue)
|
||||
- [FncPage.vue](/home/carl/git/skt-vuetify-templates/src/views/FncPage.vue)
|
||||
- [Home.vue](../src/views/Home.vue)
|
||||
- [Login.vue](../src/views/Login.vue)
|
||||
- [EditableGrid.vue](../src/views/maint/EditableGrid.vue)
|
||||
- [Forbidden.vue](../src/views/errors/Forbidden.vue)
|
||||
- [ServerError.vue](../src/views/errors/ServerError.vue)
|
||||
- [ServiceUnavailable.vue](../src/views/errors/ServiceUnavailable.vue)
|
||||
- [NetworkError.vue](../src/views/errors/NetworkError.vue)
|
||||
- [Maintenance.vue](../src/views/errors/Maintenance.vue)
|
||||
- [NotFound.vue](../src/views/errors/NotFound.vue)
|
||||
- [ErrorShell.vue](../src/views/errors/ErrorShell.vue)
|
||||
- [FncPage.vue](../src/views/FncPage.vue)
|
||||
- [Settings.vue](../src/views/Settings.vue)
|
||||
|
||||
目前仍偏厚的 view:
|
||||
|
||||
- [SingleRecord.vue](/home/carl/git/skt-vuetify-templates/src/views/maint/SingleRecord.vue)
|
||||
- [MasterDetailA.vue](/home/carl/git/skt-vuetify-templates/src/views/maint/MasterDetailA.vue)
|
||||
- [MasterDetailB.vue](/home/carl/git/skt-vuetify-templates/src/views/maint/MasterDetailB.vue)
|
||||
- [MasterDetailC.vue](/home/carl/git/skt-vuetify-templates/src/views/maint/MasterDetailC.vue)
|
||||
- [SingleRecord.vue](../src/views/maint/SingleRecord.vue)
|
||||
- [MasterDetailA.vue](../src/views/maint/MasterDetailA.vue)
|
||||
- [MasterDetailB.vue](../src/views/maint/MasterDetailB.vue)
|
||||
- [MasterDetailC.vue](../src/views/maint/MasterDetailC.vue)
|
||||
|
||||
`views` 應遵守的原則:
|
||||
|
||||
@@ -94,9 +94,9 @@
|
||||
|
||||
目前以下元件實際上扮演 page component:
|
||||
|
||||
- [PageLogin.vue](/home/carl/git/skt-vuetify-templates/src/components/PageLogin.vue)
|
||||
- [PageIndex.vue](/home/carl/git/skt-vuetify-templates/src/components/PageIndex.vue)
|
||||
- [PageMaint.vue](/home/carl/git/skt-vuetify-templates/src/components/PageMaint.vue)
|
||||
- [PageLogin.vue](../src/components/PageLogin.vue)
|
||||
- [PageIndex.vue](../src/components/PageIndex.vue)
|
||||
- [PageMaint.vue](../src/components/PageMaint.vue)
|
||||
|
||||
這些檔案的責任是:
|
||||
|
||||
@@ -114,14 +114,14 @@
|
||||
|
||||
登入頁的較細 UI 區塊已集中到:
|
||||
|
||||
- [CreateAccountLink.vue](/home/carl/git/skt-vuetify-templates/src/components/login/CreateAccountLink.vue)
|
||||
- [LoginAnnouncementBoard.vue](/home/carl/git/skt-vuetify-templates/src/components/login/LoginAnnouncementBoard.vue)
|
||||
- [LoginBrand.vue](/home/carl/git/skt-vuetify-templates/src/components/login/LoginBrand.vue)
|
||||
- [LoginForm.vue](/home/carl/git/skt-vuetify-templates/src/components/login/LoginForm.vue)
|
||||
- [LoginHeader.vue](/home/carl/git/skt-vuetify-templates/src/components/login/LoginHeader.vue)
|
||||
- [LoginIllustration.vue](/home/carl/git/skt-vuetify-templates/src/components/login/LoginIllustration.vue)
|
||||
- [LoginToolBar.vue](/home/carl/git/skt-vuetify-templates/src/components/login/LoginToolBar.vue)
|
||||
- [LoginVerify.vue](/home/carl/git/skt-vuetify-templates/src/components/login/LoginVerify.vue)
|
||||
- [CreateAccountLink.vue](../src/components/login/CreateAccountLink.vue)
|
||||
- [LoginAnnouncementBoard.vue](../src/components/login/LoginAnnouncementBoard.vue)
|
||||
- [LoginBrand.vue](../src/components/login/LoginBrand.vue)
|
||||
- [LoginForm.vue](../src/components/login/LoginForm.vue)
|
||||
- [LoginHeader.vue](../src/components/login/LoginHeader.vue)
|
||||
- [LoginIllustration.vue](../src/components/login/LoginIllustration.vue)
|
||||
- [LoginToolBar.vue](../src/components/login/LoginToolBar.vue)
|
||||
- [LoginVerify.vue](../src/components/login/LoginVerify.vue)
|
||||
|
||||
這一層的定位是:
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
|
||||
目前 `components/base` 只剩下:
|
||||
|
||||
- [DraggableDialog.vue](/home/carl/git/skt-vuetify-templates/src/components/base/DraggableDialog.vue)
|
||||
- [DraggableDialog.vue](../src/components/base/DraggableDialog.vue)
|
||||
|
||||
目前判斷原則很直接:
|
||||
|
||||
@@ -144,18 +144,18 @@
|
||||
|
||||
目前 layout 實作集中於:
|
||||
|
||||
- [MainLayout.vue](/home/carl/git/skt-vuetify-templates/src/components/layouts/MainLayout.vue)
|
||||
- [PlainLayout.vue](/home/carl/git/skt-vuetify-templates/src/components/layouts/PlainLayout.vue)
|
||||
- [MainLayout.vue](../src/components/layouts/MainLayout.vue)
|
||||
- [PlainLayout.vue](../src/components/layouts/PlainLayout.vue)
|
||||
- `src/components/layouts/main-layout/*`
|
||||
|
||||
其中 `main-layout/*` 是 `MainLayout` 底下拆出的骨架子元件:
|
||||
|
||||
- [AppBarBreadcrumbCol.vue](/home/carl/git/skt-vuetify-templates/src/components/layouts/main-layout/AppBarBreadcrumbCol.vue)
|
||||
- [AppBarFavoritesCol.vue](/home/carl/git/skt-vuetify-templates/src/components/layouts/main-layout/AppBarFavoritesCol.vue)
|
||||
- [AppBarTopCol.vue](/home/carl/git/skt-vuetify-templates/src/components/layouts/main-layout/AppBarTopCol.vue)
|
||||
- [DrawerDesktopMenu.vue](/home/carl/git/skt-vuetify-templates/src/components/layouts/main-layout/DrawerDesktopMenu.vue)
|
||||
- [DrawerMobileFavoritesPanel.vue](/home/carl/git/skt-vuetify-templates/src/components/layouts/main-layout/DrawerMobileFavoritesPanel.vue)
|
||||
- [DrawerMobileMenuPanel.vue](/home/carl/git/skt-vuetify-templates/src/components/layouts/main-layout/DrawerMobileMenuPanel.vue)
|
||||
- [AppBarBreadcrumbCol.vue](../src/components/layouts/main-layout/AppBarBreadcrumbCol.vue)
|
||||
- [AppBarFavoritesCol.vue](../src/components/layouts/main-layout/AppBarFavoritesCol.vue)
|
||||
- [AppBarTopCol.vue](../src/components/layouts/main-layout/AppBarTopCol.vue)
|
||||
- [DrawerDesktopMenu.vue](../src/components/layouts/main-layout/DrawerDesktopMenu.vue)
|
||||
- [DrawerMobileFavoritesPanel.vue](../src/components/layouts/main-layout/DrawerMobileFavoritesPanel.vue)
|
||||
- [DrawerMobileMenuPanel.vue](../src/components/layouts/main-layout/DrawerMobileMenuPanel.vue)
|
||||
|
||||
layout 應只承擔:
|
||||
|
||||
@@ -172,22 +172,22 @@ layout 不應承擔:
|
||||
|
||||
這個目錄目前是最接近 feature folder 的區域,放 maintenance 領域的 page component 與 domain component:
|
||||
|
||||
- [PageMaint.vue](/home/carl/git/skt-vuetify-templates/src/components/PageMaint.vue)
|
||||
- [CommonConfirmDialog.vue](/home/carl/git/skt-vuetify-templates/src/components/maint/CommonConfirmDialog.vue)
|
||||
- [EditableGrid.vue](/home/carl/git/skt-vuetify-templates/src/components/maint/EditableGrid.vue)
|
||||
- [MasterFileFormFields.vue](/home/carl/git/skt-vuetify-templates/src/components/maint/MasterFileFormFields.vue)
|
||||
- [MntDialogCard.vue](/home/carl/git/skt-vuetify-templates/src/components/maint/MntDialogCard.vue)
|
||||
- [MntRecordNavToolbar.vue](/home/carl/git/skt-vuetify-templates/src/components/maint/MntRecordNavToolbar.vue)
|
||||
- [PageMaint.vue](../src/components/PageMaint.vue)
|
||||
- [CommonConfirmDialog.vue](../src/components/maint/CommonConfirmDialog.vue)
|
||||
- [EditableGrid.vue](../src/components/maint/EditableGrid.vue)
|
||||
- [MasterFileFormFields.vue](../src/components/maint/MasterFileFormFields.vue)
|
||||
- [MntDialogCard.vue](../src/components/maint/MntDialogCard.vue)
|
||||
- [MntRecordNavToolbar.vue](../src/components/maint/MntRecordNavToolbar.vue)
|
||||
- `master-detail/*`
|
||||
|
||||
`master-detail/*` 目前屬於維護頁專用的較細組件群:
|
||||
|
||||
- [CourseMobilePanel.vue](/home/carl/git/skt-vuetify-templates/src/components/maint/master-detail/CourseMobilePanel.vue)
|
||||
- [DetailCollapseGropus.vue](/home/carl/git/skt-vuetify-templates/src/components/maint/master-detail/DetailCollapseGropus.vue)
|
||||
- [DetailFullHeightPanel.vue](/home/carl/git/skt-vuetify-templates/src/components/maint/master-detail/DetailFullHeightPanel.vue)
|
||||
- [DetailNavigation.vue](/home/carl/git/skt-vuetify-templates/src/components/maint/master-detail/DetailNavigation.vue)
|
||||
- [DetailSidePanel.vue](/home/carl/git/skt-vuetify-templates/src/components/maint/master-detail/DetailSidePanel.vue)
|
||||
- [DetailSimpleList.vue](/home/carl/git/skt-vuetify-templates/src/components/maint/master-detail/DetailSimpleList.vue)
|
||||
- [CourseMobilePanel.vue](../src/components/maint/master-detail/CourseMobilePanel.vue)
|
||||
- [DetailCollapseGropus.vue](../src/components/maint/master-detail/DetailCollapseGropus.vue)
|
||||
- [DetailFullHeightPanel.vue](../src/components/maint/master-detail/DetailFullHeightPanel.vue)
|
||||
- [DetailNavigation.vue](../src/components/maint/master-detail/DetailNavigation.vue)
|
||||
- [DetailSidePanel.vue](../src/components/maint/master-detail/DetailSidePanel.vue)
|
||||
- [DetailSimpleList.vue](../src/components/maint/master-detail/DetailSimpleList.vue)
|
||||
|
||||
結論:
|
||||
|
||||
@@ -204,12 +204,12 @@ layout 不應承擔:
|
||||
|
||||
代表性檔案:
|
||||
|
||||
- [useAdminLayoutState.ts](/home/carl/git/skt-vuetify-templates/src/composables/layout/useAdminLayoutState.ts)
|
||||
- [useThemeToggle.ts](/home/carl/git/skt-vuetify-templates/src/composables/layout/useThemeToggle.ts)
|
||||
- [useMaintenanceCrudFlow.ts](/home/carl/git/skt-vuetify-templates/src/composables/maint/useMaintenanceCrudFlow.ts)
|
||||
- [useStudentMaintenanceForm.ts](/home/carl/git/skt-vuetify-templates/src/composables/maint/useStudentMaintenanceForm.ts)
|
||||
- [useEditableStudentGrid.ts](/home/carl/git/skt-vuetify-templates/src/composables/maint/useEditableStudentGrid.ts)
|
||||
- [useApiCall.ts](/home/carl/git/skt-vuetify-templates/src/composables/useApiCall.ts)
|
||||
- [useAdminLayoutState.ts](../src/composables/layout/useAdminLayoutState.ts)
|
||||
- [useThemeToggle.ts](../src/composables/layout/useThemeToggle.ts)
|
||||
- [useMaintenanceCrudFlow.ts](../src/composables/maint/useMaintenanceCrudFlow.ts)
|
||||
- [useStudentMaintenanceForm.ts](../src/composables/maint/useStudentMaintenanceForm.ts)
|
||||
- [useEditableStudentGrid.ts](../src/composables/maint/useEditableStudentGrid.ts)
|
||||
- [useApiCall.ts](../src/composables/useApiCall.ts)
|
||||
|
||||
`composables` 的責任:
|
||||
|
||||
@@ -223,21 +223,23 @@ layout 不應承擔:
|
||||
|
||||
代表性檔案:
|
||||
|
||||
- [auth.ts](/home/carl/git/skt-vuetify-templates/src/stores/auth.ts)
|
||||
- [menu.ts](/home/carl/git/skt-vuetify-templates/src/stores/menu.ts)
|
||||
- [breadcrumbs.ts](/home/carl/git/skt-vuetify-templates/src/stores/breadcrumbs.ts)
|
||||
- [favorites.ts](/home/carl/git/skt-vuetify-templates/src/stores/favorites.ts)
|
||||
- [messages.ts](/home/carl/git/skt-vuetify-templates/src/stores/messages.ts)
|
||||
- [snackbar.ts](/home/carl/git/skt-vuetify-templates/src/stores/snackbar.ts)
|
||||
- [loginAnnouncements.ts](/home/carl/git/skt-vuetify-templates/src/stores/loginAnnouncements.ts)
|
||||
- [students.ts](/home/carl/git/skt-vuetify-templates/src/stores/students.ts)
|
||||
- [semesters.ts](/home/carl/git/skt-vuetify-templates/src/stores/semesters.ts)
|
||||
- [auth.ts](../src/stores/auth.ts)
|
||||
- [app.ts](../src/stores/app.ts)
|
||||
- [menu.ts](../src/stores/menu.ts)
|
||||
- [breadcrumbs.ts](../src/stores/breadcrumbs.ts)
|
||||
- [favorites.ts](../src/stores/favorites.ts)
|
||||
- [messages.ts](../src/stores/messages.ts)
|
||||
- [snackbar.ts](../src/stores/snackbar.ts)
|
||||
- [loginAnnouncements.ts](../src/stores/loginAnnouncements.ts)
|
||||
- [students.ts](../src/stores/students.ts)
|
||||
- [semesters.ts](../src/stores/semesters.ts)
|
||||
|
||||
責任:
|
||||
|
||||
- 承接跨頁共享狀態
|
||||
- 承接畫面快取與顯示狀態
|
||||
- 作為 view 與 services 之間的狀態收斂點
|
||||
- `app.ts` 目前是空的 Pinia scaffold,尚未承擔實際 app state
|
||||
|
||||
規則:
|
||||
|
||||
@@ -250,13 +252,13 @@ layout 不應承擔:
|
||||
|
||||
代表性檔案:
|
||||
|
||||
- [client.ts](/home/carl/git/skt-vuetify-templates/src/services/client.ts)
|
||||
- [interceptors.ts](/home/carl/git/skt-vuetify-templates/src/services/interceptors.ts)
|
||||
- [error.ts](/home/carl/git/skt-vuetify-templates/src/services/error.ts)
|
||||
- [http-error.ts](/home/carl/git/skt-vuetify-templates/src/services/http-error.ts)
|
||||
- [http-toast.ts](/home/carl/git/skt-vuetify-templates/src/services/http-toast.ts)
|
||||
- [session.ts](/home/carl/git/skt-vuetify-templates/src/services/session.ts)
|
||||
- [token.ts](/home/carl/git/skt-vuetify-templates/src/services/token.ts)
|
||||
- [client.ts](../src/services/client.ts)
|
||||
- [interceptors.ts](../src/services/interceptors.ts)
|
||||
- [error.ts](../src/services/error.ts)
|
||||
- [http-error.ts](../src/services/http-error.ts)
|
||||
- [http-toast.ts](../src/services/http-toast.ts)
|
||||
- [session.ts](../src/services/session.ts)
|
||||
- [token.ts](../src/services/token.ts)
|
||||
- `services/modules/*`
|
||||
|
||||
責任:
|
||||
@@ -272,61 +274,6 @@ layout 不應承擔:
|
||||
|
||||
## 目前已落地的分層模式
|
||||
|
||||
## Template Core 與 Demo 邊界
|
||||
|
||||
### Template Core
|
||||
|
||||
以下檔案屬於 template core,負責 app shell、layout、route、plugin、theme、HTTP 基礎設施與全域狀態:
|
||||
|
||||
- [main.ts](/home/carl/git/skt-vuetify-templates/src/main.ts)
|
||||
- [App.vue](/home/carl/git/skt-vuetify-templates/src/App.vue)
|
||||
- `src/router/index.ts`
|
||||
- `src/router/guards.ts`
|
||||
- `src/components/layouts/*`
|
||||
- `src/views/Login.vue`
|
||||
- `src/plugins/*`
|
||||
- `src/styles/*`
|
||||
- `src/services/client.ts`
|
||||
- `src/services/interceptors.ts`
|
||||
- `src/services/token.ts`
|
||||
- `src/services/session.ts`
|
||||
- `src/services/error.ts`
|
||||
- `src/services/http-error.ts`
|
||||
- `src/services/http-toast.ts`
|
||||
- `src/stores/auth.ts`
|
||||
- `src/stores/menu.ts`
|
||||
- `src/stores/breadcrumbs.ts`
|
||||
- `src/stores/favorites.ts`
|
||||
- `src/stores/messages.ts`
|
||||
- `src/stores/snackbar.ts`
|
||||
- `src/composables/layout/*`
|
||||
|
||||
一般功能開發優先不要修改 template core;只有需求明確要求改變框架行為時才調整。
|
||||
|
||||
`src/router/routes.ts` 是新增功能 route 的正式入口,可新增 route,但不要破壞既有 layout meta、auth meta 與 catch-all route 規則。
|
||||
|
||||
### Demo / Example
|
||||
|
||||
以下檔案偏向示範資料與範例頁,可在正式專案中替換或刪除:
|
||||
|
||||
- `src/views/Home.vue`
|
||||
- `src/components/PageIndex.vue`
|
||||
- `src/views/maint/*`
|
||||
- `src/components/maint/*`
|
||||
- `src/composables/maint/*`
|
||||
- `src/components/PageMaint.vue`
|
||||
- `src/stores/students.ts`
|
||||
- `src/stores/semesters.ts`
|
||||
- `src/views/FncPage.vue`
|
||||
- `src/views/Settings.vue`
|
||||
- `src/assets/logo.png`
|
||||
- `src/assets/logo.svg`
|
||||
- `src/assets/robot-svgrepo-com.svg`
|
||||
|
||||
`maint` 是可參考的 demo feature,不是所有新專案都必須保留的核心功能。
|
||||
|
||||
移除 demo/example 時,要同步清理 routes、menu、language、store import、component import 與 assets。
|
||||
|
||||
### 模式 1:`view -> page component -> page family components`
|
||||
|
||||
已落地頁面:
|
||||
@@ -351,11 +298,11 @@ layout 不應承擔:
|
||||
這一層目前是 maintenance 領域最清楚的結構:
|
||||
|
||||
- `views/maint/*` 承接 route 與頁面流程協調
|
||||
- [PageMaint.vue](/home/carl/git/skt-vuetify-templates/src/components/PageMaint.vue) 承接維護頁共用頁面骨架
|
||||
- [PageMaint.vue](../src/components/PageMaint.vue) 承接維護頁共用頁面骨架
|
||||
- `components/maint/*` 承接維護頁專用元件
|
||||
- `composables/maint/*` 承接 CRUD 流程、表單狀態與 editable grid 狀態
|
||||
|
||||
[EditableGrid.vue](/home/carl/git/skt-vuetify-templates/src/views/maint/EditableGrid.vue) 是目前最接近薄 view 的 maintenance 頁面。
|
||||
[EditableGrid.vue](../src/views/maint/EditableGrid.vue) 是目前最接近薄 view 的 maintenance 頁面。
|
||||
|
||||
### 模式 3:`router meta -> App.vue -> layout`
|
||||
|
||||
@@ -377,9 +324,9 @@ layout 不應承擔:
|
||||
|
||||
目前例子:
|
||||
|
||||
- [PageLogin.vue](/home/carl/git/skt-vuetify-templates/src/components/PageLogin.vue)
|
||||
- [PageIndex.vue](/home/carl/git/skt-vuetify-templates/src/components/PageIndex.vue)
|
||||
- [PageMaint.vue](/home/carl/git/skt-vuetify-templates/src/components/PageMaint.vue)
|
||||
- [PageLogin.vue](../src/components/PageLogin.vue)
|
||||
- [PageIndex.vue](../src/components/PageIndex.vue)
|
||||
- [PageMaint.vue](../src/components/PageMaint.vue)
|
||||
|
||||
### 資料夾命名
|
||||
|
||||
@@ -397,30 +344,6 @@ layout 不應承擔:
|
||||
- 不要為了抽象而保留含糊的舊前綴
|
||||
- 若元件只在 maint 領域使用,就留在 `components/maint`
|
||||
|
||||
## 目前仍待整理的區域
|
||||
|
||||
### 高優先度
|
||||
|
||||
- 繼續瘦身:
|
||||
- [SingleRecord.vue](/home/carl/git/skt-vuetify-templates/src/views/maint/SingleRecord.vue)
|
||||
- [MasterDetailA.vue](/home/carl/git/skt-vuetify-templates/src/views/maint/MasterDetailA.vue)
|
||||
- [MasterDetailB.vue](/home/carl/git/skt-vuetify-templates/src/views/maint/MasterDetailB.vue)
|
||||
- [MasterDetailC.vue](/home/carl/git/skt-vuetify-templates/src/views/maint/MasterDetailC.vue)
|
||||
|
||||
原因:
|
||||
|
||||
- 這些頁面仍保留較多頁面內資料轉換與事件協調
|
||||
|
||||
### 中優先度
|
||||
|
||||
- 檢查 `components/maint` 內是否仍有可再明確命名的舊名稱
|
||||
- 視 `PageMaint` 的後續演進,決定是否維持在 `components` 根目錄
|
||||
|
||||
### 中低優先度
|
||||
|
||||
- 持續檢查 `views` 是否有可再下放到 page component 的模板片段
|
||||
- 清理命名調整後留下的空資料夾或死連結
|
||||
|
||||
## 新增或修改檔案時的判斷準則
|
||||
|
||||
1. 這個檔案是否直接被 route 載入?
|
||||
|
||||
@@ -63,6 +63,7 @@ router -> App.vue -> layout -> view -> component -> composable/store -> service
|
||||
- 一般被主 layout 包住的頁面:參考 `src/views/Home.vue`、`src/views/maint/EditableGrid.vue`
|
||||
- 登入相關 UI:參考 `src/components/PageLogin.vue` 與 `src/components/login/*`
|
||||
- 維護頁:參考 `src/views/maint/*`、`src/components/maint/*`、`src/composables/maint/*`
|
||||
- 維護頁範本選擇:參考 `src/views/maint/README.md`
|
||||
- API 呼叫:參考 `src/services/modules/*` 與使用它們的 store/composable
|
||||
- 全域提示:參考 `src/stores/snackbar.ts` 與 `src/composables/useApiCall.ts`
|
||||
|
||||
@@ -91,6 +92,7 @@ router -> App.vue -> layout -> view -> component -> composable/store -> service
|
||||
- `src/stores/favorites.ts`
|
||||
- `src/stores/messages.ts`
|
||||
- `src/stores/snackbar.ts`
|
||||
- `src/stores/app.ts`
|
||||
- `src/composables/layout/*`
|
||||
|
||||
以下內容偏向 demo/example,建立正式專案時可依需求替換或刪除:
|
||||
|
||||
@@ -0,0 +1,337 @@
|
||||
# PageIndex 規格表
|
||||
|
||||
來源元件:`src/components/PageIndex.vue`
|
||||
|
||||
`PageIndex` 是首頁主畫面展示元件,負責組合歡迎區、最新消息、訊息中心入口、快速存取與最新消息 dialog。元件本身不直接呼叫後端 API;所有資料都透過 props 傳入,互動則透過 emit 交給外層 view 處理。
|
||||
|
||||
目前使用位置:`src/views/Home.vue`
|
||||
|
||||
## 功能總覽
|
||||
|
||||
| 功能區塊 | 功能說明 | 主要輸入 | 主要輸出事件 | 需要後端 API |
|
||||
|---|---|---|---|---|
|
||||
| 歡迎區 | 顯示固定歡迎文字與操作提示。 | 無 | 無 | 否,目前為靜態文案。 |
|
||||
| 最新消息列表 | 以 `v-data-iterator` 顯示消息清單,包含日期、月份、標題、NEW 標籤、摘要、單位與瀏覽次數。 | `newsItems` | `news(item)` | 一般需要;現況由 `Home.vue` 靜態陣列提供。 |
|
||||
| 最新消息詳情 dialog | 顯示被選取消息的標題、日期、單位、瀏覽次數與內容。開關狀態由外層控制。 | `selectedNews`, `isNewsDialogOpen` | `update:isNewsDialogOpen` | 視需求;若列表已含完整內容可不另打詳情 API,若需完整內文或附件則建議補 API。 |
|
||||
| 訊息中心入口 | 顯示訊息中心卡片與未讀文字,點擊後通知外層開啟訊息中心。 | 無 | `message-center` | 一般需要;現況文字 `12 筆未讀` 為靜態內容,點擊後只開啟共用 dialog。 |
|
||||
| 快速存取 | 顯示常用操作入口卡片。 | `quickItems` | `quick(item)` | 視需求;現況由 `Home.vue` 靜態陣列提供,點擊只顯示 snackbar。 |
|
||||
|
||||
## 現況資料來源
|
||||
|
||||
| 資料 | 目前來源 | 說明 | 後端需求 |
|
||||
|---|---|---|---|
|
||||
| `newsItems` | `src/views/Home.vue` 靜態陣列 | 包含 3 筆示意最新消息。 | 現況否;正式系統通常需要。 |
|
||||
| `quickItems` | `src/views/Home.vue` 靜態陣列 | 包含線上加選、線上退選、成績查詢、個人課表、網路請假、場地借用。 | 視需求。 |
|
||||
| `selectedNews` | `src/views/Home.vue` 本機 `ref` | 點擊消息後設定。 | 否。 |
|
||||
| `isNewsDialogOpen` | `src/views/Home.vue` 本機 `ref` | 控制消息 dialog 開關。 | 否。 |
|
||||
| 訊息中心開關 | `src/stores/messages.ts` | store 只管理 dialog 開關狀態,不包含訊息資料。 | 否,但訊息內容正式化時需要。 |
|
||||
| 訊息中心未讀文字 | `PageIndex.vue` 靜態文案 | 固定顯示 `12 筆未讀`。 | 正式系統建議需要。 |
|
||||
|
||||
## 一般建議補齊的 API 配合清單
|
||||
|
||||
這份清單是以一般後台首頁實作來看,列出 `PageIndex` 常見會需要後端配合的資料。現況沒有任何 API 直接供應 `PageIndex`;所有資料都是外層靜態資料或本機狀態。
|
||||
|
||||
| 類別 | 建議 API | 對應首頁功能 | 必要性 | 說明 |
|
||||
|---|---|---|---|---|
|
||||
| 最新消息列表 | `Announcement/GetLatest` 或 `News/GetLatest` | 最新消息列表 `newsItems` | 建議 | 回傳首頁要顯示的最新消息,通常需支援發布狀態、排序、置頂、有效日期與使用者可見範圍。 |
|
||||
| 最新消息詳情 | `Announcement/GetDetail` 或 `News/GetDetail` | 最新消息詳情 dialog | 視需求 | 若列表只回摘要,點擊後應用 detail API 取得完整內容、附件、連結或已讀狀態。 |
|
||||
| 消息瀏覽次數 | `Announcement/AddView` 或由 detail API 自動累計 | `views` 顯示 | 視需求 | 若瀏覽次數要準確,通常由後端統計;目前 `views` 是靜態文字。 |
|
||||
| 訊息未讀數 | `Message/GetUnreadCount` 或 `Notification/GetUnreadCounts` | 訊息中心入口未讀文字 | 建議 | 首頁卡片與 layout toolbar badge 可共用同一份未讀數 API。 |
|
||||
| 訊息清單 | `Message/GetMessages` | 訊息中心 dialog | 建議 | 點擊首頁訊息中心後應取得訊息列表;現況只開啟共用 dialog,訊息內容在 `App.vue` 仍是示意資料。 |
|
||||
| 訊息已讀 | `Message/MarkAsRead`, `Message/MarkAllAsRead` | 訊息中心互動與未讀數歸零 | 視需求 | 若訊息中心有未讀狀態,通常需要已讀更新 API。 |
|
||||
| 快速存取查詢 | `Shortcut/GetHomeShortcuts` 或 `Menu/GetQuickAccess` | 快速存取 `quickItems` | 視需求 | 若快速存取要依角色、權限或個人偏好變動,應由後端或既有選單資料推導。 |
|
||||
| 快速存取維護 | `Shortcut/SaveHomeShortcuts`, `Shortcut/UpdateOrder` | 自訂首頁快捷入口 | 可選 | 只有開放使用者自訂首頁快捷時才需要。 |
|
||||
| 快速存取導頁 | 可沿用 `Menu/GetMenu` 回傳路徑 | 快速存取點擊後導頁 | 建議 | 現況 `quickItems` 沒有 path,點擊只顯示 snackbar;正式系統應提供可導頁資訊。 |
|
||||
| 首頁統計摘要 | `Dashboard/GetSummary` | 未來若加入待辦、申請、課程、公告統計卡片 | 可選 | 目前 `PageIndex` 沒有統計卡片;只有產品需要首頁 dashboard 時才補。 |
|
||||
|
||||
## API 優先順序建議
|
||||
|
||||
| 優先順序 | API / 功能 | 建議理由 |
|
||||
|---|---|---|
|
||||
| 1 | `Announcement/GetLatest` | 最新消息是首頁主要內容,正式系統不應長期使用靜態資料。 |
|
||||
| 2 | `Message/GetUnreadCount` 或共用 `Notification/GetUnreadCounts` | 首頁訊息中心入口目前有固定未讀數,需改為真實資料。 |
|
||||
| 3 | `Message/GetMessages` | 點擊訊息中心後應顯示真實訊息清單。 |
|
||||
| 4 | 快速存取 path / 導頁資料 | 現況快速存取無法真的導頁,只顯示 snackbar。 |
|
||||
| 5 | `Announcement/GetDetail` | 若列表資料不足以顯示完整內容,再補詳情 API。 |
|
||||
| 6 | 快速存取自訂與排序 API | 屬個人化體驗,不影響首頁基本可用性,可後續處理。 |
|
||||
|
||||
## 建議 API 回傳格式
|
||||
|
||||
以下格式是給後端製作 API 時的建議契約。若沿用現有 service 包裝,前端實際讀取位置可能是 `res.data.data`;欄位命名可配合既有後端規範調整,但資料語意應保持一致。
|
||||
|
||||
### `Announcement/GetLatest` 或 `News/GetLatest`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "",
|
||||
"data": {
|
||||
"items": [
|
||||
{
|
||||
"id": 1,
|
||||
"title": "113學年度第2學期加退選開始",
|
||||
"summary": "加退選時間為1月29日至2月9日止,請同學把握時間完成選課作業。",
|
||||
"departmentId": "academic",
|
||||
"departmentName": "教務處",
|
||||
"publishedAt": "2026-01-29T09:00:00+08:00",
|
||||
"views": 1234,
|
||||
"isNew": true,
|
||||
"isPinned": false
|
||||
}
|
||||
],
|
||||
"total": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `Announcement/GetDetail` 或 `News/GetDetail`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"title": "113學年度第2學期加退選開始",
|
||||
"content": "加退選時間為1月29日至2月9日止,請同學把握時間完成選課作業。",
|
||||
"summary": "加退選時間為1月29日至2月9日止。",
|
||||
"departmentId": "academic",
|
||||
"departmentName": "教務處",
|
||||
"publishedAt": "2026-01-29T09:00:00+08:00",
|
||||
"views": 1235,
|
||||
"isNew": true,
|
||||
"attachments": [
|
||||
{
|
||||
"id": "file-1",
|
||||
"fileName": "加退選說明.pdf",
|
||||
"url": "/service/files/file-1"
|
||||
}
|
||||
],
|
||||
"links": [
|
||||
{
|
||||
"title": "前往選課系統",
|
||||
"url": "/course-add"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `Announcement/AddView`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "",
|
||||
"data": {
|
||||
"id": 1,
|
||||
"views": 1235
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `Message/GetUnreadCount`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "",
|
||||
"data": {
|
||||
"unreadCount": 12
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `Notification/GetUnreadCounts`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "",
|
||||
"data": {
|
||||
"notifications": 3,
|
||||
"messages": 12
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `Message/GetMessages`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "",
|
||||
"data": {
|
||||
"items": [
|
||||
{
|
||||
"id": "msg-1",
|
||||
"title": "系統維護提醒",
|
||||
"summary": "系統將於週六凌晨維護。",
|
||||
"sender": "資訊中心",
|
||||
"sentAt": "2026-05-07T09:00:00+08:00",
|
||||
"isRead": false,
|
||||
"link": "/messages/msg-1"
|
||||
}
|
||||
],
|
||||
"total": 1,
|
||||
"unreadCount": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `Message/MarkAsRead`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "已標記為已讀",
|
||||
"data": {
|
||||
"id": "msg-1",
|
||||
"isRead": true,
|
||||
"unreadCount": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `Message/MarkAllAsRead`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "已全部標記為已讀",
|
||||
"data": {
|
||||
"unreadCount": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `Shortcut/GetHomeShortcuts` 或 `Menu/GetQuickAccess`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "",
|
||||
"data": [
|
||||
{
|
||||
"id": "course-add",
|
||||
"title": "線上加選",
|
||||
"path": "/course-add",
|
||||
"icon": "mdiPlus",
|
||||
"sort": 1,
|
||||
"source": "menu"
|
||||
},
|
||||
{
|
||||
"id": "score-query",
|
||||
"title": "成績查詢",
|
||||
"path": "/score-query",
|
||||
"icon": "mdiChartBar",
|
||||
"sort": 2,
|
||||
"source": "menu"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### `Shortcut/SaveHomeShortcuts`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "快捷已儲存",
|
||||
"data": [
|
||||
{
|
||||
"id": "course-add",
|
||||
"title": "線上加選",
|
||||
"path": "/course-add",
|
||||
"icon": "mdiPlus",
|
||||
"sort": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### `Shortcut/UpdateOrder`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "排序已更新",
|
||||
"data": [
|
||||
{
|
||||
"id": "course-add",
|
||||
"sort": 1
|
||||
},
|
||||
{
|
||||
"id": "score-query",
|
||||
"sort": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### `Dashboard/GetSummary`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "",
|
||||
"data": {
|
||||
"todoCount": 2,
|
||||
"pendingApplicationCount": 1,
|
||||
"todayCourseCount": 4,
|
||||
"unreadMessageCount": 12,
|
||||
"latestAnnouncementCount": 3
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 可維持前端處理的功能
|
||||
|
||||
| 功能 | 原因 |
|
||||
|---|---|
|
||||
| 最新消息 dialog 開關 | 純 UI 狀態,使用 `selectedNews` 與 `isNewsDialogOpen` 即可。 |
|
||||
| 最新消息列表解包 `resolveNewsItem` | 只是處理 Vuetify `v-data-iterator` wrapper,不需後端配合。 |
|
||||
| 歡迎區文案 | 若各角色顯示相同文字,可維持靜態。 |
|
||||
| 快速存取卡片排版 | 展示方式屬前端 UI,不需後端參與。 |
|
||||
| 點擊快速存取後的前端導頁 | 只要資料含 path,router push 可由前端處理。 |
|
||||
|
||||
## Props 與狀態來源
|
||||
|
||||
| Prop / 狀態 | 用途 | 預設值或目前來源 | 後端需求 |
|
||||
|---|---|---|---|
|
||||
| `newsItems` | 最新消息列表資料。 | `Home.vue` 靜態陣列。 | 正式系統建議來自最新消息 API。 |
|
||||
| `quickItems` | 快速存取卡片資料。 | `Home.vue` 靜態陣列。 | 視需求,可由選單、權限或快捷 API 提供。 |
|
||||
| `selectedNews` | 最新消息 dialog 顯示的目前消息。 | `Home.vue` 點擊消息後設定。 | 否。 |
|
||||
| `isNewsDialogOpen` | 最新消息 dialog 開關。 | `Home.vue` 本機 `ref`。 | 否。 |
|
||||
|
||||
## 建議資料結構
|
||||
|
||||
### 最新消息 `NewsItem`
|
||||
|
||||
| 欄位 | 型別 | 用途 | API 建議 |
|
||||
|---|---|---|---|
|
||||
| `id` | `number` | 列表 key 與詳情查詢識別。 | 後端提供。 |
|
||||
| `date` | `string` | 日期 badge 的日期。 | 可由後端直接提供,或前端由發布日期格式化。 |
|
||||
| `month` | `string` | 日期 badge 的月份。 | 可由後端直接提供,或前端由發布日期格式化。 |
|
||||
| `title` | `string` | 消息標題。 | 後端提供。 |
|
||||
| `desc` | `string` | 消息摘要或內容。 | 列表 API 可回摘要;詳情 API 可回完整內容。 |
|
||||
| `dept` | `string` | 發布單位。 | 後端提供。 |
|
||||
| `views` | `string` | 瀏覽次數顯示文字。 | 建議後端回 number,前端格式化。 |
|
||||
| `isNew` | `boolean` | 是否顯示 NEW 標籤。 | 可由後端提供,或前端依發布日期推導。 |
|
||||
|
||||
### 快速存取 `QuickItem`
|
||||
|
||||
| 欄位 | 型別 | 用途 | API 建議 |
|
||||
|---|---|---|---|
|
||||
| `icon` | `string` | 卡片圖示文字。 | 若正式使用 MDI icon,建議改為 icon key 或路徑。 |
|
||||
| `title` | `string` | 卡片標題。 | 後端或前端設定提供。 |
|
||||
| `path` | `string` | 目前型別尚未定義;正式導頁建議補上。 | 建議由後端或 `Menu/GetMenu` 對應功能提供。 |
|
||||
|
||||
## 事件契約
|
||||
|
||||
| 事件 | 觸發時機 | 外層目前處理 |
|
||||
|---|---|---|
|
||||
| `news(item)` | 點擊最新消息卡片。 | `Home.vue` 設定 `selectedNews` 並開啟 dialog。 |
|
||||
| `message-center` | 點擊訊息中心卡片。 | `Home.vue` 呼叫 `messageStore.open()`。 |
|
||||
| `quick(item)` | 點擊快速存取卡片。 | `Home.vue` 顯示 snackbar:`前往:${item.title}`。 |
|
||||
| `update:isNewsDialogOpen(value)` | dialog 開關狀態變更或點擊關閉。 | `Home.vue` 寫回 `isNewsDialogOpen`。 |
|
||||
@@ -0,0 +1,430 @@
|
||||
# MainLayout 規格表
|
||||
|
||||
來源元件:`src/components/layouts/MainLayout.vue`
|
||||
|
||||
`MainLayout` 是預設後台版型的 app shell,負責組合側邊選單、頂部工具列、常用功能列、breadcrumb、內容區與輔助視窗。元件本身不直接呼叫後端 API;所有資料都透過 props 傳入,互動則透過 emit 交給外層處理。
|
||||
|
||||
## 功能總覽
|
||||
|
||||
| 功能區塊 | 功能說明 | 主要輸入 | 主要輸出事件 | 需要後端 API |
|
||||
|---|---|---|---|---|
|
||||
| 系統品牌區 | 顯示系統標題、副標題,或由 `title` slot 覆蓋。 | `systemTitle`, `systemSubtitle`, `title` slot | 無 | 否,目前為 props/default。 |
|
||||
| 使用者資訊 | 顯示使用者頭像文字、姓名、角色。可用 feature toggle 關閉。 | `userProfile`, `features.showUserInfo` | 無 | 否,目前為 props/default。 |
|
||||
| 側邊選單 | 桌面版顯示多層 drawer menu;支援展開群組、收合 rail、選單項目導頁。 | `menuItems`, `isRail`, `drawerConfig` | `select`, `toggle-sidebar`, `update:isRail` | 是,`menuItems` 目前由 `GetMenu` 取得後轉換。 |
|
||||
| 行動版選單 | 行動版 drawer 使用階層式選單面板,點擊有子層項目會進入下一層,點擊葉節點會選取並關閉 drawer。 | `menuItems`, Vuetify display 狀態 | `select`, `toggle-sidebar` | 是,資料同 `menuItems`,目前由 `GetMenu` 取得後轉換。 |
|
||||
| 行動版階層導覽 | 在 drawer 上方顯示「主選單」與目前進入的選單層級,可返回任一層。 | `menuItems` 衍生出的 `mobileMenuLevels` | 無 | 是,層級內容間接來自 `GetMenu`。 |
|
||||
| 常用功能列 | 桌面版顯示常用功能 chip,可選取、移除,也可顯示新增按鈕。 | `favoriteItems`, `favoritesConfig`, `favoritesBarVisible`, `features.showFavorites` | `select`, `add-favorite`, `remove-favorite`, `update:favoritesBarVisible` | 否,目前不是由後端提供;`GetFavorite` 已有 service/store 方法但登入流程中未啟用。 |
|
||||
| 行動版常用功能 | 行動版 drawer 可切換到常用功能面板並選取項目。 | `favoriteItems`, `features.showFavorites` | `select` | 否,目前不是由後端提供。 |
|
||||
| 搜尋列 | 輸入關鍵字後,按 Enter 或按鈕才觸發搜尋;觸發後清空輸入。 | `searchConfig`, `features.showSearch` | `search` | 否,`MainLayout` 只送出關鍵字;目前外層用已載入的選單做前端比對。 |
|
||||
| 工具列通知 | 顯示通知按鈕與 badge 數量。 | `toolbarActions.notificationsLabel`, `toolbarCounts.notifications` | `action('notifications')` | 否,目前只是按鈕與 props 數字。 |
|
||||
| 工具列訊息 | 顯示訊息按鈕與 badge 數量。 | `toolbarActions.messagesLabel`, `toolbarCounts.messages` | `action('messages')` | 否,目前外層開啟示意訊息 dialog,沒有 API。 |
|
||||
| 工具列設定 | 顯示設定 menu,可切換常用功能列與 breadcrumb 顯示狀態。 | `showFavoritesBar`, `breadcrumbBarVisible` | `update:favoritesBarVisible`, `update:breadcrumbBarVisible` | 否,屬本機 UI 狀態。 |
|
||||
| 登出 | 顯示登出按鈕,點擊後交由外層處理。 | `logoutLabel` | `logout` | 否,layout 本身不呼叫 API。 |
|
||||
| 主題切換 | feature 開啟時顯示主題切換按鈕,透過 `useThemeToggle` 切換 Vuetify theme。 | `features.showThemeToggle`, `themeToggleLabel` | `toggle-theme` | 否,本機 theme 狀態。 |
|
||||
| Breadcrumb | 桌面版顯示目前頁面路徑;未傳入項目時顯示預設首頁。可插入 `breadcrumb-actions` slot。 | `breadcrumbItems`, `breadcrumbConfig`, `breadcrumbBarVisible`, `features.showBreadcrumb` | `update:breadcrumbBarVisible`, `update:favoritesBarVisible` | 否,目前由外層依路由與已載入選單推導。 |
|
||||
| 內容區 | 以 `slot` 承載各頁面內容,並依 app bar 高度動態設定 `v-main` padding。 | default slot | 無 | 否。 |
|
||||
| 操作說明浮窗 | 收到 `help` action 時顯示暫時說明內容,可關閉。 | `toolbarActions.helpLabel` | `action('help')` | 否,目前內容為靜態文字,且 help 按鈕在子元件中未顯示。 |
|
||||
|
||||
## 後端 API 需求
|
||||
|
||||
| API | 目前狀態 | 呼叫位置 | 提供給 `MainLayout` 的資料 | Request | Response 對應 |
|
||||
|---|---|---|---|---|---|
|
||||
| `Menu/GetMenu` | 已啟用 | `src/views/Login.vue` 登入成功後呼叫 `menuStore.getMenu(authStore.user?.id ?? '')` | `menuItems` | `{ userID: string }` | `res.data.data` 存入 `menuStore.menu`,再由 `toLayoutMenuItems()` 轉成 layout 選單。 |
|
||||
| `Menu/GetFavorite` | 未啟用 | service/store 已存在,但登入流程呼叫被註解 | 無 | `{ userID: string }` | 若未來啟用,可轉成 `favoriteItems`;目前不列為後端需求。 |
|
||||
|
||||
## 一般建議補齊的 API 配合清單
|
||||
|
||||
這份清單是以一般後台系統實作來看,列出 `MainLayout` 常見會需要後端配合的資料。現況仍只有 `Menu/GetMenu` 已接上;其餘項目可依產品需求決定是否實作。
|
||||
|
||||
| 類別 | 建議 API | 對應 layout 功能 | 必要性 | 說明 |
|
||||
|---|---|---|---|---|
|
||||
| 選單與權限 | `Menu/GetMenu` | 側邊選單、行動版選單、前端選單搜尋、breadcrumb 推導 | 必要,已啟用 | 依使用者、角色、權限回傳可用功能。 |
|
||||
| 使用者資訊 | `User/GetCurrentUser` 或 `User/GetProfile` | 使用者資訊區 `userProfile` | 建議 | 回傳姓名、角色、單位、頭像文字或頭像 URL。現況使用 default props。 |
|
||||
| 常用功能查詢 | `Menu/GetFavorite` 或 `Favorite/GetFavorites` | 常用功能列、行動版常用功能 | 建議 | 若常用功能要跨裝置保存,就應由後端提供。現況 service/store 已有 `Menu/GetFavorite`,但登入流程未啟用。 |
|
||||
| 常用功能維護 | `Favorite/AddFavorite`, `Favorite/RemoveFavorite`, `Favorite/UpdateFavoriteOrder` | 新增常用、移除常用、常用排序 | 建議 | 現況常用功能主要由前端本機 store 處理;若要保存到帳號需補 API。 |
|
||||
| 未讀數量 | `Notification/GetUnreadCounts` | 通知 badge、訊息 badge `toolbarCounts` | 建議 | 可一次回傳 `{ notifications, messages }`,避免 layout 分別打多支 API。現況預設皆為 `0`。 |
|
||||
| 通知清單 | `Notification/GetNotifications` | 通知按鈕點擊後的通知列表 | 視需求 | 目前 layout 只 emit `action('notifications')`,外層尚未實作通知 UI。 |
|
||||
| 通知已讀 | `Notification/MarkAsRead`, `Notification/MarkAllAsRead` | 通知清單互動、badge 歸零 | 視需求 | 若有通知列表,通常需要搭配已讀狀態更新。 |
|
||||
| 訊息清單 | `Message/GetMessages` | 訊息按鈕點擊後的訊息 dialog | 建議 | 現況 `App.vue` 使用示意資料,不含 API。 |
|
||||
| 訊息已讀 | `Message/MarkAsRead`, `Message/MarkAllAsRead` | 訊息清單互動、badge 歸零 | 視需求 | 若訊息中心要顯示未讀數,通常需要已讀 API。 |
|
||||
| 搜尋 | `Search/SearchMenu` 或 `Search/GlobalSearch` | 搜尋列 | 視需求 | 只搜尋目前已載入選單可維持前端搜尋;若要搜尋公告、頁面、業務資料或權限內功能,應補後端搜尋 API。 |
|
||||
| 登出 | `Auth/Logout` 或 `Auth/RevokeToken` | 登出按鈕 | 視認證架構 | 若後端有 session、refresh token 或 token revoke 機制,需要呼叫後端;若只是清 local token,可維持前端處理。 |
|
||||
| 使用者偏好 | `UserPreference/GetLayoutSettings`, `UserPreference/SaveLayoutSettings` | 側欄收合、常用列顯示、breadcrumb 顯示、主題 | 可選 | 目前可用 localStorage/store 處理;只有需要跨裝置同步時才需要 API。 |
|
||||
| 操作說明 | `Help/GetPageHelp` 或 CMS API | 操作說明浮窗 | 可選 | 現況為靜態暫時文字,且 help 按鈕未顯示;若說明內容需依頁面、角色或版本管理才需要 API。 |
|
||||
|
||||
## API 優先順序建議
|
||||
|
||||
| 優先順序 | API / 功能 | 建議理由 |
|
||||
|---|---|---|
|
||||
| 1 | `Menu/GetMenu` | layout 最核心資料,決定使用者可見功能與導頁入口。 |
|
||||
| 2 | `User/GetCurrentUser` | 使用者資訊區不應長期使用假資料,且常被其他功能共用。 |
|
||||
| 3 | `Favorite/GetFavorites` 與常用功能維護 API | 常用功能若要符合使用者帳號體驗,需要後端保存。 |
|
||||
| 4 | `Notification/GetUnreadCounts` / `Message/GetMessages` | toolbar badge 與訊息中心目前是 demo 狀態,若要上線需補。 |
|
||||
| 5 | `Search/GlobalSearch` | 只有當搜尋範圍超過目前選單時才需要。 |
|
||||
| 6 | `UserPreference` 類 API | 屬體驗同步,不影響核心操作,可最後處理。 |
|
||||
|
||||
## 建議 API 回傳格式
|
||||
|
||||
以下格式是給後端製作 API 時的建議契約。若沿用現有 service 包裝,前端實際讀取位置可能是 `res.data.data`;欄位命名可配合既有後端規範調整,但資料語意應保持一致。
|
||||
|
||||
### `Menu/GetMenu`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "",
|
||||
"data": [
|
||||
{
|
||||
"mdl_id": "student",
|
||||
"mdl_name": "學生資訊",
|
||||
"children": [
|
||||
{
|
||||
"unt_id": "course",
|
||||
"unt_name": "選課作業",
|
||||
"children": [
|
||||
{
|
||||
"fnc_id": "course-add",
|
||||
"fnc_name": "線上加選"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### `User/GetCurrentUser` 或 `User/GetProfile`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "",
|
||||
"data": {
|
||||
"id": "A123456789",
|
||||
"name": "王小明",
|
||||
"role": "資訊工程系 - 學生",
|
||||
"avatarText": "王",
|
||||
"departmentId": "CS",
|
||||
"departmentName": "資訊工程系"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `Menu/GetFavorite` 或 `Favorite/GetFavorites`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "",
|
||||
"data": [
|
||||
{
|
||||
"id": "fav-1",
|
||||
"title": "線上加選",
|
||||
"path": "/course-add",
|
||||
"icon": "mdiPlus",
|
||||
"sort": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### `Favorite/AddFavorite`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "新增成功",
|
||||
"data": {
|
||||
"id": "fav-1",
|
||||
"title": "線上加選",
|
||||
"path": "/course-add",
|
||||
"icon": "mdiPlus",
|
||||
"sort": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `Favorite/RemoveFavorite`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "移除成功",
|
||||
"data": {
|
||||
"id": "fav-1",
|
||||
"path": "/course-add"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `Favorite/UpdateFavoriteOrder`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "排序已更新",
|
||||
"data": [
|
||||
{
|
||||
"id": "fav-1",
|
||||
"path": "/course-add",
|
||||
"sort": 1
|
||||
},
|
||||
{
|
||||
"id": "fav-2",
|
||||
"path": "/score-query",
|
||||
"sort": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### `Notification/GetUnreadCounts`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "",
|
||||
"data": {
|
||||
"notifications": 3,
|
||||
"messages": 12
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `Notification/GetNotifications`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "",
|
||||
"data": {
|
||||
"items": [
|
||||
{
|
||||
"id": "notice-1",
|
||||
"title": "系統維護提醒",
|
||||
"content": "系統將於週六凌晨維護。",
|
||||
"source": "資訊中心",
|
||||
"publishedAt": "2026-05-07T09:00:00+08:00",
|
||||
"isRead": false,
|
||||
"link": "/announcements/notice-1"
|
||||
}
|
||||
],
|
||||
"total": 1,
|
||||
"unreadCount": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `Notification/MarkAsRead`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "已標記為已讀",
|
||||
"data": {
|
||||
"id": "notice-1",
|
||||
"isRead": true,
|
||||
"unreadCount": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `Notification/MarkAllAsRead`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "已全部標記為已讀",
|
||||
"data": {
|
||||
"unreadCount": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `Message/GetMessages`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "",
|
||||
"data": {
|
||||
"items": [
|
||||
{
|
||||
"id": "msg-1",
|
||||
"title": "教務處公告",
|
||||
"summary": "加退選時間即將開始。",
|
||||
"sender": "教務處",
|
||||
"sentAt": "2026-05-07T10:30:00+08:00",
|
||||
"isRead": false,
|
||||
"link": "/messages/msg-1"
|
||||
}
|
||||
],
|
||||
"total": 1,
|
||||
"unreadCount": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `Message/MarkAsRead`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "已標記為已讀",
|
||||
"data": {
|
||||
"id": "msg-1",
|
||||
"isRead": true,
|
||||
"unreadCount": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `Message/MarkAllAsRead`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "已全部標記為已讀",
|
||||
"data": {
|
||||
"unreadCount": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `Search/SearchMenu` 或 `Search/GlobalSearch`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "",
|
||||
"data": {
|
||||
"items": [
|
||||
{
|
||||
"id": "course-add",
|
||||
"type": "menu",
|
||||
"title": "線上加選",
|
||||
"path": "/course-add",
|
||||
"parents": ["學生資訊", "選課作業"],
|
||||
"icon": "mdiPlus"
|
||||
}
|
||||
],
|
||||
"total": 1
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `Auth/Logout` 或 `Auth/RevokeToken`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "登出成功",
|
||||
"data": {
|
||||
"revoked": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `UserPreference/GetLayoutSettings`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "",
|
||||
"data": {
|
||||
"isRail": false,
|
||||
"favoritesBarVisible": true,
|
||||
"breadcrumbBarVisible": true,
|
||||
"themeName": "light"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `UserPreference/SaveLayoutSettings`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "設定已儲存",
|
||||
"data": {
|
||||
"isRail": false,
|
||||
"favoritesBarVisible": true,
|
||||
"breadcrumbBarVisible": true,
|
||||
"themeName": "light",
|
||||
"updatedAt": "2026-05-07T10:30:00+08:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `Help/GetPageHelp`
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message": "",
|
||||
"data": {
|
||||
"pageKey": "home",
|
||||
"title": "操作說明",
|
||||
"content": "這裡顯示目前頁面的操作說明。",
|
||||
"updatedAt": "2026-05-07T10:30:00+08:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 可維持前端處理的功能
|
||||
|
||||
| 功能 | 原因 |
|
||||
|---|---|
|
||||
| Breadcrumb 顯示與路徑推導 | 可由目前 route、`menuItems`、`favoriteItems` 推導,不一定要後端提供。 |
|
||||
| 側欄收合狀態 | 屬使用者介面偏好,localStorage 即可;除非要求跨裝置同步。 |
|
||||
| 常用列顯示 / breadcrumb 顯示 | 屬畫面偏好,localStorage/store 即可。 |
|
||||
| 主題切換 | 本機 theme 狀態即可;除非要求登入後跨裝置一致。 |
|
||||
| 前端選單搜尋 | 若搜尋範圍只限已載入的 `menuItems`,不需要後端 API。 |
|
||||
|
||||
## `GetMenu` 欄位轉換
|
||||
|
||||
| 後端節點層級 | 後端欄位 | Layout 欄位 | 說明 |
|
||||
|---|---|---|---|
|
||||
| 模組層 | `mdl_name` | `title` | 第一層選單標題。 |
|
||||
| 模組層 | `children` | `subItems` | 第二層單元清單。 |
|
||||
| 單元層 | `unt_name` | `title` | 第二層選單標題。 |
|
||||
| 單元層 | `children` | `subItems` | 第三層功能清單。 |
|
||||
| 功能層 | `fnc_name` | `title` | 葉節點功能名稱。 |
|
||||
| 功能層 | `fnc_id` | `path` | 有值時轉成 `/${fnc_id}`,作為 router path。 |
|
||||
| 模組層與單元層 | 無 | `navigable: false` | 群組節點預設不可導頁。 |
|
||||
|
||||
## Props 與狀態來源
|
||||
|
||||
| Prop / 狀態 | 用途 | 預設值或目前來源 | 後端需求 |
|
||||
|---|---|---|---|
|
||||
| `menuItems` | 桌面與行動版主選單。 | `App.vue` 使用 `menuStore.menuItems` 加上固定選單合併後傳入。 | 是,來自 `GetMenu`。 |
|
||||
| `favoriteItems` | 常用功能列與行動版常用面板。 | `App.vue` 合併 `menuStore.favoriteItems` 與 `favoritesStore.layoutItems`;目前 `GetFavorite` 未啟用。 | 否。 |
|
||||
| `breadcrumbItems` | Breadcrumb 顯示。 | `breadcrumbStore` 依 route、`menuItems`、`favoriteItems` 推導。 | 否。 |
|
||||
| `userProfile` | 使用者資訊區。 | `MainLayout` default props。 | 否。 |
|
||||
| `toolbarCounts` | 通知、訊息 badge。 | `MainLayout` default props,預設皆為 `0`。 | 否。 |
|
||||
| `searchConfig` | 搜尋 placeholder 與 label。 | `MainLayout` default props。 | 否。 |
|
||||
| `toolbarActions` | 通知、訊息、說明、設定 label。 | `MainLayout` default props。 | 否。 |
|
||||
| `favoritesConfig` | 常用列 label、新增按鈕 label、是否顯示新增。 | `MainLayout` default props。 | 否。 |
|
||||
| `breadcrumbConfig` | 首頁 breadcrumb label、disabled、icon。 | `MainLayout` default props。 | 否。 |
|
||||
| `features` | 控制主題切換、常用列、breadcrumb、搜尋、工具列、使用者資訊是否顯示。 | `MainLayout` default props。 | 否。 |
|
||||
| `drawerConfig` | drawer 寬度與 rail 寬度。 | `MainLayout` default props。 | 否。 |
|
||||
| `isRail` | 桌面側欄是否收合。 | `App.vue` 以 `v-model:is-rail` 綁定 `menuStore.isRail`,store 會寫入 localStorage。 | 否。 |
|
||||
| `favoritesBarVisible` | 常用功能列是否顯示。 | `App.vue` 以 `v-model:favorites-bar-visible` 綁定 `favoritesStore`。 | 否。 |
|
||||
| `breadcrumbBarVisible` | Breadcrumb 是否顯示。 | `App.vue` 以 `v-model:breadcrumb-bar-visible` 綁定 `favoritesStore`。 | 否。 |
|
||||
|
||||
## 事件契約
|
||||
|
||||
| 事件 | 觸發時機 | 外層目前處理 |
|
||||
|---|---|---|
|
||||
| `select(item)` | 選取側邊選單、常用功能或搜尋結果延伸選取時。 | `App.vue` 呼叫 `router.push(item.path)`。 |
|
||||
| `search(keyword)` | 搜尋列按 Enter 或搜尋按鈕。 | `App.vue` 以已載入的合併選單做前端搜尋並顯示 dialog。 |
|
||||
| `action(type)` | 點擊通知、訊息、說明等工具列 action。 | `messages` 會開啟訊息 dialog;其他目前無處理。 |
|
||||
| `logout` | 點擊登出按鈕。 | `App.vue` 清除 auth、tabs,導回 login。 |
|
||||
| `toggle-sidebar(payload)` | 點擊 drawer 收合/展開按鈕。 | 目前外層未綁定。 |
|
||||
| `toggle-theme(themeName)` | 切換主題成功。 | 目前外層未綁定。 |
|
||||
| `add-favorite` | 點擊常用功能新增按鈕。 | 目前外層未綁定。 |
|
||||
| `remove-favorite(item)` | 點擊常用 chip close。 | `App.vue` 從本機常用清單切換移除。 |
|
||||
| `update:isRail(value)` | 受控模式下更新側欄 rail 狀態。 | `v-model:is-rail` 寫回 `menuStore.isRail`。 |
|
||||
| `update:favoritesBarVisible(value)` | 更新常用列顯示狀態。 | `v-model:favorites-bar-visible` 寫回 `favoritesStore`。 |
|
||||
| `update:breadcrumbBarVisible(value)` | 更新 breadcrumb 顯示狀態。 | `v-model:breadcrumb-bar-visible` 寫回 `favoritesStore`。 |
|
||||
@@ -0,0 +1,91 @@
|
||||
# Maintenance View 複製指南
|
||||
|
||||
## 文件目的
|
||||
|
||||
`src/views/maint/*.vue` 是維護頁 demo/example。新增相似維護頁時,可以複製最接近的檔案再替換欄位、資料來源、文案、route 與 component import。
|
||||
|
||||
這份指南只說明應該從哪個 view 開始複製,不代表新功能一定要留在 `maint` 目錄。正式 feature 若有自己的 domain,優先建立 `src/views/<feature>`、`src/components/<feature>` 與 `src/composables/<feature>`。
|
||||
|
||||
## 共通規則
|
||||
|
||||
複製任何維護頁後,至少同步調整:
|
||||
|
||||
- `src/router/routes.ts` 的 `path`、`name`、`component` 與 `meta.layout`
|
||||
- 頁面標題、查詢欄位、表格欄位與 action 文案
|
||||
- form 型別、初始值、驗證規則與送出流程
|
||||
- store、service、composable 與 component import
|
||||
- 對應的語系、menu、breadcrumb 或 favorites 資料
|
||||
|
||||
一般維護頁 route 使用 `meta: { layout: 'default' }`。不要在 view 內直接 import 或包住 `MainLayout.vue`。
|
||||
|
||||
## 檔案選擇
|
||||
|
||||
### `EditableGrid.vue`
|
||||
|
||||
適合複製的情況:
|
||||
|
||||
- 頁面主體是可直接編輯的表格
|
||||
- view 只需要當 route 入口
|
||||
- 主要 UI 與狀態已經能放在單一 feature component
|
||||
|
||||
目前這個檔案只載入 `@/components/maint/EditableGrid.vue`。如果新頁面需要同樣的薄 view 形狀,優先複製這個檔案,再把 component import 換成新的 feature component。
|
||||
|
||||
### `SingleRecord.vue`
|
||||
|
||||
適合複製的情況:
|
||||
|
||||
- 主畫面是查詢條件加資料表
|
||||
- 使用者從資料表開啟單筆資料 dialog
|
||||
- dialog 只維護一個主檔表單
|
||||
- 需要新增、檢視、修改、刪除、換筆、未儲存變更確認
|
||||
|
||||
這是單主檔維護頁範本。若新需求沒有明細檔、巢狀清單或 master-detail 操作,優先從這個檔案開始。
|
||||
|
||||
### `MasterDetailA.vue`
|
||||
|
||||
適合複製的情況:
|
||||
|
||||
- dialog 需要同時呈現主檔與明細檔
|
||||
- desktop 需要主檔 card 搭配側邊明細 panel
|
||||
- 明細有獨立編輯狀態,使用者會先選一筆明細再編輯內容
|
||||
- mobile 需要在 master/detail panel 之間切換
|
||||
|
||||
這個版本的重點是 `DetailSidePanel` 與 `DetailNavigation`。如果明細內容比較像側邊抽屜或右側檢視編輯區,優先複製這個檔案。
|
||||
|
||||
### `MasterDetailB.vue`
|
||||
|
||||
適合複製的情況:
|
||||
|
||||
- dialog 需要主檔加多組可展開的明細群組
|
||||
- 明細適合用 collapse/accordion 方式呈現
|
||||
- desktop 希望主檔與明細在同一個 full-height card 內操作
|
||||
- mobile detail 需要全高明細 panel
|
||||
|
||||
這個版本的重點是 `DetailCollapseGropus` 與 `DetailFullHeightPanel`。如果明細資料有群組、階層或大量列項,優先複製這個檔案。
|
||||
|
||||
### `MasterDetailC.vue`
|
||||
|
||||
適合複製的情況:
|
||||
|
||||
- dialog 需要主檔加簡化明細清單
|
||||
- 明細操作比 `MasterDetailB.vue` 輕量
|
||||
- desktop 主要是在主檔表單下方操作簡單清單
|
||||
- mobile 需要獨立明細 panel,但不需要 full-height collapse 群組
|
||||
|
||||
這個版本的重點是 `DetailSimpleList` 與 `CourseMobilePanel`。如果明細資料較少、互動較直接,優先複製這個檔案。
|
||||
|
||||
## 不建議直接複製的情況
|
||||
|
||||
- 只新增一般靜態或 dashboard 頁面:參考 `src/views/Home.vue`
|
||||
- 只新增登入頁區塊:修改 `src/components/login/*`
|
||||
- 只新增共用 dialog 或基礎元件:放到適合的 feature component,必要時才放 `src/components/base`
|
||||
- 新頁面屬於正式 domain:複製後應改放到新 domain 目錄,不要把所有正式功能都塞進 `maint`
|
||||
|
||||
## 複製後的瘦身方向
|
||||
|
||||
`SingleRecord.vue`、`MasterDetailA.vue`、`MasterDetailB.vue`、`MasterDetailC.vue` 仍偏厚。若複製後要長期維護,優先把下列內容拆出:
|
||||
|
||||
- 大段表單欄位拆到 `src/components/<feature>`
|
||||
- 可重用的表格 action、dialog content 或 detail panel 拆到 feature component
|
||||
- 表單狀態、CRUD 流程、明細編輯流程拆到 `src/composables/<feature>`
|
||||
- 跨頁共享資料或快取才放到 `src/stores`
|
||||
Reference in New Issue
Block a user