5.8 KiB
5.8 KiB
Draft 欄位改進方案
問題描述
原本的 draft 欄位被用於兩種不同目的,導致資料結構混亂:
- 暫存沖帳分配 - 在個人沖帳流程中暫存使用者的沖帳金額分配
- 歷史沖帳記錄 - 記錄已完成的沖帳明細
這導致兩種不同用途的資料互相覆蓋,造成資料不一致的問題。
改進方案
將原本的純陣列格式改為物件格式,包含兩個子陣列:
新的 draft 欄位格式
{
"transfer_draft": [
{
"pro_order_detail_num": "訂單明細編號",
"reconcile": "沖帳金額"
}
],
"pro_order_detail_items": [
{
"pro_order_detail_num": "訂單明細編號",
"reconcile": "沖帳金額",
"activity_name": "活動名稱",
"actitem_name": "項目名稱",
"price": "原始金額",
"register_date": "報名日期",
"order_no": "訂單編號"
}
]
}
1. transfer_draft - 暫存沖帳分配
用途:
- 在
personal_reconcile.aspx中暫存使用者的沖帳金額分配 - 顯示 📝 圖示表示有暫存資料
- 支援「暫存」和「重新分配」功能
2. pro_order_detail_items - 沖帳明細記錄
用途:
- 在
balance_reconcile.aspx中顯示歷史沖帳記錄 - 在
balance_reconcile_query.aspx中顯示選取項目 - 包含完整的活動和項目資訊
向後相容性
程式碼會自動檢測格式並處理:
新格式(物件)
{
"transfer_draft": [...],
"pro_order_detail_items": [...]
}
舊格式(陣列)
[
{
"pro_order_detail_num": "12345",
"reconcile": 5000
}
]
修改的檔案
personal_reconcile.aspx
- 更新
loadFromDraftOrAutoDistribute()方法支援新舊格式 - 更新
saveDraft()方法使用新格式 - 新增
hasTransferDraft()方法檢查暫存資料 - 更新顯示邏輯使用新格式
balance_reconcile.aspx
- 更新歷史記錄載入邏輯支援新格式
- 更新詳細資訊顯示邏輯支援新格式
- 保持向後相容性
balance_reconcile_query.aspx
- 更新
getDraftItems()方法支援新舊格式 - 更新項目顯示邏輯
資料安全保護機制
為了確保 transfer_draft 和 pro_order_detail_items 的操作互不影響,實作了以下保護機制:
1. 統一工具函數
所有頁面都使用統一的 draft-utils.js 工具函數:
window.DraftUtils.getDraftObject(draft)- 安全解析 draft 欄位window.DraftUtils.getDraftField(draft, fieldName)- 安全取得特定欄位window.DraftUtils.updateDraftField(draft, fieldName, newValue)- 安全更新特定欄位window.DraftUtils.hasTransferDraft(draft)- 檢查是否有暫存資料window.DraftUtils.hasProOrderDetailItems(draft)- 檢查是否有歷史記錄
2. 操作範例
更新 transfer_draft(不會影響 pro_order_detail_items):
const currentDraft = this.dialog.selected.draft || '';
const newTransferDraft = this.dialog.items
.filter(item => Number(item.reconcile) > 0)
.map(item => ({
pro_order_detail_num: item.num,
reconcile: Number(item.reconcile)
}));
const newDraftObj = window.DraftUtils.updateDraftField(currentDraft, 'transfer_draft', newTransferDraft);
更新 pro_order_detail_items(不會影響 transfer_draft):
const currentDraft = item.draft || '';
const newDetailItems = [
{
pro_order_detail_num: "123",
reconcile: 5000,
activity_name: "法會",
actitem_name: "護持金"
}
];
const newDraftObj = window.DraftUtils.updateDraftField(currentDraft, 'pro_order_detail_items', newDetailItems);
檢查是否有暫存資料:
if (window.DraftUtils.hasTransferDraft(item.draft)) {
console.log('有暫存資料');
}
取得特定欄位:
const transferDraft = window.DraftUtils.getDraftField(item.draft, 'transfer_draft');
const detailItems = window.DraftUtils.getDraftField(item.draft, 'pro_order_detail_items');
3. 統一工具檔案
建立了 draft-utils.js 統一工具檔案,所有頁面都引用此檔案:
- 所有 draft 操作函數統一管理
- 格式驗證功能
- 向後相容性處理
- 詳細的使用範例
- 避免程式碼重複,提升維護性
4. 頁面引用方式
每個 .aspx 頁面都在 <script> 標籤前加入:
<script src="draft-utils.js"></script>
然後使用 window.DraftUtils 來呼叫工具函數,確保所有頁面使用相同的邏輯。
5. 完整工具函數清單
draft-utils.js 提供以下工具函數:
基本操作:
getDraftObject(draft)- 解析 draft 欄位,返回標準化物件getDraftField(draft, fieldName)- 安全取得特定欄位updateDraftField(draft, fieldName, newValue)- 安全更新特定欄位clearDraftField(draft, fieldName)- 清除特定欄位
檢查函數:
hasTransferDraft(draft)- 檢查是否有暫存資料hasProOrderDetailItems(draft)- 檢查是否有歷史記錄
工具函數:
mergeDraftObjects(draft1, draft2)- 合併兩個 draft 物件validateDraftFormat(draft)- 驗證 draft 格式getDraftSummary(draft)- 取得 draft 摘要資訊migrateLegacyFormat(draft)- 將舊格式轉換為新格式cleanEmptyDraft(draft)- 清理空的 draft 欄位formatDraftJson(draft)- 格式化 draft JSON 為可讀字串
優點
- 職責分離 - 每個子陣列有明確的用途
- 資料一致性 - 避免不同用途的資料互相覆蓋
- 向後相容 - 支援舊格式,無需資料庫變更
- 易於維護 - 程式碼邏輯更清晰
- 擴展性 - 未來可以添加更多子陣列
- 資料安全 - 確保各欄位操作互不影響
- 程式碼統一 - 所有頁面使用相同的工具函數
- 功能完整 - 提供豐富的工具函數支援各種操作需求