Files
17168ERP/data/memo/DRAFT_FIELD_IMPROVEMENT.md
2025-08-29 01:27:25 +08:00

5.8 KiB
Raw Blame History

Draft 欄位改進方案

問題描述

原本的 draft 欄位被用於兩種不同目的,導致資料結構混亂:

  1. 暫存沖帳分配 - 在個人沖帳流程中暫存使用者的沖帳金額分配
  2. 歷史沖帳記錄 - 記錄已完成的沖帳明細

這導致兩種不同用途的資料互相覆蓋,造成資料不一致的問題。

改進方案

將原本的純陣列格式改為物件格式,包含兩個子陣列:

新的 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_draftpro_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 為可讀字串

優點

  1. 職責分離 - 每個子陣列有明確的用途
  2. 資料一致性 - 避免不同用途的資料互相覆蓋
  3. 向後相容 - 支援舊格式,無需資料庫變更
  4. 易於維護 - 程式碼邏輯更清晰
  5. 擴展性 - 未來可以添加更多子陣列
  6. 資料安全 - 確保各欄位操作互不影響
  7. 程式碼統一 - 所有頁面使用相同的工具函數
  8. 功能完整 - 提供豐富的工具函數支援各種操作需求