Pivot Module 執行計劃
概述
建立多頁籤數據透視查詢模組,參考 transfer 模組的設計架構,使用相同的技術棧與 UI/UX 模式,實現法會報名資料的多維度分析與展示。
技術架構
前端技術
- 框架: Vue.js 2.x + Vuetify 2.x(與 transfer 模組一致)
- 表格元件: v-data-table(Vuetify 內建表格元件)
- 頁籤元件: v-tabs / v-tab / v-tab-item(Vuetify 頁籤)
- UI 框架: Bootstrap 5 + Bootstrap Icons(MasterPage)
- 樣式: 與 transfer 模組保持一致的視覺風格
後端 API
- 框架: ASP.NET Web API(C#)
- ORM: Entity Framework + LINQ
- 控制器:
App_Code/api/pivotController.cs(已建立) - 資料庫視圖:
報名明細查詢(SQL View)
資料流架構(重要)★
查詢流程:
┌─────────────┐
│ Tab 1 │ → 選擇法會 → API 查詢一次 →
│ 查詢條件 │ (完整資料集)
└─────────────┘
↓
┌─────────────────────────────────────────┐
│ Vue Data (存於前端 this.rawData) │
│ - 完整報名明細 │
│ - 一次性載入,不重複查詢 │
└─────────────────────────────────────────┘
↓
┌──────┬──────┬──────┬──────┬──────┐
│Tab 2 │Tab 3 │Tab 4 │Tab 5 │Tab 6 │
│明細 │信眾 │收入 │趨勢 │對比 │
│ │ │ │ │ │
│ 純前端計算 / 過濾 / 分組 / 統計 │
│ 使用 computed / methods / filters │
└──────────────────────────────────────┘
優點:
- ✅ 效能優化: API 只查詢一次,減少伺服器負載
- ✅ 即時響應: 切換頁籤無延遲,使用者體驗佳
- ✅ 離線分析: 資料載入後可離線操作(過濾、排序、統計)
- ✅ 減少流量: 不重複傳輸相同資料
- ✅ 一致性: 所有頁籤基於同一份資料,確保一致性
技術實現:
this.rawData: 原始完整資料(Tab 1 查詢後存入)computed properties: 各頁籤的資料來源(動態計算)methods: 過濾、分組、統計邏輯watch: 監聽過濾條件變化
元件規格
- 日期選擇器:
v-date-picker或<input type="date"> - 下拉選單:
v-select(年份、月份、法會選擇) - 資料表格:
v-data-table(分頁、排序、過濾) - 頁籤切換:
v-tabs(Tab 1~N) - 按鈕群組:
v-btn(查詢、匯出、重設) - 載入狀態:
:loading="loading" - 視覺標記: Bootstrap Badge(橙、藍、綠、紫色標籤)
頁籤設計
Tab 1: 查詢條件設定
功能目標: 提供查詢條件,篩選法會並選擇目標法會
UI 布局
+--------------------------------------------------------------+
| [查詢條件] |
|--------------------------------------------------------------|
| 時間範圍: [年份 ▼] [月份 ▼] [查詢法會] |
|--------------------------------------------------------------|
| 法會清單: |
| +----------------------------------------------------------+ |
| | 序號 | 法會名稱 | 開始日期 | 結束日期 | 報名人數 | 操作 | |
| +----------------------------------------------------------+ |
| | 1 | 2025春季法會 | 2025-03-01 | 2025-03-15 | 120 | [選擇] | |
| | 2 | 2025夏季法會 | 2025-06-01 | 2025-06-20 | 85 | [選擇] | |
| +----------------------------------------------------------+ |
+--------------------------------------------------------------+
查詢流程
- 選擇年份(2020
2025)或月份(112) - 點擊「查詢法會」按鈕
- API 回傳該期間的法會清單(
api/pivot/activity_stats) - 表格呈現法會清單(法會名稱、日期、統計)
- 點擊「選擇」按鈕,載入該法會的詳細資料
- 自動切換到 Tab 2(詳細資料頁籤)
API 整合
- 端點:
GET api/pivot/activity_stats?startDate={start}&endDate={end} - 回傳: 法會清單(含報名統計)
資料查詢策略
// 選擇法會後,一次性載入完整資料
selectActivity(item) {
this.loading = true;
this.selectedActivity = item;
// 一次性查詢完整報名明細(不分頁)
axios.get('/api/pivot/registration_details', {
params: {
activityNum: item.法會ID,
pageSize: 9999 // 取得全部資料
}
}).then(response => {
// 存入原始資料(供所有頁籤使用)
this.rawData = response.data.data.list;
// 自動切換到 Tab 2
this.activeTab = 1;
this.loading = false;
});
}
元件範例
<v-select
:items="yearOptions"
v-model="selectedYear"
label="年份"
dense
outlined
></v-select>
<v-select
:items="monthOptions"
v-model="selectedMonth"
label="月份"
dense
outlined
clearable
></v-select>
<v-btn color="primary" @click="loadActivities">查詢法會</v-btn>
<v-data-table
:headers="activityHeaders"
:items="activities"
:loading="loading"
item-key="法會ID"
>
<template v-slot:item.actions="{ item }">
<v-btn small color="success" @click="selectActivity(item)">選擇</v-btn>
</template>
</v-data-table>
Tab 2: 報名明細資料
功能目標: 完整呈現該場法會的所有報名明細
UI 布局
+--------------------------------------------------------------+
| [報名明細] 法會: 2025春季法會 (2025-03-01 ~ 2025-03-15) |
|--------------------------------------------------------------|
| 過濾: [信眾姓名] [功德類型 ▼] [狀態 ▼] [查詢] [匯出Excel] |
|--------------------------------------------------------------|
| +----------------------------------------------------------+ |
| | 報名編號 | 報名日期 | 信眾姓名 | 功德名稱 | 數量 | 金額 | |
| +----------------------------------------------------------+ |
| | 20250301001 | 2025-03-01 | 張三 | 點燈 | 1 | 500 | |
| | 20250301002 | 2025-03-01 | 李四 | 安太歲 | 1 | 300 | |
| +----------------------------------------------------------+ |
| 第 1 頁,共 10 頁(共 200 筆) |
+--------------------------------------------------------------+
功能特性
- 欄位顯示: 報名編號、報名日期、信眾姓名、功德名稱、數量、金額、已收、未收
- 過濾條件: 信眾姓名(模糊搜尋)、功德類型(下拉選單)、功德主(是/否)
- 排序: 可依任意欄位排序(升序/降序)
- 分頁: 預設每頁 50 筆,可調整(10/20/50/100)
- 匯出: 匯出 Excel/CSV
欄位色彩標記(參考 Excel 視圖)
- 橙色(法會資料): 法會ID、法會名稱、開始日期、結束日期
- 藍色(信眾資料): 信眾編號、信眾姓名
- 綠色(功德資訊): 報名編號、報名日期、功德主、功德類型、功德名稱
- 紫色(計算欄位): 數量、金額、已收、未收
使用 Bootstrap Badge 或背景色區隔:
<span class="badge bg-warning text-dark">法會</span>
<span class="badge bg-info">信眾</span>
<span class="badge bg-success">功德</span>
<span class="badge bg-secondary">計算</span>
資料來源(前端計算)
computed: {
// Tab 2: 報名明細(前端分頁、過濾)
filteredRegistrations() {
let data = this.rawData;
// 過濾:信眾姓名
if (this.filter.followerName) {
data = data.filter(x => x.信眾姓名.includes(this.filter.followerName));
}
// 過濾:功德類型
if (this.filter.itemKind) {
data = data.filter(x => x.功德類型 === this.filter.itemKind);
}
// 過濾:功德主
if (this.filter.isParent !== null) {
data = data.filter(x => x.功德主 === (this.filter.isParent ? '是' : '否'));
}
return data;
},
// 前端分頁
paginatedRegistrations() {
const start = (this.currentPage - 1) * this.pageSize;
const end = start + this.pageSize;
return this.filteredRegistrations.slice(start, end);
}
}
元件範例
<v-data-table
:headers="detailHeaders"
:items="registrations"
:loading="loading"
:server-items-length="totalCount"
:options.sync="options"
item-key="報名編號"
class="elevation-1"
>
<template v-slot:item.信眾姓名="{ item }">
<span class="badge bg-info me-1">信</span>{{ item.信眾姓名 }}
</template>
<template v-slot:item.金額="{ item }">
<span class="badge bg-secondary me-1">計</span>{{ item.金額 | currency }}
</template>
</v-data-table>
Tab 3: 信眾參與分析
功能目標: 統計信眾的參與情況(參與次數、金額、最近參與)
UI 布局
+--------------------------------------------------------------+
| [信眾參與分析] |
|--------------------------------------------------------------|
| 過濾: [信眾編號] [參與次數 ≥] [總金額 ≥] [查詢] |
|--------------------------------------------------------------|
| +----------------------------------------------------------+ |
| | 信眾編號 | 姓名 | 參與次數 | 總金額 | 最近參與日期 | |
| +----------------------------------------------------------+ |
| | F001 | 張三 | 5 | 2500 | 2025-03-01 | |
| | F002 | 李四 | 3 | 1500 | 2025-02-15 | |
| +----------------------------------------------------------+ |
+--------------------------------------------------------------+
功能特性
- 統計欄位: 參與次數、總金額、平均金額、最近參與日期
- 過濾條件: 信眾編號、參與次數閾值、總金額閾值
- 排序: 預設依參與次數降序
- 分頁: 預設每頁 50 筆
資料來源(前端計算)
computed: {
// Tab 3: 信眾參與分析(從 rawData 計算)
followerAnalysis() {
const followerMap = {};
this.rawData.forEach(item => {
const fNum = item.信眾編號;
if (!followerMap[fNum]) {
followerMap[fNum] = {
信眾編號: fNum,
姓名: item.信眾姓名,
參與次數: 0,
總金額: 0,
最近參與日期: item.報名日期
};
}
followerMap[fNum].參與次數++;
followerMap[fNum].總金額 += (item.金額 * item.數量);
// 更新最近參與日期
if (new Date(item.報名日期) > new Date(followerMap[fNum].最近參與日期)) {
followerMap[fNum].最近參與日期 = item.報名日期;
}
});
// 轉換為陣列,並計算平均金額
return Object.values(followerMap).map(f => ({
...f,
平均金額: Math.round(f.總金額 / f.參與次數)
})).sort((a, b) => b.參與次數 - a.參與次數); // 依參與次數降序
}
}
Tab 4: 收入統計分析
功能目標: 依時間、法會、功德類型統計收入
UI 布局
+--------------------------------------------------------------+
| [收入統計分析] |
|--------------------------------------------------------------|
| 分組方式: ( ) 月份 ( ) 年度 (•) 法會 ( ) 功德類型 |
|--------------------------------------------------------------|
| +----------------------------------------------------------+ |
| | 分組名稱 | 報名人數 | 總金額 | 已收 | 未收 | 收款率 | |
| +----------------------------------------------------------+ |
| | 2025春季法會 | 120 | 60000 | 50000 | 10000 | 83.3% | |
| | 2025夏季法會 | 85 | 45000 | 40000 | 5000 | 88.9% | |
| +----------------------------------------------------------+ |
+--------------------------------------------------------------+
功能特性
- 分組方式: 月份、年度、法會、功德類型
- 統計欄位: 報名人數、總金額、已收、未收、收款率
- 圖表呈現: 可加入 CanvasJS 長條圖/圓餅圖(選配)
- 匯出: 支援 Excel/CSV
資料來源(前端計算)
computed: {
// Tab 4: 收入統計分析(從 rawData 計算)
incomeStats() {
const statsMap = {};
const groupBy = this.groupBy; // 'monthly', 'yearly', 'activity', 'itemKind'
this.rawData.forEach(item => {
let key;
switch(groupBy) {
case 'monthly':
key = item.報名日期.substring(0, 7); // YYYY-MM
break;
case 'yearly':
key = item.報名日期.substring(0, 4); // YYYY
break;
case 'activity':
key = item.法會名稱;
break;
case 'itemKind':
key = item.功德類型;
break;
}
if (!statsMap[key]) {
statsMap[key] = {
分組名稱: key,
報名人數: 0,
總金額: 0,
已收: 0,
未收: 0
};
}
statsMap[key].報名人數++;
const amount = item.金額 * item.數量;
statsMap[key].總金額 += amount;
statsMap[key].已收 += item.已收 || 0;
statsMap[key].未收 += item.未收 || amount;
});
// 計算收款率
return Object.values(statsMap).map(s => ({
...s,
收款率: s.總金額 > 0 ? ((s.已收 / s.總金額) * 100).toFixed(1) + '%' : '0%'
}));
}
}
Tab 5: 趨勢分析
功能目標: 顯示時間序列趨勢(收入、參與人數、法會數量)
UI 布局
+--------------------------------------------------------------+
| [趨勢分析] |
|--------------------------------------------------------------|
| 指標: ( ) 收入 (•) 參與人數 ( ) 法會數量 |
| 時間間隔: ( ) 月份 (•) 季度 ( ) 年度 |
|--------------------------------------------------------------|
| [折線圖] |
| |
| +----------------------------------------------------------+ |
| | 時間 | 數值 | 成長率 | |
| +----------------------------------------------------------+ |
| | 2025-01 | 120 | +10% | |
| | 2025-02 | 132 | +10% | |
| +----------------------------------------------------------+ |
+--------------------------------------------------------------+
功能特性
- 指標選擇: 收入、參與人數、法會數量
- 時間間隔: 月份、季度、年度
- 成長率計算: 較前期成長率
- 圖表: CanvasJS 折線圖(選配)
資料來源(前端計算)
computed: {
// Tab 5: 趨勢分析(從 rawData 計算)
trendAnalysis() {
const metric = this.trendMetric; // 'income', 'followers', 'count'
const interval = this.trendInterval; // 'monthly', 'quarterly', 'yearly'
const trendMap = {};
this.rawData.forEach(item => {
let key;
switch(interval) {
case 'monthly':
key = item.報名日期.substring(0, 7); // YYYY-MM
break;
case 'quarterly':
const month = parseInt(item.報名日期.substring(5, 7));
const quarter = Math.ceil(month / 3);
key = `${item.報名日期.substring(0, 4)}-Q${quarter}`;
break;
case 'yearly':
key = item.報名日期.substring(0, 4); // YYYY
break;
}
if (!trendMap[key]) {
trendMap[key] = { 時間: key, 收入: 0, 人數: 0, 次數: 0 };
}
trendMap[key].收入 += (item.金額 * item.數量);
trendMap[key].人數++; // 簡化計算,實際可用 Set 去重
trendMap[key].次數++;
});
// 轉換為陣列並排序
const result = Object.values(trendMap).sort((a, b) => a.時間.localeCompare(b.時間));
// 計算成長率
return result.map((item, index) => {
if (index === 0) {
return { ...item, 數值: item[metric === 'income' ? '收入' : metric === 'followers' ? '人數' : '次數'], 成長率: '-' };
}
const prev = result[index - 1];
const currentValue = item[metric === 'income' ? '收入' : metric === 'followers' ? '人數' : '次數'];
const prevValue = prev[metric === 'income' ? '收入' : metric === 'followers' ? '人數' : '次數'];
const growthRate = prevValue > 0 ? (((currentValue - prevValue) / prevValue) * 100).toFixed(1) : '0';
return { ...item, 數值: currentValue, 成長率: growthRate + '%' };
});
}
}
Tab 6: 對比分析(選配)
功能目標: 不同時期、法會的對比分析
UI 布局
+--------------------------------------------------------------+
| [對比分析] |
|--------------------------------------------------------------|
| 對比類型: (•) 法會對比 ( ) 年度對比 |
| 期間1: [2025春季法會 ▼] 期間2: [2024春季法會 ▼] |
|--------------------------------------------------------------|
| +----------------------------------------------------------+ |
| | 指標 | 期間1 | 期間2 | 差異 | 差異率 | |
| +----------------------------------------------------------+ |
| | 報名人數 | 120 | 100 | +20 | +20% | |
| | 總金額 | 60000 | 50000 | +10000 | +20% | |
| +----------------------------------------------------------+ |
+--------------------------------------------------------------+
資料來源(前端計算)
computed: {
// Tab 6: 對比分析(從 rawData 計算)
// 注意:對比分析可能需要跨法會資料,如需要可額外查詢
comparativeAnalysis() {
// 如果只在單一法會內對比(如月份對比),可用 rawData
// 如果需要跨法會對比,建議另外查詢或在 Tab 1 時一併載入多場法會資料
const period1Data = this.rawData.filter(x => {
// 依 period1 條件過濾
return this.isPeriod1(x);
});
const period2Data = this.rawData.filter(x => {
// 依 period2 條件過濾
return this.isPeriod2(x);
});
const stats1 = this.calculateStats(period1Data);
const stats2 = this.calculateStats(period2Data);
return [
{ 指標: '報名人數', 期間1: stats1.count, 期間2: stats2.count, 差異: stats1.count - stats2.count },
{ 指標: '總金額', 期間1: stats1.amount, 期間2: stats2.amount, 差異: stats1.amount - stats2.amount },
// ... 其他指標
];
}
}
視覺設計規範
色彩系統(參考 transfer)
- 主色調: Bootstrap 5 預設配色
- 成功/確認:
bg-success/text-success - 警告:
bg-warning/text-warning - 危險/錯誤:
bg-danger/text-danger - 資訊:
bg-info/text-info - 次要:
bg-secondary/text-muted
欄位色彩標記(對應 Excel)
<!-- 橙色:法會資料 -->
<span class="badge bg-warning text-dark">法</span>
<!-- 藍色:信眾資料 -->
<span class="badge bg-info">信</span>
<!-- 綠色:功德資訊 -->
<span class="badge bg-success">功德</span>
<!-- 紫色:計算欄位 -->
<span class="badge bg-secondary">計</span>
表格樣式
/* 與 transfer 保持一致 */
.v-data-table th {
background-color: #f5f5f5 !important;
font-weight: bold;
}
.v-data-table tbody tr:hover {
background-color: #f0f8ff !important;
}
/* 欄位色彩標記 */
.field-activity { border-left: 3px solid #ffc107; } /* 橙 */
.field-follower { border-left: 3px solid #17a2b8; } /* 藍 */
.field-merit { border-left: 3px solid #28a745; } /* 綠 */
.field-calculated { border-left: 3px solid #6c757d; } /* 紫 */
API 端點總覽
| 端點 | 方法 | 功能 | 對應頁籤 | 使用時機 |
|---|---|---|---|---|
/api/pivot/activity_stats |
GET | 查詢法會清單與統計 | Tab 1 | 選擇查詢條件時 |
/api/pivot/registration_details |
GET | 報名明細查詢(完整資料) | Tab 1 | 選擇法會後一次性載入 ★ |
/api/pivot/registration_details_export |
GET | 報名明細匯出 | Tab 2 | 匯出 Excel 時(選配) |
/api/pivot/excel_data_structured |
GET | Excel 數據連接 | 外部 | Power Query/Power Pivot |
重要說明:
- ✅ Tab 2~6 不呼叫 API,全部使用前端
computed計算 - ✅
registration_details查詢時使用pageSize=9999取得完整資料 - ✅ 原
follower_analysis,income_stats,trend_analysis,comparative_analysis端點保留備用,但前端優先使用 computed - ✅ 如資料量過大(>5000 筆),可調整策略改用分頁查詢
檔案結構
admin/pivot/
├── index.aspx # 首頁(已完成)
├── index.aspx.cs # 首頁邏輯(已完成)
├── query.aspx # 多頁籤查詢頁面(待建立)★
├── query.aspx.cs # 查詢頁面邏輯(待建立)★
└── README.md # 本文件
App_Code/api/
└── pivotController.cs # API 控制器(已完成)
實作步驟
Phase 1: 建立查詢頁面骨架
- ✅ 建立
query.aspx(參考 transfer/verify.aspx) - ✅ 建立
query.aspx.cs(參考 transfer/verify.aspx.cs) - ✅ 引入 Vue.js + Vuetify
- ✅ 建立頁籤結構(v-tabs)
Phase 2: 實作 Tab 1(查詢條件)
- ✅ 年份/月份選擇器
- ✅ 查詢法會按鈕與 API 整合(
activity_stats) - ✅ 法會清單表格(v-data-table)
- ✅ 選擇法會邏輯(一次性載入完整資料)
- ✅
this.rawData資料結構設計
Phase 3: 實作 Tab 2(報名明細)
- ✅ 報名明細表格(前端分頁、排序、過濾)
- ✅
computed: filteredRegistrations實作 - ✅ 欄位色彩標記(badge)
- ✅ 匯出功能(選配)
Phase 4: 實作 Tab 3~6(分析頁籤)
- ✅ 信眾參與分析(Tab 3)-
computed: followerAnalysis - ✅ 收入統計分析(Tab 4)-
computed: incomeStats - ✅ 趨勢分析(Tab 5)-
computed: trendAnalysis - ✅ 對比分析(Tab 6,選配)-
computed: comparativeAnalysis
Phase 5: 優化與測試
- ✅ UI/UX 調整(與 transfer 保持一致)
- ✅ 效能優化(分頁、快取)
- ✅ 瀏覽器相容性測試
- ✅ 權限控制(ezAuthorize)
參考範例
1. transfer/verify.aspx
- 多階段流程設計(程序1、程序2)
- v-data-table 表格元件使用
- 信眾選擇對話框(v-dialog)
- 狀態選擇(v-select)
2. transfer/verify1.aspx
- 單階段流程設計
- 簡潔的查詢與確認流程
3. transfer/index.aspx
- 功能入口頁面設計
- Bootstrap Icons + Badge
- 三欄式布局
注意事項
- 元件一致性: 所有元件、樣式、命名均與 transfer 模組保持一致
- API 規範: 遵循 RESTful 設計,統一回傳格式
- 權限控制: 所有 API 加上
[ezAuthorize] - 效能考量:
- ✅ 前端計算策略: Tab 1 查詢一次,Tab 2~6 使用 Vue computed 計算
- ✅ 資料量控制: 單一法會報名明細預估 <5000 筆,適合前端處理
- ⚠️ 大資料處理: 若單場法會 >5000 筆,可改用 API 分頁查詢
- ✅ 記憶體管理: 切換法會時清除舊資料(
this.rawData = [])
- 視覺區隔: 使用 Badge、邊框色、背景色標記欄位類型
- 使用者體驗: 載入狀態(loading)、錯誤提示(alert)、空資料提示
- 前端效能優化:
- 使用
computed而非methods(自動快取) - 大型陣列操作使用
Object.freeze()凍結原始資料 - v-data-table 啟用虛擬滾動(
:virtual-scroll="true",資料量 >1000 時)
- 使用
SQL View 參考
CREATE VIEW [dbo].[報名明細查詢]
AS
SELECT dbo.activity.num AS 法會ID, dbo.activity.subject AS 法會名稱, dbo.activity.startDate_solar AS 開始日期, dbo.activity.endDate_solar AS 結束日期,
dbo.followers.f_number AS 信眾編號, dbo.followers.u_name AS 信眾姓名, dbo.pro_order.order_no AS 報名編號, dbo.pro_order.up_time AS 報名日期,
CASE WHEN parent_num IS NOT NULL THEN '是' ELSE '否' END AS 功德主, dbo.actItem_kind.kind AS 功德類型, dbo.actItem.subject AS 功德名稱,
dbo.pro_order_detail.qty AS 數量, dbo.pro_order_detail.price AS 金額, 0 AS 已收, dbo.pro_order_detail.price * dbo.pro_order_detail.qty - 0 AS 未收
FROM dbo.pro_order_detail INNER JOIN
dbo.pro_order ON dbo.pro_order_detail.order_no = dbo.pro_order.order_no INNER JOIN
dbo.actItem ON dbo.pro_order_detail.actItem_num = dbo.actItem.num INNER JOIN
dbo.activity ON dbo.pro_order.activity_num = dbo.activity.num INNER JOIN
dbo.followers ON dbo.pro_order.f_num = dbo.followers.num INNER JOIN
dbo.actItem_kind ON dbo.actItem.kind = dbo.actItem_kind.num
GO
資料結構範例
// Vue data 結構
data() {
return {
// 原始完整資料(Tab 1 查詢後存入,供所有頁籤使用)
rawData: [], // Array<報名明細物件>
// 選中的法會
selectedActivity: null,
// 當前頁籤索引
activeTab: 0, // 0=Tab1, 1=Tab2, 2=Tab3...
// Tab 2 過濾條件
filter: {
followerName: '',
itemKind: null,
isParent: null
},
// Tab 4 分組方式
groupBy: 'activity', // 'monthly', 'yearly', 'activity', 'itemKind'
// Tab 5 趨勢設定
trendMetric: 'income', // 'income', 'followers', 'count'
trendInterval: 'monthly', // 'monthly', 'quarterly', 'yearly'
// 載入狀態
loading: false
}
}
Vue Computed 效能考量
computed: {
// 使用 Object.freeze() 凍結大型陣列,提升效能
frozenRawData() {
return Object.freeze(this.rawData);
},
// 各頁籤 computed 基於 frozenRawData
filteredRegistrations() {
return this.frozenRawData.filter(/* 過濾邏輯 */);
}
}
執行確認
請檢視以上計劃,確認以下事項:
- ✅ 頁籤設計(Tab 1~6)符合需求
- ✅ 查詢流程(年/月 → 法會清單 → 明細資料)清晰
- ✅ 視覺區隔(色彩標記、Badge)符合 Excel 概念
- ✅ 技術架構(Vue + Vuetify + API)與 transfer 一致
- ✅ 功能完整性(查詢、過濾、排序、匯出)
- ✅ **資料流架構(一次查詢 + 前端計算)**合理且高效 ★
確認後即開始實作 Phase 1(建立查詢頁面骨架)。