chore: 首次簽入 Thinkyu ASP.NET 專案
- 加入 Visual Studio / ASP.NET .gitignore - 排除建置輸出、IDE 設定、NuGet packages、大型 MSI 安裝檔
This commit is contained in:
@@ -0,0 +1,269 @@
|
||||
# DAC_領據.SelectSummary 彙整邏輯 - 完成報告
|
||||
|
||||
## 概述
|
||||
|
||||
已成功完成 `DAC_領據.SelectSummary` 方法中的**彙整邏輯**。該方法負責將領據、勞務費、差旅費和付款設定資料進行分組彙總,生成個人費用彙整表。
|
||||
|
||||
## 完成的工作
|
||||
|
||||
### 1. 資料模型定義 ✅
|
||||
|
||||
在 `DAC\領據系統\DAC_領據2.cs` 中定義了完整的資料模型:
|
||||
|
||||
**`個人費用彙整表List` 類別**
|
||||
- 繼承自 `List<個人費用彙整表Item>`
|
||||
- 實現 `IDataList` 介面
|
||||
- 支援 ORM 資料填充
|
||||
|
||||
**`個人費用彙整表Item` 類別**
|
||||
```csharp
|
||||
public partial class 個人費用彙整表Item
|
||||
{
|
||||
// 內部欄位 (查詢用)
|
||||
public string 講師_非講師編號 { get; set; }
|
||||
public DateTime? 活動日期 { get; set; }
|
||||
|
||||
// 顯示欄位
|
||||
public string 領款人姓名 { get; set; }
|
||||
public string 身分證字號 { get; set; }
|
||||
public decimal 堂數 { get; set; } // 已彙總
|
||||
public decimal 付款金額 { get; set; } // 已彙總
|
||||
public string 扣繳類別 { get; set; }
|
||||
public string 扣繳類別名稱 { get; set; }
|
||||
public string 帳戶名 { get; set; }
|
||||
public string 匯款帳號 { get; set; }
|
||||
public string 銀行分行代碼 { get; set; }
|
||||
public string 銀行分行 { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
### 2. SelectSummary 方法完成 ✅
|
||||
|
||||
**方法簽名**
|
||||
```csharp
|
||||
public 個人費用彙整表List SelectSummary(
|
||||
bool noInputReturnAll,
|
||||
int startRowIndex,
|
||||
int maximumRows,
|
||||
DateTime? 起日,
|
||||
DateTime? 迄日,
|
||||
string 身分別,
|
||||
string 付款方式)
|
||||
```
|
||||
|
||||
**實現流程**
|
||||
|
||||
#### 步驟 1: 基本資料查詢
|
||||
- 從 `領據` 表查詢基本資訊
|
||||
- 左 JOIN `勞務費` 表(取得堂數和金額)
|
||||
- 左 JOIN `差旅費` 表(取得差旅費用)
|
||||
- 支援日期和身分別、付款方式篩選
|
||||
|
||||
#### 步驟 2: 加入付款設定資料
|
||||
```csharp
|
||||
var dao付款設定 = new DAC_付款設定(conn);
|
||||
foreach (var r in tempData)
|
||||
{
|
||||
var paymentSetting = dao付款設定.SelectRecentlyActivated(r.講師_非講師編號, r.活動日期);
|
||||
if (paymentSetting != null)
|
||||
{
|
||||
r.扣繳類別 = 扣繳類別.GetActuralValue(paymentSetting.扣繳類別);
|
||||
r.扣繳類別名稱 = 扣繳類別.GetName(paymentSetting.扣繳類別);
|
||||
r.帳戶名 = paymentSetting.匯款戶名;
|
||||
r.匯款帳號 = paymentSetting.匯款帳號;
|
||||
r.銀行分行代碼 = paymentSetting.銀行分行代碼;
|
||||
r.銀行分行 = paymentSetting.銀行分行;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 步驟 3: 彙整聚合 ✨
|
||||
```csharp
|
||||
// 按照 (領款人姓名、身分證字號、扣繳類別、帳戶名、匯款帳號、銀行分行代碼) 分組
|
||||
var groupedData = tempData.GroupBy(x => new
|
||||
{
|
||||
x.領款人姓名,
|
||||
x.身分證字號,
|
||||
x.扣繳類別,
|
||||
x.帳戶名,
|
||||
x.匯款帳號,
|
||||
x.銀行分行代碼,
|
||||
x.銀行分行
|
||||
});
|
||||
|
||||
// 彙總堂數和付款金額
|
||||
foreach (var group in groupedData)
|
||||
{
|
||||
var summaryItem = new 個人費用彙整表Item
|
||||
{
|
||||
領款人姓名 = group.Key.領款人姓名,
|
||||
身分證字號 = group.Key.身分證字號,
|
||||
扣繳類別 = group.Key.扣繳類別,
|
||||
帳戶名 = group.Key.帳戶名,
|
||||
匯款帳號 = group.Key.匯款帳號,
|
||||
銀行分行代碼 = group.Key.銀行分行代碼,
|
||||
銀行分行 = group.Key.銀行分行,
|
||||
// 核心彙總邏輯
|
||||
堂數 = group.Sum(x => x.堂數),
|
||||
付款金額 = group.Sum(x => x.付款金額)
|
||||
};
|
||||
result.Add(summaryItem);
|
||||
}
|
||||
```
|
||||
|
||||
### 3. WebService 整合 ✅
|
||||
|
||||
在 `Services\領據處理.asmx.cs` 的 `SearchSummaryTable` 方法中呼叫 DAC 層:
|
||||
|
||||
```csharp
|
||||
using (var conn = DAC.NewConnection())
|
||||
{
|
||||
var dao領據 = new DAC_領據(conn);
|
||||
var summaryData = dao領據.SelectSummary(
|
||||
true, // noInputReturnAll
|
||||
0, // startRowIndex
|
||||
int.MaxValue, // maximumRows
|
||||
startDate, // 起日
|
||||
endDate, // 迄日
|
||||
身分別,
|
||||
付款方式
|
||||
);
|
||||
|
||||
if (輸出方式 == "DATA")
|
||||
{
|
||||
if (summaryData.Count > 0)
|
||||
return ServiceResponse.CreateSuccess("查詢成功", summaryData);
|
||||
else
|
||||
return ServiceResponse.CreateError("查不到相關資料");
|
||||
}
|
||||
else // EXPORT
|
||||
{
|
||||
// TODO: Excel 匯出邏輯
|
||||
var excelResult = new
|
||||
{
|
||||
excelData = "",
|
||||
fileName = $"講師個人費用彙整表_{DateTime.Now:yyyyMMdd_HHmmss}.xlsx"
|
||||
};
|
||||
return ServiceResponse.CreateSuccess("匯出成功", excelResult);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 資料流程圖
|
||||
|
||||
```
|
||||
領據表
|
||||
↓ (LEFT JOIN 勞務費)
|
||||
↓ (LEFT JOIN 差旅費)
|
||||
↓ 過濾條件 (日期、身分別、付款方式)
|
||||
↓
|
||||
臨時資料集合 tempData
|
||||
↓ 迴圈逐筆加入付款設定資料
|
||||
↓
|
||||
加入扣繳類別、帳戶名、匯款帳號、銀行資訊
|
||||
↓
|
||||
按照彙整鍵值分組
|
||||
↓
|
||||
彙總:
|
||||
- 堂數加總 (SUM)
|
||||
- 付款金額加總 (SUM)
|
||||
↓
|
||||
個人費用彙整表 (彙整後結果)
|
||||
```
|
||||
|
||||
## 🔑 彙整鍵值
|
||||
|
||||
以下欄位組合作為彙整的唯一鍵值:
|
||||
1. `領款人姓名`
|
||||
2. `身分證字號`
|
||||
3. `扣繳類別`
|
||||
4. `帳戶名`
|
||||
5. `匯款帳號`
|
||||
6. `銀行分行代碼`
|
||||
7. `銀行分行`
|
||||
|
||||
**邏輯說明**:同一個講師或非講師,如果有多筆領據且:
|
||||
- 相同的身分證字號
|
||||
- 相同的扣繳類別
|
||||
- 相同的付款帳戶資訊
|
||||
|
||||
則會被合併為一筆記錄,堂數和付款金額會累加。
|
||||
|
||||
## 💾 程式碼統計
|
||||
|
||||
| 項目 | 數量 |
|
||||
|------|------|
|
||||
| 新增類別 | 2 個 (List + Item) |
|
||||
| 實現方法 | 1 個 (SelectSummary) |
|
||||
| 程式碼行數 | ~60 行 |
|
||||
| 編譯狀態 | ✅ 成功 |
|
||||
|
||||
## 🧪 測試檢查清單
|
||||
|
||||
### 單元測試
|
||||
- [ ] 無條件查詢 (返回所有資料)
|
||||
- [ ] 日期範圍查詢 (起日、迄日)
|
||||
- [ ] 身分別篩選 (講師/非講師)
|
||||
- [ ] 付款方式篩選
|
||||
- [ ] 多條件組合查詢
|
||||
- [ ] 無符合資料情況
|
||||
|
||||
### 功能測試
|
||||
- [ ] 驗證彙整結果正確性
|
||||
- [ ] 檢查堂數加總是否正確
|
||||
- [ ] 檢查付款金額加總是否正確
|
||||
- [ ] 驗證付款設定資料正確加入
|
||||
- [ ] 確認無重複資料
|
||||
|
||||
### 效能測試
|
||||
- [ ] 大量資料查詢性能
|
||||
- [ ] 分組彙整效率
|
||||
- [ ] 記憶體使用情況
|
||||
|
||||
## 🚀 後續步驟
|
||||
|
||||
### 1. Excel 匯出實現 ⏳
|
||||
在 `SearchSummaryTable` 方法的 EXPORT 部分實現:
|
||||
- 生成 Excel 檔案
|
||||
- 設置欄位格式和寬度
|
||||
- Base64 編碼
|
||||
- 返回可下載的檔案
|
||||
|
||||
### 2. 前端整合驗證 ⏳
|
||||
- 測試查詢功能
|
||||
- 驗證表格顯示
|
||||
- 測試匯出功能
|
||||
- 檢查效能
|
||||
|
||||
### 3. 資料庫優化 (可選)
|
||||
- 為常查詢欄位添加索引
|
||||
- 考慮物化視圖加速查詢
|
||||
- 分析查詢執行計劃
|
||||
|
||||
## 📝 注意事項
|
||||
|
||||
1. **付款設定查詢**
|
||||
- 使用 `SelectRecentlyActivated` 方法
|
||||
- 根據活動日期選取生效的設定
|
||||
|
||||
2. **分組邏輯**
|
||||
- 使用 LINQ GroupBy 進行彙整
|
||||
- 堂數和付款金額使用 SUM 聚合
|
||||
|
||||
3. **空值處理**
|
||||
- 左 JOIN 可能導致 NULL 值
|
||||
- 已在 SQL 中使用 ISNULL 處理
|
||||
|
||||
4. **效能考量**
|
||||
- 當前採用記憶體彙整(GroupBy)
|
||||
- 大量資料時可考慮移到 SQL 實現
|
||||
|
||||
## ✅ 建置狀態
|
||||
|
||||
✅ **項目成功構建,無編譯錯誤**
|
||||
|
||||
---
|
||||
|
||||
**完成日期:** 2024年
|
||||
**實施狀態:** 彙整邏輯完成,待 Excel 匯出實現
|
||||
**下一里程碑:** Excel 匯出功能
|
||||
Reference in New Issue
Block a user