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 匯出功能
|
||||
@@ -0,0 +1,123 @@
|
||||
# NPOI 2.1 (.NET 3.5) 跨版本 Excel 列印跑版終極解決方案文件
|
||||
|
||||
## 1. 問題背景與根本原因
|
||||
在使用 **NPOI 2.1** 配合 **.NET Framework 3.5** 的舊系統環境下,產出的 Excel 報表在不同版本(例如 Excel 2010/2016 與 Excel 2021/2024)直接列印時,會出現「**橫向切到下一頁**」或「**右側多出一欄空白**」的排版不一致問題。
|
||||
|
||||
### 核心原因分析:
|
||||
1. **字型渲染引擎演進(標楷體效應)**:新舊版 Excel 對「標楷體」的字元寬度計算像素不同(GDI vs DirectWrite)。相同的標楷體文字在新版中渲染出來的總寬度通常會多出幾個像素。如果文字因為多出的像素而折行,雖然目前系統列高預留得夠高、高度沒差,但依然會觸發 Excel 盲測邊界失準,導致橫向被切頁或多印空白欄。
|
||||
2. **NPOI 2.1 底層 Bug**:原生的 `workbook.SetPrintArea` 存在著名的 XML 節點建構 Bug,在新版 Excel 中會直接導致導出檔案被判定為「檔案已損毀,需要修復」,因此無法使用設定列印區域的方式來限制範圍。
|
||||
3. **多人連線檔案鎖定**:如果直接操作、修改並儲存伺服器上的實體模板,在 Web 多人同時連線產出報表時,會引發「檔案被另一個程序佔用」的嚴重衝突。
|
||||
|
||||
---
|
||||
|
||||
## 2. 終極解決方案架構:記憶體隔離克隆法 (Thread-Safe)
|
||||
不要建立全新的 Workbook 並逐一複製樣式,也絕不污染實體模板。改用**以唯讀模式將模板讀入記憶體 ➔ 在記憶體中進行 Sheet 克隆與字串替換 ➔ 清理邊界 ➔ 存檔前刪除樣板** 的閉環流程。
|
||||
|
||||
### 核心開發流程與程式碼實作 (C#)
|
||||
|
||||
```csharp
|
||||
using System;
|
||||
using System.IO;
|
||||
using NPOI.SS.UserModel;
|
||||
|
||||
public class ExcelReportGenerator
|
||||
{
|
||||
public void GenerateReport()
|
||||
{
|
||||
string templatePath = @"C:\Templates\ReportTemplate.xlsx";
|
||||
string outputPath = @"C:\Outputs\FinalReport.xlsx";
|
||||
|
||||
// 預期報表的最大總欄數(假設固定為 8 欄,索引 0 ~ 7)
|
||||
int maxValidColumnIndex = 7;
|
||||
|
||||
// 1. 使用 FileShare.Read 唯讀模式開啟實體檔案,保證多人同時連線不鎖檔
|
||||
using (FileStream fs = new FileStream(templatePath, FileMode.Open, FileAccess.Read, FileShare.Read))
|
||||
{
|
||||
// 2. 將模板內容完整載入記憶體
|
||||
byte[] templateBytes;
|
||||
using (MemoryStream ms = new MemoryStream())
|
||||
{
|
||||
byte[] buffer = new byte[1024 * 4];
|
||||
int read;
|
||||
while ((read = fs.Read(buffer, 0, buffer.Length)) > 0)
|
||||
{
|
||||
ms.Write(buffer, 0, read);
|
||||
}
|
||||
templateBytes = ms.ToArray();
|
||||
}
|
||||
|
||||
// 3. 在完全隔離的記憶體中建立獨立的 Workbook 物件
|
||||
using (MemoryStream workbookMs = new MemoryStream(templateBytes))
|
||||
{
|
||||
IWorkbook workbook = WorkbookFactory.Create(workbookMs);
|
||||
|
||||
// 4. 利用 CloneSheet 完美克隆樣板,完整帶走字型、預設邊界與頁面配置
|
||||
int templateIndex = 0; // 假設原始樣板在第一個 Sheet
|
||||
ISheet newSheet = workbook.CloneSheet(templateIndex);
|
||||
workbook.SetSheetName(workbook.GetSheetIndex(newSheet), "正式報表");
|
||||
|
||||
// 5. 執行您原有的 Find and Replace 邏輯
|
||||
// 註:標楷體即使因為版本差而折行,因高度安全故不會影響縱向分頁
|
||||
PerformFindAndReplace(newSheet);
|
||||
|
||||
// ============================================================
|
||||
// 防線一:補上底層 PageSetup 縮放,強制鎖定橫向寬度(根治「切到下一頁」)
|
||||
// ============================================================
|
||||
newSheet.FitToPage = true;
|
||||
newSheet.PrintSetup.Scale = 0; // 關鍵:在 NPOI 2.1 中,必須將 Scale 歸零,FitWidth 才會在所有 Excel 版本中生效
|
||||
newSheet.PrintSetup.FitWidth = 1; // 強制所有欄位橫向壓縮在一頁內
|
||||
newSheet.PrintSetup.FitHeight = 0; // 高度設為 0,代表縱向不限制,隨資料自然往下延伸
|
||||
|
||||
// ============================================================
|
||||
// 防線二:徹底拔除右側隱形/殘留儲存格(替代 SetPrintArea,根治「多一欄」)
|
||||
// ============================================================
|
||||
for (int rowNum = 0; rowNum <= newSheet.LastRowNum; rowNum++)
|
||||
{
|
||||
IRow row = newSheet.GetRow(rowNum);
|
||||
if (row == null) continue;
|
||||
|
||||
// 如果 NPOI 判定此行在 XML 中的最後一欄超過了實質資料的上限
|
||||
if (row.LastCellNum > (maxValidColumnIndex + 1))
|
||||
{
|
||||
// 倒序迴圈,將指定欄位之後的所有隱形/空儲存格物件物理性地徹底拔除
|
||||
for (int c = row.LastCellNum - 1; c > maxValidColumnIndex; c--)
|
||||
{
|
||||
ICell cell = row.GetCell(c);
|
||||
if (cell != null)
|
||||
{
|
||||
row.RemoveCell(cell);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// 防線三:安全刪除原始樣板工作表,避開打開空白與重複列印
|
||||
// ============================================================
|
||||
// 技巧:先將活動焦點(ActiveSheet)移至新報表,再進行刪除
|
||||
workbook.SetActiveSheet(workbook.GetSheetIndex(newSheet));
|
||||
workbook.RemoveSheetAt(templateIndex);
|
||||
|
||||
// 6. 將專屬的報表匯出成獨立新檔(或直接 Response 給瀏覽器下載)
|
||||
using (FileStream outFs = new FileStream(outputPath, FileMode.Create, FileAccess.Write))
|
||||
{
|
||||
workbook.Write(outFs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void PerformFindAndReplace(ISheet sheet)
|
||||
{
|
||||
// 您的 Find and Replace 實作代碼
|
||||
// 提示:只更新 cell.SetCellValue(),絕對不要重新 CreateCell(),以完整保留標楷體格式與邊框
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. 關鍵執行與相容性檢查清單
|
||||
1. **只換值、不重造**:在 `Find and Replace` 時,請直接使用 `cell.SetCellValue(newValue)`,不要重新 `CreateCell`,否則會把原模板上精心設計的標楷體字型、置中、邊框等 CellStyle 屬性完全洗掉。
|
||||
2. **`Scale = 0` 是必備開關**:在 NPOI 2.1 底層 XML 結構中,如果沒有明確指定 `PrintSetup.Scale = 0`,部分 Office 版本在讀取 `FitWidth = 1` 時會發生衝突進而失效。
|
||||
3. **活動焦點移轉**:在呼叫 `workbook.RemoveSheetAt(0)` 刪除空白樣板前,必須先呼叫 `workbook.SetActiveSheet()` 鎖定新工作表,否則使用者開啟 Excel 時畫面可能因焦點遺失而顯示全白(需手動點選下方分頁才看得到內容)。
|
||||
@@ -0,0 +1,241 @@
|
||||
|
||||
-- FN取得選定講師編號
|
||||
CREATE FUNCTION FN取得選定講師編號
|
||||
(
|
||||
@課程企劃編號 AS INT,
|
||||
@課程序號 AS INT
|
||||
)
|
||||
RETURNS INT
|
||||
AS
|
||||
BEGIN
|
||||
DECLARE @RESULT INT
|
||||
DECLARE @COUNT INT
|
||||
DECLARE @講師編號 INT
|
||||
|
||||
SELECT @COUNT=COUNT(1) FROM 訓練課程內容 WHERE 訓練課程企劃編號=@課程企劃編號 AND 課程序號=@課程序號
|
||||
IF @COUNT = 0
|
||||
BEGIN
|
||||
RETURN 0
|
||||
END
|
||||
ELSE
|
||||
BEGIN
|
||||
SELECT TOP 1 @講師編號 = 講師編號 FROM 講師異動
|
||||
WHERE 課程企劃編號 = @課程企劃編號 AND 課程序號 = @課程序號
|
||||
ORDER BY 異動次數 DESC
|
||||
|
||||
IF @講師編號 IS NOT NULL
|
||||
BEGIN
|
||||
RETURN @講師編號
|
||||
END
|
||||
ELSE
|
||||
BEGIN
|
||||
DECLARE @講師A INT
|
||||
DECLARE @講師B INT
|
||||
DECLARE @講師C INT
|
||||
DECLARE @分數A INT
|
||||
DECLARE @分數B INT
|
||||
DECLARE @分數C INT
|
||||
|
||||
SELECT @講師A = ISNULL(講師編號_A, 0), @講師B = ISNULL(講師編號_B, 0), @講師C = ISNULL(講師編號_C, 0),
|
||||
@分數A = ISNULL(合計_A, 0), @分數B = ISNULL(合計_B, 0), @分數C = ISNULL(合計_C, 0)
|
||||
FROM 講師遴選
|
||||
WHERE 課程企劃編號 = @課程企劃編號 AND 課程序號 = @課程序號
|
||||
|
||||
IF (@分數A > @分數B AND @分數A > @分數C)
|
||||
SET @講師編號 = @講師A
|
||||
ELSE IF (@分數B > @分數A AND @分數B > @分數C)
|
||||
SET @講師編號 = @講師B
|
||||
ELSE
|
||||
SET @講師編號 = @講師C
|
||||
END
|
||||
END
|
||||
RETURN @講師編號
|
||||
END
|
||||
|
||||
|
||||
-- FN取得選定場地編號
|
||||
CREATE FUNCTION FN取得選定場地編號
|
||||
(
|
||||
@課程企劃編號 AS INT
|
||||
)
|
||||
RETURNS INT
|
||||
AS
|
||||
BEGIN
|
||||
DECLARE @RESULT INT
|
||||
DECLARE @COUNT INT
|
||||
DECLARE @場地編號 INT
|
||||
|
||||
SELECT @COUNT=COUNT(1) FROM 訓練課程企劃 WHERE 編號=@課程企劃編號
|
||||
IF @COUNT = 0
|
||||
BEGIN
|
||||
RETURN 0
|
||||
END
|
||||
ELSE
|
||||
BEGIN
|
||||
SELECT TOP 1 @場地編號 = 場地編號 FROM 場地異動
|
||||
WHERE 課程企劃編號 = @課程企劃編號
|
||||
ORDER BY 異動次數 DESC
|
||||
|
||||
IF @場地編號 IS NOT NULL
|
||||
BEGIN
|
||||
RETURN @場地編號
|
||||
END
|
||||
ELSE
|
||||
BEGIN
|
||||
DECLARE @場地A INT
|
||||
DECLARE @場地B INT
|
||||
DECLARE @場地C INT
|
||||
DECLARE @分數A INT
|
||||
DECLARE @分數B INT
|
||||
DECLARE @分數C INT
|
||||
|
||||
SELECT @場地A = ISNULL(場地編號_A, 0), @場地B = ISNULL(場地編號_B, 0), @場地C = ISNULL(場地編號_C, 0),
|
||||
@分數A = ISNULL(合計_A, 0), @分數B = ISNULL(合計_B, 0), @分數C = ISNULL(合計_C, 0)
|
||||
FROM 場地遴選
|
||||
WHERE 課程企劃編號 = @課程企劃編號
|
||||
|
||||
IF (@分數A > @分數B AND @分數A > @分數C)
|
||||
SET @場地編號 = @場地A
|
||||
ELSE IF (@分數B > @分數A AND @分數B > @分數C)
|
||||
SET @場地編號 = @場地B
|
||||
ELSE
|
||||
SET @場地編號 = @場地C
|
||||
END
|
||||
END
|
||||
RETURN @場地編號
|
||||
END
|
||||
|
||||
|
||||
-- FN取得選定講師名稱
|
||||
CREATE FUNCTION FN取得選定講師名稱
|
||||
(
|
||||
@課程企劃編號 AS INT,
|
||||
@課程序號 AS INT
|
||||
)
|
||||
RETURNS NVARCHAR(200)
|
||||
AS
|
||||
BEGIN
|
||||
DECLARE @講師編號 INT
|
||||
DECLARE @講師名稱 NVARCHAR(200)
|
||||
|
||||
-- 先檢查 訓練課程內容 是否存在
|
||||
IF NOT EXISTS (SELECT 1 FROM 訓練課程內容 WHERE 訓練課程企劃編號=@課程企劃編號 AND 課程序號=@課程序號)
|
||||
RETURN NULL
|
||||
|
||||
-- Step 1: 先查 講師異動 (最後異動)
|
||||
SELECT TOP 1 @講師編號 = ISNULL(講師編號, 0), @講師名稱 = 講師姓名
|
||||
FROM 講師異動
|
||||
WHERE 課程企劃編號 = @課程企劃編號 AND 課程序號 = @課程序號
|
||||
ORDER BY 異動次數 DESC
|
||||
|
||||
IF @講師編號 > 0
|
||||
BEGIN
|
||||
SELECT @講師名稱 = 姓名 FROM 講師 WHERE 編號 = @講師編號
|
||||
RETURN @講師名稱
|
||||
END
|
||||
ELSE IF @講師名稱 IS NOT NULL AND @講師名稱 <> ''
|
||||
BEGIN
|
||||
RETURN @講師名稱
|
||||
END
|
||||
|
||||
-- Step 2: 查 講師遴選
|
||||
DECLARE @講師A INT, @講師B INT, @講師C INT
|
||||
DECLARE @姓名A NVARCHAR(200), @姓名B NVARCHAR(200), @姓名C NVARCHAR(200)
|
||||
DECLARE @分數A INT, @分數B INT, @分數C INT
|
||||
DECLARE @選定 INT
|
||||
|
||||
SELECT @講師A = ISNULL(講師編號_A, 0), @講師B = ISNULL(講師編號_B, 0), @講師C = ISNULL(講師編號_C, 0),
|
||||
@姓名A = 講師姓名_A, @姓名B = 講師姓名_B, @姓名C = 講師姓名_C,
|
||||
@分數A = ISNULL(合計_A, 0), @分數B = ISNULL(合計_B, 0), @分數C = ISNULL(合計_C, 0),
|
||||
@選定 = ISNULL(選定講師, 0)
|
||||
FROM 講師遴選
|
||||
WHERE 課程企劃編號 = @課程企劃編號 AND 課程序號 = @課程序號
|
||||
|
||||
IF @@ROWCOUNT = 0
|
||||
RETURN NULL
|
||||
|
||||
IF @選定 = 1
|
||||
SELECT @講師編號 = @講師A, @講師名稱 = @姓名A
|
||||
ELSE IF @選定 = 2
|
||||
SELECT @講師編號 = @講師B, @講師名稱 = @姓名B
|
||||
ELSE IF @選定 = 3
|
||||
SELECT @講師編號 = @講師C, @講師名稱 = @姓名C
|
||||
ELSE IF (@分數A >= @分數B AND @分數A >= @分數C)
|
||||
SELECT @講師編號 = @講師A, @講師名稱 = @姓名A
|
||||
ELSE IF (@分數B >= @分數A AND @分數B >= @分數C)
|
||||
SELECT @講師編號 = @講師B, @講師名稱 = @姓名B
|
||||
ELSE
|
||||
SELECT @講師編號 = @講師C, @講師名稱 = @姓名C
|
||||
|
||||
IF @講師編號 > 0
|
||||
SELECT @講師名稱 = 姓名 FROM 講師 WHERE 編號 = @講師編號
|
||||
|
||||
RETURN @講師名稱
|
||||
END
|
||||
|
||||
|
||||
-- FN取得選定場地名稱
|
||||
CREATE FUNCTION FN取得選定場地名稱
|
||||
(
|
||||
@課程企劃編號 AS INT
|
||||
)
|
||||
RETURNS NVARCHAR(200)
|
||||
AS
|
||||
BEGIN
|
||||
DECLARE @場地編號 INT
|
||||
DECLARE @場地名稱 NVARCHAR(200)
|
||||
|
||||
-- 先檢查 訓練課程企劃 是否存在
|
||||
IF NOT EXISTS (SELECT 1 FROM 訓練課程企劃 WHERE 編號=@課程企劃編號)
|
||||
RETURN NULL
|
||||
|
||||
-- Step 1: 先查 場地異動 (最後異動)
|
||||
SELECT TOP 1 @場地編號 = ISNULL(場地編號, 0), @場地名稱 = 場地名稱
|
||||
FROM 場地異動
|
||||
WHERE 課程企劃編號 = @課程企劃編號
|
||||
ORDER BY 異動次數 DESC
|
||||
|
||||
IF @場地編號 > 0
|
||||
BEGIN
|
||||
SELECT @場地名稱 = 場地名稱 FROM 場地 WHERE 編號 = @場地編號
|
||||
RETURN @場地名稱
|
||||
END
|
||||
ELSE IF @場地名稱 IS NOT NULL AND @場地名稱 <> ''
|
||||
BEGIN
|
||||
RETURN @場地名稱
|
||||
END
|
||||
|
||||
-- Step 2: 查 場地遴選
|
||||
DECLARE @場地A INT, @場地B INT, @場地C INT
|
||||
DECLARE @名稱A NVARCHAR(200), @名稱B NVARCHAR(200), @名稱C NVARCHAR(200)
|
||||
DECLARE @分數A INT, @分數B INT, @分數C INT
|
||||
DECLARE @選定 INT
|
||||
|
||||
SELECT @場地A = ISNULL(場地編號_A, 0), @場地B = ISNULL(場地編號_B, 0), @場地C = ISNULL(場地編號_C, 0),
|
||||
@名稱A = 場地名稱_A, @名稱B = 場地名稱_B, @名稱C = 場地名稱_C,
|
||||
@分數A = ISNULL(合計_A, 0), @分數B = ISNULL(合計_B, 0), @分數C = ISNULL(合計_C, 0),
|
||||
@選定 = ISNULL(選定場地, 0)
|
||||
FROM 場地遴選
|
||||
WHERE 課程企劃編號 = @課程企劃編號
|
||||
|
||||
IF @@ROWCOUNT = 0
|
||||
RETURN NULL
|
||||
|
||||
IF @選定 = 1
|
||||
SELECT @場地編號 = @場地A, @場地名稱 = @名稱A
|
||||
ELSE IF @選定 = 2
|
||||
SELECT @場地編號 = @場地B, @場地名稱 = @名稱B
|
||||
ELSE IF @選定 = 3
|
||||
SELECT @場地編號 = @場地C, @場地名稱 = @名稱C
|
||||
ELSE IF (@分數A >= @分數B AND @分數A >= @分數C)
|
||||
SELECT @場地編號 = @場地A, @場地名稱 = @名稱A
|
||||
ELSE IF (@分數B >= @分數A AND @分數B >= @分數C)
|
||||
SELECT @場地編號 = @場地B, @場地名稱 = @名稱B
|
||||
ELSE
|
||||
SELECT @場地編號 = @場地C, @場地名稱 = @名稱C
|
||||
|
||||
IF @場地編號 > 0
|
||||
SELECT @場地名稱 = 場地名稱 FROM 場地 WHERE 編號 = @場地編號
|
||||
|
||||
RETURN @場地名稱
|
||||
END
|
||||
@@ -0,0 +1,310 @@
|
||||
# 講師個人費用彙整表 - 完整實施報告
|
||||
|
||||
## 📋 概述
|
||||
|
||||
本報告總結了「講師個人費用彙整表」功能的完整實施情況。已實施的內容包括前端 UI、Vue.js 邏輯框架和 WebService 方法簽名。待實施的內容主要為後端查詢邏輯和 Excel 匯出邏輯。
|
||||
|
||||
## 🎯 項目目標
|
||||
|
||||
實施一個完整的講師個人費用彙整表查詢和匯出系統,允許用戶:
|
||||
1. 按日期、身分別、付款方式查詢講師費用資訊
|
||||
2. 查看結果並在表格中展示 9 個關鍵欄位
|
||||
3. 將查詢結果匯出為 Excel 檔案
|
||||
|
||||
## ✅ 完成情況
|
||||
|
||||
### 1. 前端 UI (100% 完成)
|
||||
|
||||
**檔案:** `Forms\領據系統\財稅作業與領據關帳.aspx`
|
||||
|
||||
**實施內容:**
|
||||
- Tab 0 個人費用彙整表頁面結構
|
||||
- 查詢表單(4 個欄位)
|
||||
- 起日:日期選擇控制項
|
||||
- 迄日:日期選擇控制項
|
||||
- 身分別:下拉清單(動態加載)
|
||||
- 付款方式:下拉清單(動態加載)
|
||||
- 操作按鈕
|
||||
- 查詢按鈕(綠色 green80)
|
||||
- 匯出按鈕(藍色 blue80)
|
||||
- 查詢結果表格
|
||||
- 9 個欄位列標題
|
||||
- 動態綁定資料列
|
||||
- 貨幣格式化顯示
|
||||
- 訊息提示區域
|
||||
- 支援 4 種訊息類型(success, danger, warning, info)
|
||||
- 完整 CSS 樣式
|
||||
- 響應式布局
|
||||
- 現代化設計
|
||||
|
||||
**代碼行數:** ~150 行 HTML/CSS
|
||||
|
||||
### 2. Vue.js 邏輯 (100% 完成)
|
||||
|
||||
**檔案:** `Scripts\財稅作業與領據關帳.js`
|
||||
|
||||
**實施內容:**
|
||||
|
||||
**資料結構:**
|
||||
```javascript
|
||||
summaryTable: {
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
identity: '',
|
||||
paymentMethod: '',
|
||||
identityOptions: [],
|
||||
paymentMethodOptions: [],
|
||||
dataList: [],
|
||||
loading: false,
|
||||
message: '',
|
||||
messageType: 'info'
|
||||
}
|
||||
```
|
||||
|
||||
**方法(共 6 個):**
|
||||
1. `loadSummaryTableDropdowns()` - 非同步加載下拉清單選項
|
||||
2. `searchSummaryTable()` - 非同步執行查詢
|
||||
3. `exportSummaryTable()` - 非同步執行匯出
|
||||
4. `parseDate()` - 日期字符串解析(ISO 8601 格式)
|
||||
5. `formatCurrency()` - 貨幣格式化(NTD)
|
||||
6. `downloadExcel()` - Base64 Excel 檔案下載
|
||||
|
||||
**特色:**
|
||||
- 完整的異常處理
|
||||
- 加載狀態管理
|
||||
- 用戶友好的錯誤訊息
|
||||
- 自動訊息隱藏
|
||||
- 按鈕禁用狀態管理
|
||||
|
||||
**代碼行數:** ~200 行 JavaScript
|
||||
|
||||
### 3. WebService 方法 (100% 完成框架)
|
||||
|
||||
**檔案:** `Services\領據處理.asmx.cs`
|
||||
|
||||
**實施內容:**
|
||||
|
||||
**方法簽名:**
|
||||
```csharp
|
||||
[WebMethod(EnableSession = true)]
|
||||
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
|
||||
public ServiceResponse SearchSummaryTable(
|
||||
string 起日,
|
||||
string 迄日,
|
||||
string 身分別,
|
||||
string 付款方式,
|
||||
string 輸出方式)
|
||||
```
|
||||
|
||||
**功能:**
|
||||
- 日期參數解析(支援多種格式)
|
||||
- 輸出方式驗證(DATA 或 EXPORT)
|
||||
- 異常捕捉和錯誤回應
|
||||
- 參數驗證
|
||||
|
||||
**資料模型:**
|
||||
```csharp
|
||||
public class 個人費用彙整表Item
|
||||
{
|
||||
public string 領款人姓名 { get; set; }
|
||||
public string 身分證字號 { get; set; }
|
||||
public string 堂數 { get; set; }
|
||||
public string 扣繳類別 { get; set; }
|
||||
public string 帳戶名 { get; set; }
|
||||
public decimal 付款金額 { get; set; }
|
||||
public string 匯款帳號 { get; set; }
|
||||
public string 銀行分行代碼 { get; set; }
|
||||
public string 銀行分行 { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
**代碼行數:** ~80 行 C#
|
||||
|
||||
### 4. 樣式優化 (100% 完成)
|
||||
|
||||
**檔案:**
|
||||
- `Styles\領據資料處理.css`
|
||||
- `Forms\領據系統\財稅作業與領據關帳.aspx` (內部 CSS)
|
||||
|
||||
**新增樣式:**
|
||||
- `.ml-2` - 左邊距(0.5rem)
|
||||
- `.mt-3` - 上邊距(1rem)
|
||||
- `.mt-4` - 上邊距(1.5rem)
|
||||
- `.button` 系列 - 按鈕基礎樣式
|
||||
- `.green80` - 綠色按鈕
|
||||
- `.blue80` - 藍色按鈕
|
||||
- `.table` 系列 - 表格樣式
|
||||
- `.alert` 系列 - 警告訊息樣式
|
||||
- `.form-*` - 表單樣式
|
||||
|
||||
**特色:**
|
||||
- 響應式布局
|
||||
- 現代化設計
|
||||
- 易於維護和擴展
|
||||
|
||||
## ⏳ 待實施部分
|
||||
|
||||
### 1. 查詢邏輯 (需要用戶完成)
|
||||
|
||||
**位置:** `Services\領據處理.asmx.cs` 第 688 行
|
||||
|
||||
**實現要點:**
|
||||
```csharp
|
||||
// TODO: 實現查詢邏輯
|
||||
// 根據 startDate, endDate, 身分別, 付款方式 查詢資料
|
||||
// 返回 List<個人費用彙整表Item>
|
||||
|
||||
// 應該呼叫 DAC 層方法
|
||||
var summaryData = dac.SearchSummaryTable(startDate, endDate, 身分別, 付款方式);
|
||||
```
|
||||
|
||||
**建議:**
|
||||
- 創建 `DAC_個人費用彙整` 或在現有 DAC 中添加方法
|
||||
- SQL 查詢應該聯結講師、非講師、勞務費、付款設定等表
|
||||
- 考慮性能優化(分頁、索引等)
|
||||
|
||||
### 2. Excel 匯出邏輯 (需要用戶完成)
|
||||
|
||||
**位置:** `Services\領據處理.asmx.cs` 第 715 行
|
||||
|
||||
**實現要點:**
|
||||
```csharp
|
||||
// TODO: 實現 Excel 匯出邏輯
|
||||
// 1. 使用相同的查詢取得 summaryData
|
||||
// 2. 生成 Excel 檔案
|
||||
// 3. 轉換為 Base64 編碼
|
||||
// 4. 返回 { excelData, fileName }
|
||||
|
||||
var excelBase64 = GenerateExcelBase64(summaryData);
|
||||
var excelResult = new
|
||||
{
|
||||
excelData = excelBase64,
|
||||
fileName = $"講師個人費用彙整表_{DateTime.Now:yyyyMMdd_HHmmss}.xlsx"
|
||||
};
|
||||
```
|
||||
|
||||
**建議:**
|
||||
- 使用 NPOI 或 DocumentFormat.OpenXml 生成 Excel
|
||||
- 参考現有的 `Report.領據列印` 實現方式
|
||||
- 設置適當的欄寬和格式化
|
||||
|
||||
## 📊 開發統計
|
||||
|
||||
| 項目 | 數量 |
|
||||
|------|------|
|
||||
| 修改文件 | 4 個 |
|
||||
| 新增方法 | 7 個 |
|
||||
| 新增類別 | 1 個 |
|
||||
| CSS 樣式 | 100+ 行 |
|
||||
| JavaScript 代碼 | 200+ 行 |
|
||||
| C# 代碼 | 80+ 行 |
|
||||
| 總代碼行數 | 400+ 行 |
|
||||
|
||||
## 🔗 代碼流程
|
||||
|
||||
```
|
||||
用戶查詢流程:
|
||||
1. 用戶輸入查詢條件(起日、迄日、身分別、付款方式)
|
||||
2. 點擊「查詢」按鈕
|
||||
3. Vue: searchSummaryTable()
|
||||
4. Ajax: SearchSummaryTable(方式="DATA")
|
||||
5. C#: 解析參數 → 查詢資料 → 返回 JSON
|
||||
6. Vue: 綁定結果到表格
|
||||
7. 顯示查詢結果和訊息
|
||||
|
||||
用戶匯出流程:
|
||||
1. 點擊「匯出」按鈕
|
||||
2. Vue: exportSummaryTable()
|
||||
3. Ajax: SearchSummaryTable(方式="EXPORT")
|
||||
4. C#: 生成 Excel → Base64 編碼 → 返回
|
||||
5. Vue: downloadExcel()
|
||||
6. 瀏覽器下載 Excel 檔案
|
||||
```
|
||||
|
||||
## 🚀 部署步驟
|
||||
|
||||
1. **準備階段**
|
||||
- 完成查詢邏輯實施
|
||||
- 完成 Excel 匯出邏輯實施
|
||||
- 進行全面測試
|
||||
|
||||
2. **構建階段**
|
||||
- Visual Studio 編譯
|
||||
- 無編譯錯誤(已驗證 ✅)
|
||||
|
||||
3. **測試階段**
|
||||
- 單元測試
|
||||
- 集成測試
|
||||
- 用戶驗收測試
|
||||
|
||||
4. **部署階段**
|
||||
- 部署到開發環境
|
||||
- 部署到測試環境
|
||||
- 部署到生產環境
|
||||
|
||||
## 📚 參考文檔
|
||||
|
||||
1. `DOC\講師個人費用彙整表.md` - 需求文檔
|
||||
2. `DOC\個人費用彙整表_實施指南.md` - 詳細實施指南
|
||||
3. `DOC\個人費用彙整表_實施摘要.md` - 實施摘要
|
||||
4. `DOC\個人費用彙整表_檢查清單.md` - 檢查清單
|
||||
|
||||
## 🎓 技術棧
|
||||
|
||||
- **前端框架:** Vue.js 2.x
|
||||
- **前端 HTTP:** Axios
|
||||
- **後端框架:** ASP.NET WebService
|
||||
- **後端語言:** C#
|
||||
- **.NET 版本:** Framework 3.5
|
||||
- **資料庫:** SQL Server (推測)
|
||||
- **Excel 生成:** NPOI / OpenXml (待選)
|
||||
|
||||
## 💾 版本資訊
|
||||
|
||||
| 組件 | 版本 |
|
||||
|------|------|
|
||||
| Vue.js | 2.x |
|
||||
| Axios | Latest |
|
||||
| .NET Framework | 3.5 |
|
||||
| Project Status | In Development |
|
||||
|
||||
## ✨ 亮點特色
|
||||
|
||||
1. **完整的前後端集成** - 從 UI 到 WebService 的完整實施
|
||||
2. **現代化的用戶界面** - 響應式設計、友好的提示訊息
|
||||
3. **健壯的錯誤處理** - 完善的異常捕捉和錯誤回應
|
||||
4. **易於擴展** - 模塊化設計,便於添加新功能
|
||||
5. **清晰的代碼註釋** - 易於維護和理解
|
||||
|
||||
## 🔧 後續優化建議
|
||||
|
||||
1. **性能優化**
|
||||
- 添加分頁功能(大量資料場景)
|
||||
- 緩存下拉清單選項
|
||||
- 優化 SQL 查詢
|
||||
|
||||
2. **功能增強**
|
||||
- 添加更多過濾條件
|
||||
- 支援自訂欄位選擇
|
||||
- 支援高級查詢
|
||||
|
||||
3. **用戶體驗改進**
|
||||
- 添加查詢歷史
|
||||
- 支援模板保存
|
||||
- 添加快速鍵
|
||||
|
||||
## 📞 支援聯絡
|
||||
|
||||
如有任何問題或需要進一步的協助,請參考:
|
||||
- 實施指南:`DOC\個人費用彙整表_實施指南.md`
|
||||
- 實施摘要:`DOC\個人費用彙整表_實施摘要.md`
|
||||
- 檢查清單:`DOC\個人費用彙整表_檢查清單.md`
|
||||
|
||||
## ✅ 建置狀態
|
||||
|
||||
✅ **項目成功構建,無編譯錯誤**
|
||||
|
||||
---
|
||||
|
||||
**報告生成時間:** 2024年
|
||||
**報告狀態:** 完整實施階段完成,待後端邏輯實施
|
||||
@@ -0,0 +1,154 @@
|
||||
# 個人費用彙整表 - 實施指南
|
||||
|
||||
## 概述
|
||||
已完成「個人費用彙整表」的前端和框架實施。本文檔說明需要用戶完成的後端邏輯部分。
|
||||
|
||||
## 完成的工作
|
||||
|
||||
### 1. 前端 UI (Forms\領據系統\財稅作業與領據關帳.aspx)
|
||||
✅ **完成內容:**
|
||||
- Tab 0 查詢表單 (起日、迄日、身分別、付款方式)
|
||||
- 查詢/匯出按鈕
|
||||
- 查詢結果表格 (9 個欄位)
|
||||
- 完整的 CSS 樣式
|
||||
|
||||
### 2. Vue.js 邏輯 (Scripts\財稅作業與領據關帳.js)
|
||||
✅ **完成內容:**
|
||||
- summaryTable 資料物件初始化
|
||||
- 下拉清單加載邏輯 (`loadSummaryTableDropdowns`)
|
||||
- 查詢方法 (`searchSummaryTable`)
|
||||
- 匯出方法 (`exportSummaryTable`)
|
||||
- 輔助方法 (`parseDate`, `formatCurrency`, `downloadExcel`)
|
||||
|
||||
### 3. WebService 方法簽名 (Services\領據處理.asmx.cs)
|
||||
✅ **完成內容:**
|
||||
- `SearchSummaryTable` 方法框架
|
||||
- `個人費用彙整表Item` 資料模型類
|
||||
|
||||
## 需要用戶完成的工作
|
||||
|
||||
### 1. SearchSummaryTable 後端實現
|
||||
|
||||
**位置:** `Services\領據處理.asmx.cs` - `SearchSummaryTable` 方法
|
||||
|
||||
**需要實現:**
|
||||
```csharp
|
||||
// 在此處替換 TODO 註解的部分
|
||||
|
||||
// 根據查詢參數取得資料:
|
||||
using (var conn = DAC.NewConnection())
|
||||
{
|
||||
// 你的查詢邏輯應該:
|
||||
// 1. 根據 startDate (起日), endDate (迄日) 篩選日期範圍
|
||||
// 2. 如果 身分別 有值,篩選身分別
|
||||
// 3. 如果 付款方式 有值,篩選付款方式
|
||||
// 4. 返回 List<個人費用彙整表Item>
|
||||
|
||||
// 查詢應該返回以下欄位:
|
||||
var summaryData = new List<個人費用彙整表Item>();
|
||||
|
||||
// TODO: 實現查詢邏輯
|
||||
// var result = dac.SearchSummaryTable(startDate, endDate, 身分別, 付款方式);
|
||||
// summaryData = result.ToList();
|
||||
|
||||
return summaryData;
|
||||
}
|
||||
```
|
||||
|
||||
**輸出欄位 (9 個):**
|
||||
1. `領款人姓名` (string) - 講師/非講師姓名
|
||||
2. `身分證字號` (string)
|
||||
3. `堂數` (string) - 格式:「數量 + 單位」,例如「5堂」
|
||||
4. `扣繳類別` (string)
|
||||
5. `帳戶名` (string)
|
||||
6. `付款金額` (decimal)
|
||||
7. `匯款帳號` (string)
|
||||
8. `銀行分行代碼` (string)
|
||||
9. `銀行分行` (string)
|
||||
|
||||
**參數:**
|
||||
- `startDate` (DateTime?) - 起日
|
||||
- `endDate` (DateTime?) - 迄日
|
||||
- `身分別` (string) - 身分別 (可空)
|
||||
- `付款方式` (string) - 付款方式 (可空)
|
||||
|
||||
### 2. Excel 匯出實現
|
||||
|
||||
**位置:** `Services\領據處理.asmx.cs` - `SearchSummaryTable` 方法中的 EXPORT 部分
|
||||
|
||||
**需要實現:**
|
||||
```csharp
|
||||
if (輸出方式 == "EXPORT")
|
||||
{
|
||||
// TODO: 實現 Excel 匯出邏輯
|
||||
// 1. 使用相同的查詢取得 summaryData
|
||||
// 2. 生成 Excel 檔案 (使用 NPOI 或其他庫)
|
||||
// 3. 將 Excel 檔案轉換為 Base64 編碼
|
||||
// 4. 返回 excelData (Base64) 和 fileName
|
||||
|
||||
var excelResult = new
|
||||
{
|
||||
excelData = excelBase64String, // Base64 編碼的 Excel 檔案內容
|
||||
fileName = $"講師個人費用彙整表_{DateTime.Now:yyyyMMdd_HHmmss}.xlsx"
|
||||
};
|
||||
|
||||
return ServiceResponse.CreateSuccess("匯出成功", excelResult);
|
||||
}
|
||||
```
|
||||
|
||||
## 測試檢查清單
|
||||
|
||||
- [ ] 在 Visual Studio 中構建項目 (確無編譯錯誤)
|
||||
- [ ] 在瀏覽器中開啟財稅作業與領據關帳頁面
|
||||
- [ ] 驗證 Tab 0 個人費用彙整表是否顯示正確
|
||||
- [ ] 驗證下拉清單是否正確加載身分別和付款方式
|
||||
- [ ] 點擊查詢按鈕,驗證是否呼叫後端 `SearchSummaryTable` 方法
|
||||
- [ ] 驗證查詢結果表格是否正確顯示 (如有 TODO 實現)
|
||||
- [ ] 點擊匯出按鈕,驗證是否下載 Excel 檔案 (如有 TODO 實現)
|
||||
|
||||
## 後續建議
|
||||
|
||||
1. **數據庫查詢**
|
||||
- 建立 DAC 類別 `DAC_個人費用彙整` 或在現有 DAC 中添加查詢方法
|
||||
- 優化 SQL 查詢效能 (考慮分組、合計等)
|
||||
|
||||
2. **Excel 匯出**
|
||||
- 建議使用 NPOI 庫生成 Excel
|
||||
- 可參考現有的 `Report.領據列印` 實現方式
|
||||
|
||||
3. **數據驗證**
|
||||
- 驗證日期範圍的合理性
|
||||
- 驗證身分別和付款方式的有效值
|
||||
|
||||
4. **錯誤處理**
|
||||
- 新增更詳細的錯誤訊息
|
||||
- 記錄查詢日誌用於除錯
|
||||
|
||||
## 技術棧
|
||||
|
||||
- **前端:** Vue.js 2.x, HTML5, CSS3
|
||||
- **後端:** ASP.NET (C#), WebService
|
||||
- **資料庫:** SQL Server (假設)
|
||||
- **.NET 版本:** Framework 3.5
|
||||
|
||||
## 支援的瀏覽器
|
||||
|
||||
- Chrome (推薦)
|
||||
- Firefox
|
||||
- Edge
|
||||
- Safari
|
||||
|
||||
## 常見問題
|
||||
|
||||
**Q: 如何修改查詢結果欄位?**
|
||||
A: 修改 `個人費用彙整表Item` 類別的屬性,並更新前端表格 HTML。
|
||||
|
||||
**Q: 如何添加更多查詢條件?**
|
||||
A:
|
||||
1. 在 ASPX 中添加新的表單控制項
|
||||
2. 在 Vue data 中添加新屬性
|
||||
3. 在 `searchSummaryTable` 方法中傳遞新參數
|
||||
4. 在後端 `SearchSummaryTable` 方法中處理新參數
|
||||
|
||||
**Q: 如何修改 Excel 匯出格式?**
|
||||
A: 在 EXPORT 邏輯中自訂 Excel 生成代碼,調整欄寬、字體、顏色等。
|
||||
@@ -0,0 +1,199 @@
|
||||
# 講師個人費用彙整表 - 實施摘要
|
||||
|
||||
## ✅ 已完成部分
|
||||
|
||||
### 1. 前端 UI 實施
|
||||
|
||||
**檔案:** `Forms\領據系統\財稅作業與領據關帳.aspx`
|
||||
|
||||
- ✅ Tab 0: 個人費用彙整表頁面結構
|
||||
- ✅ 查詢表單 (4 個輸入欄位)
|
||||
- 起日 (date input)
|
||||
- 迄日 (date input)
|
||||
- 身分別 (dropdown)
|
||||
- 付款方式 (dropdown)
|
||||
- ✅ 操作按鈕
|
||||
- 查詢按鈕 (綠色)
|
||||
- 匯出按鈕 (藍色)
|
||||
- ✅ 查詢結果表格 (9 欄)
|
||||
- 領款人姓名、身分證字號、堂數、扣繳類別、帳戶名、付款金額、匯款帳號、銀行分行代碼、銀行分行
|
||||
- ✅ 完整 CSS 樣式
|
||||
- 按鈕樣式、表格樣式、提示訊息樣式、表單樣式等
|
||||
|
||||
### 2. Vue.js 邏輯實施
|
||||
|
||||
**檔案:** `Scripts\財稅作業與領據關帳.js`
|
||||
|
||||
- ✅ 初始化 summaryTable 物件
|
||||
```javascript
|
||||
summaryTable: {
|
||||
startDate: '',
|
||||
endDate: '',
|
||||
identity: '',
|
||||
paymentMethod: '',
|
||||
identityOptions: [],
|
||||
paymentMethodOptions: [],
|
||||
dataList: [],
|
||||
loading: false,
|
||||
message: '',
|
||||
messageType: 'info'
|
||||
}
|
||||
```
|
||||
|
||||
- ✅ 方法實施
|
||||
- `loadSummaryTableDropdowns()` - 加載下拉選項
|
||||
- `searchSummaryTable()` - 執行查詢
|
||||
- `exportSummaryTable()` - 執行匯出
|
||||
- `parseDate()` - 日期解析
|
||||
- `formatCurrency()` - 貨幣格式化
|
||||
- `downloadExcel()` - Excel 下載
|
||||
|
||||
### 3. WebService 框架實施
|
||||
|
||||
**檔案:** `Services\領據處理.asmx.cs`
|
||||
|
||||
- ✅ `SearchSummaryTable` 方法簽名
|
||||
```csharp
|
||||
public ServiceResponse SearchSummaryTable(
|
||||
string 起日,
|
||||
string 迄日,
|
||||
string 身分別,
|
||||
string 付款方式,
|
||||
string 輸出方式)
|
||||
```
|
||||
|
||||
- ✅ 日期解析邏輯
|
||||
- ✅ 輸出方式驗證 (DATA / EXPORT)
|
||||
- ✅ `個人費用彙整表Item` 資料模型
|
||||
|
||||
### 4. 樣式優化
|
||||
|
||||
**檔案:** `Styles\領據資料處理.css` 和 ASPX 內部 CSS
|
||||
|
||||
- ✅ 新增邊距類 (`ml-2`, `mt-3`, `mt-4`)
|
||||
- ✅ 表格響應式設計
|
||||
- ✅ 按鈕樣式 (綠色、藍色)
|
||||
- ✅ 警告/成功/信息訊息樣式
|
||||
- ✅ 表單欄位布局
|
||||
|
||||
## 📋 待實施部分(用戶需完成)
|
||||
|
||||
### 1. SearchSummaryTable 查詢邏輯
|
||||
|
||||
**方法位置:** `Services\領據處理.asmx.cs` 第 688 行
|
||||
|
||||
**需要完成:**
|
||||
```csharp
|
||||
// 1. 連接資料庫
|
||||
using (var conn = DAC.NewConnection())
|
||||
{
|
||||
// 2. 根據參數查詢資料
|
||||
// - startDate (起日)
|
||||
// - endDate (迄日)
|
||||
// - 身分別 (可空)
|
||||
// - 付款方式 (可空)
|
||||
|
||||
// 3. 返回 List<個人費用彙整表Item>
|
||||
var summaryData = new List<個人費用彙整表Item>();
|
||||
|
||||
// TODO: 實現查詢邏輯
|
||||
// 可參考現有的 DAC_領據.SelectPageWithRelations() 方法
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Excel 匯出邏輯
|
||||
|
||||
**方法位置:** `Services\領據處理.asmx.cs` 第 715 行
|
||||
|
||||
**需要完成:**
|
||||
```csharp
|
||||
if (輸出方式 == "EXPORT")
|
||||
{
|
||||
// 1. 生成 Excel 檔案
|
||||
// 2. 轉換為 Base64 編碼
|
||||
// 3. 返回 { excelData, fileName }
|
||||
|
||||
// 可參考現有的 Report.領據列印 實現方式
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 資料模型
|
||||
|
||||
```csharp
|
||||
public class 個人費用彙整表Item
|
||||
{
|
||||
public string 領款人姓名 { get; set; } // 講師/非講師姓名
|
||||
public string 身分證字號 { get; set; }
|
||||
public string 堂數 { get; set; } // 格式:「數量 + 單位」
|
||||
public string 扣繳類別 { get; set; }
|
||||
public string 帳戶名 { get; set; }
|
||||
public decimal 付款金額 { get; set; }
|
||||
public string 匯款帳號 { get; set; }
|
||||
public string 銀行分行代碼 { get; set; }
|
||||
public string 銀行分行 { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
## 🔗 方法調用流程
|
||||
|
||||
```
|
||||
前端查詢按鈕
|
||||
↓
|
||||
JavaScript: searchSummaryTable()
|
||||
↓
|
||||
WebService: SearchSummaryTable (輸出方式="DATA")
|
||||
↓
|
||||
返回 List<個人費用彙整表Item>
|
||||
↓
|
||||
Vue 綁定結果到表格
|
||||
```
|
||||
|
||||
```
|
||||
前端匯出按鈕
|
||||
↓
|
||||
JavaScript: exportSummaryTable()
|
||||
↓
|
||||
WebService: SearchSummaryTable (輸出方式="EXPORT")
|
||||
↓
|
||||
返回 { excelData: Base64, fileName: "..." }
|
||||
↓
|
||||
JavaScript: downloadExcel()
|
||||
↓
|
||||
瀏覽器下載檔案
|
||||
```
|
||||
|
||||
## 🛠 設定和相依性
|
||||
|
||||
- ✅ Vue.js 2.x (已在頁面加載)
|
||||
- ✅ Axios (已在頁面加載)
|
||||
- ✅ ToastMixin (已在頁面加載)
|
||||
- ✅ ApiMixin (已在頁面加載)
|
||||
|
||||
## ✨ 特色功能
|
||||
|
||||
1. **响應式設計** - 適配不同螢幕尺寸
|
||||
2. **即時驗證** - 日期範圍檢查
|
||||
3. **錯誤提示** - 友好的錯誤訊息
|
||||
4. **加載狀態** - 按鈕禁用狀態提示
|
||||
5. **貨幣格式** - 自動格式化付款金額 (NTD)
|
||||
6. **Excel 下載** - Base64 解碼下載
|
||||
|
||||
## 📝 建置狀態
|
||||
|
||||
✅ 項目已成功構建,無編譯錯誤
|
||||
|
||||
## 🚀 下一步
|
||||
|
||||
1. 實施 `SearchSummaryTable` 的查詢邏輯
|
||||
2. 實施 Excel 匯出邏輯
|
||||
3. 測試查詢和匯出功能
|
||||
4. 驗證資料正確性
|
||||
5. 性能優化 (如需要)
|
||||
|
||||
## 📞 技術支援
|
||||
|
||||
- 有任何問題,請檢查:
|
||||
1. WebService 方法是否正確傳遞參數
|
||||
2. 資料庫查詢是否返回正確欄位
|
||||
3. Excel 生成邏輯是否正確編碼為 Base64
|
||||
4. 瀏覽器開發者工具中的網路請求和回應
|
||||
@@ -0,0 +1,215 @@
|
||||
# 講師個人費用彙整表 - 檢查清單
|
||||
|
||||
## 📅 實施日期:2024
|
||||
|
||||
## ✅ 已完成項目
|
||||
|
||||
### 前端實施
|
||||
|
||||
- [x] ASPX 頁面結構(Tab 0)
|
||||
- [x] 查詢表單(4 個輸入欄位)
|
||||
- [x] 操作按鈕(查詢、匯出)
|
||||
- [x] 結果表格(9 欄)
|
||||
- [x] 訊息提示區域
|
||||
|
||||
- [x] CSS 樣式
|
||||
- [x] 表單樣式
|
||||
- [x] 按鈕樣式(綠色、藍色)
|
||||
- [x] 表格樣式(響應式、奇偶行)
|
||||
- [x] 訊息樣式(警告、成功、信息、錯誤)
|
||||
- [x] 邊距類(ml-2、mt-3、mt-4)
|
||||
|
||||
### JavaScript 實施
|
||||
|
||||
- [x] Vue.js 資料物件
|
||||
- [x] summaryTable 初始化
|
||||
- [x] 下拉清單選項陣列
|
||||
- [x] 查詢結果陣列
|
||||
- [x] 狀態標誌
|
||||
|
||||
- [x] Vue.js 方法
|
||||
- [x] loadSummaryTableDropdowns()
|
||||
- [x] searchSummaryTable()
|
||||
- [x] exportSummaryTable()
|
||||
- [x] parseDate()
|
||||
- [x] formatCurrency()
|
||||
- [x] downloadExcel()
|
||||
|
||||
### WebService 實施
|
||||
|
||||
- [x] SearchSummaryTable 方法簽名
|
||||
- [x] 參數解析
|
||||
- [x] 日期驗證
|
||||
- [x] 輸出方式驗證
|
||||
- [x] 成功/失敗回應
|
||||
|
||||
- [x] 資料模型類
|
||||
- [x] 個人費用彙整表Item
|
||||
- [x] 9 個屬性定義
|
||||
|
||||
## 📝 待完成項目
|
||||
|
||||
### 查詢邏輯
|
||||
|
||||
- [ ] 實施 SearchSummaryTable 的 TODO 查詢部分
|
||||
- [ ] 根據日期範圍查詢
|
||||
- [ ] 根據身分別篩選
|
||||
- [ ] 根據付款方式篩選
|
||||
- [ ] 返回 List<個人費用彙整表Item>
|
||||
|
||||
- [ ] 創建或修改 DAC 類別
|
||||
- [ ] DAC_個人費用彙整(新建或擴充)
|
||||
- [ ] 實施查詢方法
|
||||
|
||||
### Excel 匯出
|
||||
|
||||
- [ ] 實施 SearchSummaryTable 的 TODO 匯出部分
|
||||
- [ ] 生成 Excel 檔案
|
||||
- [ ] 轉換為 Base64 編碼
|
||||
- [ ] 返回檔案名和內容
|
||||
|
||||
## 🧪 測試計劃
|
||||
|
||||
### 單元測試
|
||||
|
||||
- [ ] 測試日期解析
|
||||
- [ ] 有效的日期格式
|
||||
- [ ] 無效的日期格式
|
||||
- [ ] 空值處理
|
||||
|
||||
- [ ] 測試查詢方法
|
||||
- [ ] 無條件查詢
|
||||
- [ ] 僅日期條件
|
||||
- [ ] 僅身分別條件
|
||||
- [ ] 僅付款方式條件
|
||||
- [ ] 多條件組合
|
||||
- [ ] 無結果情況
|
||||
|
||||
- [ ] 測試匯出方法
|
||||
- [ ] 正常匯出
|
||||
- [ ] 無資料匯出
|
||||
|
||||
### 集成測試
|
||||
|
||||
- [ ] 頁面加載
|
||||
- [ ] Tab 0 是否正確顯示
|
||||
- [ ] 下拉清單是否正確加載
|
||||
- [ ] 樣式是否正確應用
|
||||
|
||||
- [ ] 查詢功能
|
||||
- [ ] 點擊查詢按鈕
|
||||
- [ ] WebService 方法呼叫
|
||||
- [ ] 結果綁定表格
|
||||
- [ ] 訊息提示顯示
|
||||
|
||||
- [ ] 匯出功能
|
||||
- [ ] 點擊匯出按鈕
|
||||
- [ ] WebService 方法呼叫
|
||||
- [ ] Excel 檔案下載
|
||||
- [ ] 檔案內容驗證
|
||||
|
||||
### UI 測試
|
||||
|
||||
- [ ] 響應式設計
|
||||
- [ ] 桌面版(≥1024px)
|
||||
- [ ] 平板版(768px-1023px)
|
||||
- [ ] 手機版(<768px)
|
||||
|
||||
- [ ] 瀏覽器兼容性
|
||||
- [ ] Chrome
|
||||
- [ ] Firefox
|
||||
- [ ] Edge
|
||||
- [ ] Safari
|
||||
|
||||
- [ ] 用戶交互
|
||||
- [ ] 表單驗證
|
||||
- [ ] 按鈕禁用狀態
|
||||
- [ ] 加載動畫
|
||||
- [ ] 訊息自動隱藏
|
||||
|
||||
## 📊 功能驗收標準
|
||||
|
||||
### 查詢功能
|
||||
|
||||
- ✅ 系統應正確解析查詢參數
|
||||
- ✅ 系統應返回符合條件的資料
|
||||
- ✅ 系統應顯示符合的資料筆數
|
||||
- ✅ 系統應在無結果時提示用戶
|
||||
|
||||
### 匯出功能
|
||||
|
||||
- ✅ 系統應生成有效的 Excel 檔案
|
||||
- ✅ 系統應正確命名檔案(日期+時間)
|
||||
- ✅ 系統應在用戶瀏覽器中下載檔案
|
||||
- ✅ 系統應包含所有查詢結果
|
||||
|
||||
### 用戶體驗
|
||||
|
||||
- ✅ 用戶應能快速進行查詢
|
||||
- ✅ 用戶應看到清晰的結果
|
||||
- ✅ 用戶應收到操作反饋
|
||||
- ✅ 用戶應能輕鬆匯出資料
|
||||
|
||||
## 🐛 已知問題
|
||||
|
||||
(待用戶填充)
|
||||
|
||||
## 📞 後續步驟
|
||||
|
||||
1. **實施查詢邏輯**
|
||||
- 根據文檔指南完成 DAC 層查詢
|
||||
- 在 SearchSummaryTable 方法中替換 TODO
|
||||
|
||||
2. **實施匯出邏輯**
|
||||
- 選擇 Excel 生成庫(建議 NPOI)
|
||||
- 在 SearchSummaryTable 方法中替換 TODO
|
||||
|
||||
3. **執行測試**
|
||||
- 執行單元測試
|
||||
- 執行集成測試
|
||||
- 執行 UI 測試
|
||||
|
||||
4. **上線部署**
|
||||
- 代碼審查
|
||||
- QA 測試通過
|
||||
- 部署到生產環境
|
||||
|
||||
## 📎 相關文檔
|
||||
|
||||
- [個人費用彙整表.md](./個人費用彙整表.md) - 需求文檔
|
||||
- [個人費用彙整表_實施指南.md](./個人費用彙整表_實施指南.md) - 實施指南
|
||||
- [個人費用彙整表_實施摘要.md](./個人費用彙整表_實施摘要.md) - 實施摘要
|
||||
|
||||
## 💾 檔案變更記錄
|
||||
|
||||
| 檔案 | 狀態 | 說明 |
|
||||
|------|------|------|
|
||||
| Forms\領據系統\財稅作業與領據關帳.aspx | ✅ 修改 | 添加 Tab 0 內容 |
|
||||
| Scripts\財稅作業與領據關帳.js | ✅ 修改 | 添加查詢和匯出邏輯 |
|
||||
| Services\領據處理.asmx.cs | ✅ 修改 | 添加 SearchSummaryTable 方法和資料模型 |
|
||||
| Styles\領據資料處理.css | ✅ 修改 | 添加邊距類 |
|
||||
|
||||
## ✨ 開發貼士
|
||||
|
||||
1. **調試技巧**
|
||||
- 使用瀏覽器開發者工具的 Network 標籤檢查 WebService 呼叫
|
||||
- 使用 Console 檢查 JavaScript 錯誤
|
||||
- 使用 Vue 開發者工具檢查資料狀態
|
||||
|
||||
2. **性能優化**
|
||||
- 考慮分頁加載大量資料
|
||||
- 考慮緩存下拉清單選項
|
||||
- 優化 SQL 查詢效能
|
||||
|
||||
3. **安全考量**
|
||||
- 驗證用戶輸入
|
||||
- 檢查用戶權限
|
||||
- 記錄操作日誌
|
||||
|
||||
## 簽名和日期
|
||||
|
||||
開發者:_____________________ 日期:_____________
|
||||
|
||||
審核者:_____________________ 日期:_____________
|
||||
|
||||
批准者:_____________________ 日期:_____________
|
||||
@@ -0,0 +1,221 @@
|
||||
# 講師個人費用彙整表 - 快速開始指南
|
||||
|
||||
## 🎯 5 分鐘快速瞭解
|
||||
|
||||
### 已實施的功能 ✅
|
||||
|
||||
1. **前端 UI** - 完整的查詢表單和結果表格
|
||||
2. **Vue.js 邏輯** - 查詢和匯出的前端邏輯
|
||||
3. **WebService 框架** - SearchSummaryTable 方法簽名和資料模型
|
||||
|
||||
### 需要實施的功能 ⏳
|
||||
|
||||
1. **查詢邏輯** - 後端資料查詢(SQL)
|
||||
2. **Excel 匯出** - Excel 檔案生成和下載
|
||||
|
||||
## 🚀 立即開始
|
||||
|
||||
### 步驟 1: 驗證前端
|
||||
|
||||
1. 打開 Visual Studio
|
||||
2. 按 F5 或點擊「開始除錯」
|
||||
3. 導航至「財稅作業與領據關帳」頁面
|
||||
4. 驗證 Tab 0「個人費用彙整表」是否顯示
|
||||
5. 驗證查詢表單和按鈕是否可見
|
||||
|
||||
### 步驟 2: 實施查詢邏輯
|
||||
|
||||
**檔案:** `Services\領據處理.asmx.cs`
|
||||
|
||||
**方法:** `SearchSummaryTable` (第 688 行)
|
||||
|
||||
**實現步驟:**
|
||||
|
||||
```csharp
|
||||
// 1. 在 TODO 註解處添加查詢邏輯
|
||||
using (var conn = DAC.NewConnection())
|
||||
{
|
||||
// 2. 創建或使用現有的 DAC 查詢方法
|
||||
// 例如:DAC_領據、DAC_勞務費 等
|
||||
|
||||
// 3. 根據參數查詢資料
|
||||
var dac = new DAC_個人費用彙整(conn); // 假設的 DAC 類
|
||||
var summaryData = dac.SearchSummaryTable(
|
||||
startDate,
|
||||
endDate,
|
||||
身分別,
|
||||
付款方式
|
||||
);
|
||||
|
||||
// 4. 轉換為 List<個人費用彙整表Item>
|
||||
var result = new List<個人費用彙整表Item>();
|
||||
foreach (var item in summaryData)
|
||||
{
|
||||
result.Add(new 個人費用彙整表Item
|
||||
{
|
||||
領款人姓名 = item.姓名,
|
||||
身分證字號 = item.身分證,
|
||||
堂數 = $"{item.數量}{item.單位}",
|
||||
扣繳類別 = item.扣繳類別,
|
||||
帳戶名 = item.帳戶名,
|
||||
付款金額 = item.金額,
|
||||
匯款帳號 = item.帳號,
|
||||
銀行分行代碼 = item.銀行代碼,
|
||||
銀行分行 = item.銀行分行
|
||||
});
|
||||
}
|
||||
|
||||
return ServiceResponse.CreateSuccess("查詢成功", result);
|
||||
}
|
||||
```
|
||||
|
||||
### 步驟 3: 實施 Excel 匯出
|
||||
|
||||
**檔案:** `Services\領據處理.asmx.cs`
|
||||
|
||||
**方法:** `SearchSummaryTable` (第 715 行)
|
||||
|
||||
**使用 NPOI 庫的示例:**
|
||||
|
||||
```csharp
|
||||
if (輸出方式 == "EXPORT")
|
||||
{
|
||||
// 1. 執行相同的查詢取得資料
|
||||
var summaryData = dac.SearchSummaryTable(...);
|
||||
|
||||
// 2. 使用 NPOI 生成 Excel
|
||||
var workbook = new HSSFWorkbook();
|
||||
var sheet = workbook.CreateSheet("個人費用彙整");
|
||||
|
||||
// 3. 寫入表頭
|
||||
var headerRow = sheet.CreateRow(0);
|
||||
headerRow.CreateCell(0).SetCellValue("領款人姓名");
|
||||
headerRow.CreateCell(1).SetCellValue("身分證字號");
|
||||
// ... 其他欄位
|
||||
|
||||
// 4. 寫入資料
|
||||
int rowNum = 1;
|
||||
foreach (var item in summaryData)
|
||||
{
|
||||
var row = sheet.CreateRow(rowNum++);
|
||||
row.CreateCell(0).SetCellValue(item.領款人姓名);
|
||||
row.CreateCell(1).SetCellValue(item.身分證字號);
|
||||
// ... 其他欄位
|
||||
}
|
||||
|
||||
// 5. 轉換為 Base64
|
||||
using (var ms = new MemoryStream())
|
||||
{
|
||||
workbook.Write(ms);
|
||||
var excelBase64 = Convert.ToBase64String(ms.ToArray());
|
||||
|
||||
var excelResult = new
|
||||
{
|
||||
excelData = excelBase64,
|
||||
fileName = $"講師個人費用彙整表_{DateTime.Now:yyyyMMdd_HHmmss}.xlsx"
|
||||
};
|
||||
|
||||
return ServiceResponse.CreateSuccess("匯出成功", excelResult);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📝 實施檢查清單
|
||||
|
||||
實施前:
|
||||
- [ ] 備份原始代碼
|
||||
- [ ] 確認資料庫表結構
|
||||
- [ ] 準備必要的 DAC 類
|
||||
|
||||
實施中:
|
||||
- [ ] 完成查詢邏輯
|
||||
- [ ] 完成 Excel 匯出
|
||||
- [ ] 測試各種查詢條件
|
||||
|
||||
實施後:
|
||||
- [ ] 修復任何編譯錯誤
|
||||
- [ ] 進行功能測試
|
||||
- [ ] 驗證資料正確性
|
||||
- [ ] 測試 Excel 匯出
|
||||
- [ ] 檢查性能
|
||||
|
||||
## 🧪 快速測試
|
||||
|
||||
### 測試查詢功能
|
||||
|
||||
1. 打開頁面
|
||||
2. 輸入查詢條件(至少一項)
|
||||
3. 點擊「查詢」按鈕
|
||||
4. 驗證結果表格是否顯示資料
|
||||
5. 驗證訊息提示是否出現
|
||||
|
||||
### 測試匯出功能
|
||||
|
||||
1. 執行查詢獲得結果
|
||||
2. 點擊「匯出」按鈕
|
||||
3. 驗證是否下載 Excel 檔案
|
||||
4. 打開 Excel 驗證資料正確性
|
||||
|
||||
## 📊 常見問題
|
||||
|
||||
**Q: 查詢按鈕無反應?**
|
||||
A:
|
||||
- 檢查 WebService 是否正確實施
|
||||
- 檢查瀏覽器控制台是否有 JavaScript 錯誤
|
||||
- 確認 TODO 部分已實施
|
||||
|
||||
**Q: 匯出後 Excel 無法打開?**
|
||||
A:
|
||||
- 驗證 Base64 編碼是否正確
|
||||
- 確認 Excel 檔案格式正確
|
||||
- 檢查是否有特殊字符導致編碼錯誤
|
||||
|
||||
**Q: 查詢結果為空?**
|
||||
A:
|
||||
- 驗證資料庫中是否有符合條件的資料
|
||||
- 檢查查詢條件是否正確
|
||||
- 檢查資料庫連線是否正常
|
||||
|
||||
## 💡 提示
|
||||
|
||||
1. **調試技巧**
|
||||
- 使用 SQL Server Management Studio 測試 SQL 查詢
|
||||
- 使用 Postman 測試 WebService 方法
|
||||
- 使用瀏覽器開發者工具調試 JavaScript
|
||||
|
||||
2. **性能優化**
|
||||
- 為常用列添加資料庫索引
|
||||
- 考慮添加分頁功能
|
||||
- 考慮緩存下拉清單選項
|
||||
|
||||
3. **用戶體驗**
|
||||
- 添加查詢條件驗證
|
||||
- 提供清晰的錯誤訊息
|
||||
- 添加操作提示
|
||||
|
||||
## 🔗 相關資源
|
||||
|
||||
- `DOC\個人費用彙整表_實施指南.md` - 詳細實施指南
|
||||
- `DOC\個人費用彙整表_實施摘要.md` - 完整摘要
|
||||
- `DOC\個人費用彙整表_檢查清單.md` - 詳細檢查清單
|
||||
|
||||
## 📞 聯絡方式
|
||||
|
||||
如有任何問題,請參考:
|
||||
1. 查看相關文檔
|
||||
2. 檢查代碼註釋
|
||||
3. 執行測試用例
|
||||
|
||||
## ✨ 下一步
|
||||
|
||||
完成上述步驟後:
|
||||
1. ✅ 驗證所有功能正常
|
||||
2. ✅ 執行效能測試
|
||||
3. ✅ 進行用戶驗收測試
|
||||
4. ✅ 提交上線部署
|
||||
|
||||
---
|
||||
|
||||
**預計實施時間:** 2-4 小時
|
||||
**難度級別:** 中等
|
||||
**所需技能:** C#、SQL、ASP.NET WebService
|
||||
@@ -0,0 +1,62 @@
|
||||
# 扣繳明細及寄發通知
|
||||
|
||||
這是用來查詢講師領據明細與寄發郵件通知的功能
|
||||
|
||||
## 查詢畫面
|
||||
畫面:~\Forms\領據系統\財稅作業與領據關帳.aspx 裡面的 "Tab 1: 扣繳明細及寄發通知"
|
||||
Script:~\Scripts\財稅作業與領據關帳.js
|
||||
|
||||
### 查詢條件輸入
|
||||
- 起日 (日期輸入)
|
||||
- 迄日 (日期輸入)
|
||||
- 身分別 (下拉,選項來源:GetDropdownLists("身分別"))
|
||||
- 憑證類別 (下拉,選項來源:GetDropdownLists("憑證類別"))
|
||||
- 查詢按鈕 呼叫 SearchDetailTable,輸出方式="DATA"
|
||||
- 匯出按鈕 呼叫 SearchDetailTable,輸出方式="EXPORT"
|
||||
|
||||
### 寄件人與郵件內容輸入
|
||||
- 寄件人郵箱
|
||||
- 郵件主旨
|
||||
- 郵件內文
|
||||
- 發送按鈕 呼叫 SendEmail,輸出方式="SENDMAIL"
|
||||
- 預覽按鈕 呼叫 SendEmail,輸出方式="PREVIEW"
|
||||
|
||||
### 查詢結果
|
||||
#### 講師
|
||||
- 要發送勾選
|
||||
- 已發送顯示
|
||||
- 領款人姓名 (講師/非講師姓名)
|
||||
- 身分證字號
|
||||
- 戶籍地址
|
||||
- 扣繳類別
|
||||
- 合計金額 (講師 / 勞務費)
|
||||
- 應扣繳稅額
|
||||
- 服務費
|
||||
#### 講師的明細 (可展開收合)
|
||||
- 序
|
||||
- 計畫代號
|
||||
- 活動日期
|
||||
- 活動名稱 / 事由
|
||||
- 扣繳類別
|
||||
- 講師 / 勞務費
|
||||
- 應扣繳稅額
|
||||
- 服務費
|
||||
|
||||
## 後端服務
|
||||
~/Services/領據處理.asmx
|
||||
- GetDropdownLists(類別):取得下拉清單選項
|
||||
- SearchDetailTable(DateTime? 起日, DateTime? 迄日, string 身分別, string 扣繳類別, string 輸出方式)
|
||||
- 查詢講師領據明細資料
|
||||
- 輸出方式:DATA=查詢結果資料 / EXPORT=匯出Excel
|
||||
- 實際 SQL 我自己寫,DATA 輸出會符合查詢結果的畫面欄位
|
||||
- 匯出我自己寫
|
||||
- SendEmail(DateTime? 起日, DateTime? 迄日, string 身分別, string 扣繳類別, string 輸出方式, List<string> 講師非講師編號, string 寄件人郵箱, string 郵件主旨, string 郵件內文)
|
||||
- 發送郵件或輸出郵件預覽資料
|
||||
- 輸出方式:PREVIEW=輸出預覽用資料 / SENDMAIL=發送郵件
|
||||
- 講師非講師編號:從查詢結果的「要發送勾選」欄位勾上的講師非講師編號
|
||||
- 實際 SQL 我自己寫,PREVIEW 輸出會符合預覽用的畫面欄位
|
||||
- 發郵件我自己寫
|
||||
|
||||
## 樣式表
|
||||
- 儘量用現有的樣式表
|
||||
- 若要撰寫新樣式,儘量保持畫面高度緊湊
|
||||
@@ -0,0 +1,151 @@
|
||||
# 扣繳明細及寄發通知 - 實現指南
|
||||
|
||||
## 概述
|
||||
此文檔說明如何完成 "扣繳明細及寄發通知" 功能的後端實現。前端 UI 與基本服務框架已完成,需要實現核心的業務邏輯。
|
||||
|
||||
## 已實現的部分
|
||||
|
||||
### 1. 前端 (ASPX + Vue.js)
|
||||
- ✅ Tab 1 UI 布局完整,包括:
|
||||
- 查詢條件輸入欄位
|
||||
- 查詢結果表格(支持展開/收合明細)
|
||||
- 郵件設定區塊
|
||||
- 郵件預覽與發送功能
|
||||
|
||||
- ✅ JavaScript 邏輯框架:
|
||||
- `loadDetailTableDropdowns()` - 加載下拉清單
|
||||
- `searchDetailTable()` - 查詢資料
|
||||
- `exportDetailTable()` - 匯出 Excel
|
||||
- `previewEmail()` - 預覽郵件
|
||||
- `sendEmail()` - 發送郵件
|
||||
- `toggleSelectAll()` - 全選/反選
|
||||
|
||||
### 2. 後端服務基框架 (Services/領據處理.asmx.cs)
|
||||
已新增三個服務方法,框架完整但需實現 SQL 邏輯:
|
||||
- `SearchDetailTable()` - 扣繳明細查詢與匯出
|
||||
- `SendEmail()` - 郵件發送與預覽
|
||||
- `GetDropdownLists()` - 已存在,返回下拉清單
|
||||
|
||||
## 需要實現的部分
|
||||
|
||||
### 1. SearchDetailTable 方法 (Services/領據處理.asmx.cs)
|
||||
|
||||
**位置**: 約 900 行
|
||||
|
||||
**任務**:
|
||||
- 根據查詢條件查詢扣繳明細資料
|
||||
- 支持 DATA(回傳資料)和 EXPORT(匯出 Excel)兩種模式
|
||||
|
||||
**返回資料結構**(DATA 模式):
|
||||
```csharp
|
||||
List<dynamic> 或 DataTable
|
||||
{
|
||||
編號 (或 ID/no) - 用於郵件發送時識別收件者
|
||||
領款人姓名
|
||||
身分證字號
|
||||
戶籍地址
|
||||
扣繳類別
|
||||
合計金額
|
||||
應扣繳稅額
|
||||
服務費
|
||||
已發送 (boolean) - 判斷是否已發送過郵件
|
||||
明細 - List<dynamic> 或 nested DataTable
|
||||
{
|
||||
計畫代號
|
||||
活動日期
|
||||
活動名稱
|
||||
扣繳類別
|
||||
金額 (講師/勞務費)
|
||||
應扣繳稅額
|
||||
服務費
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**實現建議**:
|
||||
1. 使用 DAC_領據 與相關 DAC 類別查詢
|
||||
2. 按日期與身分別條件篩選
|
||||
3. 使用講師非講師編號進行分組
|
||||
4. 對於 EXPORT 模式,可建立新的 Report 類別或使用現有的 Excel 工具
|
||||
|
||||
### 2. SendEmail 方法 (Services/領據處理.asmx.cs)
|
||||
|
||||
**位置**: 約 950 行
|
||||
|
||||
**任務**:
|
||||
- PREVIEW 模式:組織郵件預覽資料
|
||||
- SENDMAIL 模式:實際發送郵件
|
||||
|
||||
**實現建議**:
|
||||
1. PREVIEW 模式:返回將發送的郵件預覽,供確認
|
||||
2. SENDMAIL 模式:
|
||||
- 遍歷 `講師非講師編號` 列表
|
||||
- 根據編號查詢收件者郵箱地址
|
||||
- 使用 .NET 的 SmtpClient 或郵件服務發送
|
||||
- 記錄發送時間至資料庫(更新「已發送」欄位)
|
||||
- 返回成功/失敗統計
|
||||
|
||||
**注意**:
|
||||
- 需要配置 SMTP 服務設定(郵件伺服器、帳號密碼等)
|
||||
- 考慮錯誤處理:單個郵件失敗不應中斷整個流程
|
||||
- 建議記錄郵件發送日誌
|
||||
|
||||
### 3. 資料庫相關
|
||||
|
||||
**需要確認**:
|
||||
- 講師/非講師資料表中是否有郵箱欄位
|
||||
- 是否有「郵件發送記錄」表來追蹤已發送狀態
|
||||
- 領據資料表的結構與關聯
|
||||
|
||||
### 4. DAC 擴展(如需要)
|
||||
|
||||
**可能需要新增方法**:
|
||||
- `DAC_領據.SelectDetailByDate()` - 按日期範圍查詢明細
|
||||
- 郵件發送記錄相關的 DAC 操作
|
||||
- 收件者郵箱查詢方法
|
||||
|
||||
## 前端資料綁定說明
|
||||
|
||||
### ASPX 欄位映射
|
||||
|
||||
查詢結果表格預期從後端接收以下欄位:
|
||||
|
||||
| 前端顯示 | 資料欄位 | 說明 |
|
||||
|---------|--------|------|
|
||||
| 要發送勾選 | item.selected | Vue.js 雙向綁定 |
|
||||
| 已發送 | item.已發送 | boolean |
|
||||
| 領款人姓名 | item.領款人姓名 | string |
|
||||
| 身分證字號 | item.身分證字號 | string |
|
||||
| 戶籍地址 | item.戶籍地址 | string |
|
||||
| 扣繳類別 | item.扣繳類別 | string |
|
||||
| 合計金額 | item.合計金額 | decimal |
|
||||
| 應扣繳稅額 | item.應扣繳稅額 | decimal |
|
||||
| 服務費 | item.服務費 | decimal |
|
||||
| 明細展開 | item.showDetail | Vue.js 控制 |
|
||||
| 明細列表 | item.明細 | List<dynamic> |
|
||||
|
||||
## 編號欄位處理
|
||||
|
||||
JavaScript 代碼支持多種 ID 欄位名稱:
|
||||
```javascript
|
||||
item.ID || item.編號 || item.no
|
||||
```
|
||||
|
||||
**選擇一個作為主要欄位即可**
|
||||
|
||||
## 測試檢查清單
|
||||
|
||||
- [ ] GetDropdownLists 能正確返回身分別與憑證類別
|
||||
- [ ] SearchDetailTable(DATA) 返回結構化的查詢結果
|
||||
- [ ] SearchDetailTable(EXPORT) 能成功匯出 Excel
|
||||
- [ ] SendEmail(PREVIEW) 能正確組織郵件預覽資料
|
||||
- [ ] SendEmail(SENDMAIL) 能正確發送郵件
|
||||
- [ ] 郵件發送後,已發送欄位應更新為是
|
||||
|
||||
## 相關檔案
|
||||
|
||||
- 前端: `Forms\領據系統\財稅作業與領據關帳.aspx`
|
||||
- JavaScript: `Scripts\財稅作業與領據關帳.js`
|
||||
- 後端服務: `Services\領據處理.asmx.cs`
|
||||
- 資料存取: `DAC\領據系統\DAC_領據2.cs`
|
||||
- 文件: `DOC\扣繳明細及寄發通知.md`
|
||||
@@ -0,0 +1,31 @@
|
||||
# 教學日誌修改紀錄
|
||||
|
||||
## 2026-07-24 修改:還原為簡化版表單
|
||||
|
||||
### 異動說明
|
||||
客戶要求移除近期新增的 14 個欄位,還原為簡化版表單。
|
||||
|
||||
### 表單新設計
|
||||
|
||||
| 欄位 | 控制項 | 說明 |
|
||||
|------|--------|------|
|
||||
| 異常情形 | RadioButtonList (無/有) + TextBox + 片語按鈕 | 選「有」時可輸入異常描述 |
|
||||
| 處理過程及建議 | TextBox (MultiLine) | 原「處理經過與結果」改名 |
|
||||
| 處理結果追蹤 | TextBox (MultiLine) | 新增欄位 |
|
||||
|
||||
### 異動檔案
|
||||
|
||||
| 檔案 | 動作 |
|
||||
|------|------|
|
||||
| `Forms\辦訓狀況\教學日誌處理.aspx` | 移除 14 個 ObjectDataSource;ItemTemplate/InsertItemTemplate/EditItemTemplate 將 14 欄位用 `<%-- --%>` 註解;異常情形改 RadioButtonList + TextBox + 片語;處理經過與結果→處理過程及建議;新增處理結果追蹤欄位 |
|
||||
| `Forms\辦訓狀況\教學日誌處理.aspx.cs` | 移除 `控制異常欄位顯示`、`ddl有無異常事項_SelectedIndexChanged`、`ddl異常類型_SelectedIndexChanged`;新增 `btn片語_Click` 空方法 |
|
||||
| `Forms\檢視UC\教學日誌暨異常狀況View.ascx` | 14 欄位用 `<%-- --%>` 註解;異常情形改 RadioButtonList + Label;處理經過與結果→處理過程及建議;新增處理結果追蹤顯示 |
|
||||
|
||||
### 保留未異動
|
||||
|
||||
| 檔案 | 說明 |
|
||||
|------|------|
|
||||
| `DAC\辦訓狀況\DAC_教學日誌1.cs` | 保留所有欄位(含 14 新增欄位),資料庫欄位不動 |
|
||||
| `DAC\辦訓狀況\DAC_教學日誌2.cs` | 不異動 |
|
||||
| `DAC\辦訓狀況\DAC_教學日誌選項.cs` | 保留所有方法(課程執行觀察、有無異常事項、異常類型、異常處理結果) |
|
||||
| 資料庫 | 保留所有欄位,不刪除 |
|
||||
@@ -0,0 +1,37 @@
|
||||
|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 課程企劃編號 | 節次 | 講師 |
|
||||
|-----------------|----------------|-----------------------------------------------------------------------------------------------------------------------------|
|
||||
| 應到人數 | 實到人數 | 缺席人數 |
|
||||
|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 課程執行觀察 | 1.課程是否依原訂計畫執行 | □ 符合原訂計畫 □ 部分調整 □ 未依原訂計畫執行,調整或未依計畫執行之說明:______(多行輸入) |
|
||||
| |--------------------------|-------------------------------------------------------------------------------------------------------------------|
|
||||
| (請依課程現場 | 2.課程進度 | □ 超前 □ 符合規劃 □ 略有落後 □ 未完成 |
|
||||
| |--------------------------|-------------------------------------------------------------------------------------------------------------------|
|
||||
| 觀察,勾選最 | 3.講師授課情形 | □ 優良 □ 良好 □ 普通 □ 待改善 |
|
||||
| |--------------------------|-------------------------------------------------------------------------------------------------------------------|
|
||||
| 符合本次課程執 | 4.學員參與互動 | □ 非常踴躍 □ 踴躍 □ 普通 □ 不佳 |
|
||||
| |--------------------------|-------------------------------------------------------------------------------------------------------------------|
|
||||
| 行情形之選項) | 5.學員學習投入 | □ 積極投入 □ 大多投入 □ 部分投入 □ 投入度不足 |
|
||||
| |--------------------------|-------------------------------------------------------------------------------------------------------------------|
|
||||
| | 6.學員課堂回應情形 | □ 能主動分享工作經驗或案例 □ 能回應提問並連結工作情境 □ 經引導後能連結工作情境 □ 未觀察到相關回應 □ 不適用|
|
||||
| |--------------------------|-------------------------------------------------------------------------------------------------------------------|
|
||||
| | 7.實作/活動完成情形 | □ 全數完成 □ 大部分完成 □ 部分完成 □ 未完成 □ 不適用 |
|
||||
| |--------------------------|-------------------------------------------------------------------------------------------------------------------|
|
||||
| | 8.教學設備及場地 | □ 正常 □ 輕微異常 □ 影響授課 □ 無法使用 |
|
||||
|----------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 註:如勾選略有落後、未完成、待改善、不佳、投入度不足、影響授課或無法使用等情形,請於下方說明 |
|
||||
|----------------|-----------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 課程觀察紀錄 | 1.本次課程值得保留或表現良好之處 |
|
||||
| | 2.本次課程可改善事項及建議 |
|
||||
|----------------|-----------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 異常情形 | □ 有 □ 無(勾無不需填寫) |
|
||||
|----------------|-----------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 處理過程及建議 | ___________________(多行輸入) |
|
||||
|----------------|-----------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 是否需後續追蹤 | □ 否,異常狀況順利解決,本案已結案 |
|
||||
| | □ 是,追蹤事項:___________________(多行輸入) |
|
||||
|----------------|-----------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 處理結果追蹤 | ___________________(多行輸入) |
|
||||
|----------------|-----------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 填表人員 | 填表日期
|
||||
|----------------|-----------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
@@ -0,0 +1,60 @@
|
||||
# 檢討報告修改
|
||||
|
||||
|
||||
## 增加欄位
|
||||
|
||||
| No | Field Name | Data Type | Length | Not Null | PK | Identity | Description | UI Order | UI Control | UI Label |
|
||||
| --- | ------------------ | --------- | ------ | -------- | --- | -------- | ------------------------------------------------------------------ | -------- | ---------- | -------- |
|
||||
| 8 | 改善措施_學員_改善內容 | NVARCHAR | 50 | | | | 改善措施_學員_ 改善內容 複選(checkboxes) 逗號分隔 1=加強課前提醒 2=增加案例分享 3=增加實作練習 4=提供課後學習資源 9=其他 | FIELD9 | FIELD10 | 改善內容 |
|
||||
| 9 | 改善措施_學員_改善內容_其他 | NVARCHAR | 200 | | | | 改善措施_學員_ 改善內容_其他 改善措施_學員_ 改善內容=9 時必填 | | | |
|
||||
| 10 | 改善措施_學員_改善作法 | INT | | | | | 改善措施_學員_ 改善作法 單選 1=納入下次課程 2=修訂教材 3=修訂表單 4=修訂SOP 5=修訂訓練品質手冊 9=其他 | | | 改善作法 |
|
||||
| 11 | 改善措施_學員_改善作法_其他 | NVARCHAR | 200 | | | | 改善措施_學員_ 改善作法_其他 改善措施_學員_ 改善作法=9 時必填 | | | |
|
||||
| 12 | 改善措施_學員_補充說明 | NVARCHAR | 200 | | | | 改善措施_學員_ 補充說明 | | | 補充說明 |
|
||||
| 13 | 改善措施_講師_改善內容 | NVARCHAR | 50 | | | | 改善措施_講師_ 改善內容 複選(checkboxes) 逗號分隔 1=調整授課節奏 2=加強重點說明 3=增加課堂互動 4=課前確認授課需求 9=其他 | | | 改善內容 |
|
||||
| 14 | 改善措施_講師_改善內容_其他 | NVARCHAR | 200 | | | | 改善措施_講師_ 改善內容_其他 改善措施_講師_ 改善內容=9 時必填 | | | |
|
||||
| 15 | 改善措施_講師_改善作法 | INT | | | | | 改善措施_講師_ 改善作法 單選 1=納入下次課程 2=修訂教材 3=修訂表單 4=修訂SOP 5=修訂訓練品質手冊 9=其他 | | | 改善作法 |
|
||||
| 16 | 改善措施_講師_改善作法_其他 | NVARCHAR | 200 | | | | 改善措施_講師_ 改善作法_其他 改善措施_講師_ 改善作法=9 時必填 | | | |
|
||||
| 17 | 改善措施_講師_補充說明 | NVARCHAR | 200 | | | | 改善措施_講師_ 補充說明 | | | 補充說明 |
|
||||
| 18 | 改善措施_教材及教具_改善內容 | NVARCHAR | 50 | | | | 改善措施_教材及教具_ 改善內容 複選(checkboxes) 逗號分隔 1=修正教材內容 2=更新教材資料 3=增加教具輔助 4=提供電子教材 9=其他 | | | 改善內容 |
|
||||
| 19 | 改善措施_教材及教具_改善內容_其他 | NVARCHAR | 200 | | | | 改善措施_教材及教具_ 改善內容_其他 改善措施_教材及教具_ 改善內容=9 時必填 | | | |
|
||||
| 20 | 改善措施_教材及教具_改善作法 | INT | | | | | 改善措施_教材及教具_ 改善作法 單選 1=納入下次課程 2=修訂教材 3=修訂表單 4=修訂SOP 5=修訂訓練品質手冊 9=其他 | | | 改善作法 |
|
||||
| 21 | 改善措施_教材及教具_改善作法_其他 | NVARCHAR | 200 | | | | 改善措施_教材及教具_ 改善作法_其他 改善措施_教材及教具_ 改善作法=9 時必填 | | | |
|
||||
| 22 | 改善措施_教材及教具_補充說明 | NVARCHAR | 200 | | | | 改善措施_教材及教具_ 補充說明 | | | 補充說明 |
|
||||
| 23 | 改善措施_教學方法_改善內容 | NVARCHAR | 50 | | | | 改善措施_教學方法_ 改善內容 複選(checkboxes) 逗號分隔 1=增加案例討論 2=增加分組互動 3=增加實作演練 4=調整教學方式 9=其他 | | | 改善內容 |
|
||||
| 24 | 改善措施_教學方法_改善內容_其他 | NVARCHAR | 200 | | | | 改善措施_教學方法_ 改善內容_其他 改善措施_教學方法_ 改善內容=9 時必填 | | | |
|
||||
| 25 | 改善措施_教學方法_改善作法 | INT | | | | | 改善措施_教學方法_ 改善作法 單選 1=納入下次課程 2=修訂教材 3=修訂表單 4=修訂SOP 5=修訂訓練品質手冊 9=其他 | | | 改善作法 |
|
||||
| 26 | 改善措施_教學方法_改善作法_其他 | NVARCHAR | 200 | | | | 改善措施_教學方法_ 改善作法_其他 改善措施_教學方法_ 改善作法=9 時必填 | | | |
|
||||
| 27 | 改善措施_教學方法_補充說明 | NVARCHAR | 200 | | | | 改善措施_教學方法_ 補充說明 | | | 補充說明 |
|
||||
| 28 | 改善措施_場地及設備_改善內容 | NVARCHAR | 50 | | | | 改善措施_場地及設備_ 改善內容 複選(checkboxes) 逗號分隔 1=調整教室配置 2=增加設備數量 3=提前測試設備 4=改善上課環境 9=其他 | | | 改善內容 |
|
||||
| 29 | 改善措施_場地及設備_改善內容_其他 | NVARCHAR | 200 | | | | 改善措施_場地及設備_ 改善內容_其他 改善措施_場地及設備_ 改善內容=9 時必填 | | | |
|
||||
| 30 | 改善措施_場地及設備_改善作法 | INT | | | | | 改善措施_場地及設備_ 改善作法 單選 1=納入下次課程 2=修訂教材 3=修訂表單 4=修訂SOP 5=修訂訓練品質手冊 9=其他 | | | 改善作法 |
|
||||
| 31 | 改善措施_場地及設備_改善作法_其他 | NVARCHAR | 200 | | | | 改善措施_場地及設備_ 改善作法_其他 改善措施_場地及設備_ 改善作法=9 時必填 | | | |
|
||||
| 32 | 改善措施_場地及設備_補充說明 | NVARCHAR | 200 | | | | 改善措施_場地及設備_ 補充說明 | | | 補充說明 |
|
||||
| 33 | 改善措施_行政流程_改善內容 | NVARCHAR | 50 | | | | 改善措施_行政流程_ 改善內容 複選(checkboxes) 逗號分隔 1=提前通知資訊 2=調整報到流程 3=強化行政協助 4=加強課後追蹤 9=其他 | | | 改善內容 |
|
||||
| 34 | 改善措施_行政流程_改善內容_其他 | NVARCHAR | 200 | | | | 改善措施_行政流程_ 改善內容_其他 改善措施_行政流程_ 改善內容=9 時必填 | | | |
|
||||
| 35 | 改善措施_行政流程_改善作法 | INT | | | | | 改善措施_行政流程_ 改善作法 單選 1=納入下次課程 2=修訂教材 3=修訂表單 4=修訂SOP 5=修訂訓練品質手冊 9=其他 | | | 改善作法 |
|
||||
| 36 | 改善措施_行政流程_改善作法_其他 | NVARCHAR | 200 | | | | 改善措施_行政流程_ 改善作法_其他 改善措施_行政流程_ 改善作法=9 時必填 | | | |
|
||||
| 37 | 改善措施_行政流程_補充說明 | NVARCHAR | 200 | | | | 改善措施_行政流程_ 補充說明 | | | 補充說明 |
|
||||
|
||||
|
||||
## 增加欄位的畫面排列
|
||||
|
||||
改善措施 | 改善內容 | 改善作法 | 補充說明
|
||||
-------------|------------------|-----------------|--------------
|
||||
學員 | {checkbox group} | {下拉 } | {輸入
|
||||
| {其他輸入 } | {其他輸入 } | }
|
||||
-------------|------------------|-----------------|--------------
|
||||
講師 | {checkbox group} | {下拉 } | {輸入
|
||||
| {其他輸入 } | {其他輸入 } | }
|
||||
-------------|------------------|-----------------|--------------
|
||||
教材及教具 | {checkbox group} | {下拉 } | {輸入
|
||||
| {其他輸入 } | {其他輸入 } | }
|
||||
-------------|------------------|-----------------|--------------
|
||||
教學方法 | {checkbox group} | {下拉 } | {輸入
|
||||
| {其他輸入 } | {其他輸入 } | }
|
||||
-------------|------------------|-----------------|--------------
|
||||
場地及設備 | {checkbox group} | {下拉 } | {輸入
|
||||
| {其他輸入 } | {其他輸入 } | }
|
||||
-------------|------------------|-----------------|--------------
|
||||
行政流程 | {checkbox group} | {下拉 } | {輸入
|
||||
| {其他輸入 } | {其他輸入 } | }
|
||||
@@ -0,0 +1,104 @@
|
||||
# 規格文件範本
|
||||
|
||||
> 說明:此文件為專案功能/技術規格範本。請依專案需求填寫每個章節,保留章節順序以利審查與版本對照。
|
||||
|
||||
---
|
||||
|
||||
##1. 文件摘要
|
||||
- 文件名稱:
|
||||
-版本:
|
||||
- 作者:
|
||||
- 建立日期:
|
||||
-目的:簡要說明此規格要達成的目標與範圍。
|
||||
|
||||
##2. 範圍與背景
|
||||
- 專案名稱:
|
||||
- 背景說明:為何需要此功能或變更。
|
||||
- 範圍:包含與不包含的功能項目(In-scope / Out-of-scope)。
|
||||
|
||||
##3.目標與成功指標
|
||||
-目標:列出可衡量的技術或業務目標。
|
||||
- 成功指標(KPI / 驗收準則):例如性能、穩定度、完成時間等。
|
||||
|
||||
##4. 用戶故事(或功能清單)
|
||||
- 功能1(範例)
|
||||
- 說明:
|
||||
- 使用者:
|
||||
- 前置條件:
|
||||
- 行為流程:
|
||||
- 驗收標準(AC):
|
||||
- 功能2 ...
|
||||
|
||||
##5. API /介面定義
|
||||
-介面名稱:
|
||||
- 方法(HTTP / 函式):
|
||||
- 路徑:
|
||||
-參數:
|
||||
- 名稱:
|
||||
- 型別:
|
||||
- 必要性:
|
||||
- 範例:
|
||||
- 回傳格式(範例 JSON 或 XML):
|
||||
- 錯誤代碼與描述:
|
||||
|
||||
##6. 資料模型(Domain Model / DB Schema)
|
||||
- 實體:
|
||||
- 欄位:名稱、型別、長度、說明、範例
|
||||
- 關聯圖(如有):
|
||||
|
||||
##7. 非功能需求
|
||||
- 相容性:例如需支援 `.NET Framework2.0` / `.NET Framework3.5`(若適用,請註明)
|
||||
- 性能:響應時間、並發數、吞吐量
|
||||
- 可用性 / 可維護性:SLA、備援需求
|
||||
- 安全性:認證、授權、資料加密、輸入驗證
|
||||
- 國際化 / 在地化(若適用)
|
||||
|
||||
##8. 錯誤與例外處理規則
|
||||
- 錯誤回傳格式:
|
||||
- 日誌需求:錯誤等級、要記錄的欄位
|
||||
- 重試與補救流程(若適用)
|
||||
|
||||
##9. 使用者介面(UI)
|
||||
- 頁面或畫面清單:
|
||||
- 每個畫面的需求與資料欄位:
|
||||
-主要互動流程(流程圖或步驟)
|
||||
|
||||
##10. 相依性與第三方套件
|
||||
-需安裝或使用的 library / 套件(含版本):
|
||||
- 外部服務或 API:
|
||||
|
||||
##11. 部署與操作
|
||||
- 部署流程(步驟、環境、指令或腳本):
|
||||
- 配置檔:需要哪些參數或環境變數
|
||||
-監控與告警:
|
||||
|
||||
##12. 測試計畫
|
||||
- 測試範圍:單元測試、整合測試、端對端測試
|
||||
- 驗收測試(UAT)條件:
|
||||
- 測試資料與測試案例範例:
|
||||
|
||||
##13.里程碑與時程
|
||||
-版本 /里程碑:預計完成日期
|
||||
-交付內容:
|
||||
|
||||
##14.交付物與驗收
|
||||
-交付物清單:程式碼、文件、測試報告、部署指引
|
||||
- 驗收流程與簽核人員:
|
||||
|
||||
##15.風險與備援措施
|
||||
- 已辨識風險項目:
|
||||
-風險等級與緩解策略:
|
||||
|
||||
##16.參考與附錄
|
||||
-相關文件或連結:
|
||||
- 資料字典、範例請求/回應:
|
||||
|
||||
##17.版本紀錄
|
||||
- v0.1 日期 - 作者 - 說明
|
||||
- v1.0 日期 - 作者 - 發佈
|
||||
|
||||
---
|
||||
|
||||
附註:
|
||||
- 建議以此範本為基礎,針對每個專案需求增減章節。
|
||||
- 若需 Word(.docx)版本,可另行產生或轉換。
|
||||
@@ -0,0 +1,35 @@
|
||||
# 講師個人費用彙整表
|
||||
|
||||
這是用來彙整講師個人費用的查詢與報表
|
||||
|
||||
## 查詢畫面
|
||||
畫面:~\Forms\領據系統\財稅作業與領據關帳.aspx 裡面的 "Tab 0: 個人費用彙整表"
|
||||
Script:~\Scripts\財稅作業與領據關帳.js
|
||||
|
||||
### 查詢條件輸入
|
||||
- 起日 (日期輸入)
|
||||
- 迄日 (日期輸入)
|
||||
- 身分別 (下拉,選項來源:GetDropdownLists("身分別"))
|
||||
- 付款方式 (下拉,選項來源:GetDropdownLists("付款方式"))
|
||||
- 查詢按鈕 呼叫 SearchSummaryTable,輸出方式="DATA"
|
||||
- 匯出按鈕 呼叫 SearchSummaryTable,輸出方式="EXPORT"
|
||||
|
||||
### 查詢結果
|
||||
- 領款人姓名 (講師/非講師姓名)
|
||||
- 身分證字號
|
||||
- 堂數 (數量 + 單位)
|
||||
- 扣繳類別
|
||||
- 帳戶名
|
||||
- 付款金額
|
||||
- 匯款帳號
|
||||
- 銀行分行代碼
|
||||
- 銀行分行
|
||||
|
||||
## 後端服務
|
||||
~/Services/領據處理.asmx
|
||||
- GetDropdownLists(類別):取得下拉清單選項
|
||||
- SearchSummaryTable(DateTime? 起日, DateTime? 迄日, string 身分別, string 付款方式, string 輸出方式)
|
||||
- 查詢講師個人費用彙整表資料
|
||||
- 輸出方式:DATA=查詢結果資料 / EXPORT=匯出Excel
|
||||
- 實際 SQL 我自己寫,DATA 輸出會符合查詢結果的畫面欄位
|
||||
- 匯出我自己寫
|
||||
@@ -0,0 +1,31 @@
|
||||
# 財稅作業與領據關帳.aspx
|
||||
|
||||
## 畫面
|
||||
* 畫面檔:財稅作業與領據關帳.aspx
|
||||
* 三個 Tab 以及 MultiView 中的 View
|
||||
- 個人費用彙整表
|
||||
- 扣繳明細及寄發通知
|
||||
- 領據關帳
|
||||
|
||||
### 個人費用彙整表
|
||||
建置中
|
||||
|
||||
### 扣繳明細及寄發通知
|
||||
建置中
|
||||
|
||||
### 領據關帳
|
||||
* 上方是提示訊息
|
||||
* 費用出帳後,財務即將領據關帳。
|
||||
* 領據關帳後,只能作廢不能修改,唯總管理處財務部可修改。
|
||||
|
||||
* 接下來是三個輸入框以及確定按鈕
|
||||
* 領據現行年度:今年 (不可修改)
|
||||
* 領據已關帳年月:目前的關帳年月
|
||||
* 調整關帳年月為:欲修改的關帳年月
|
||||
|
||||
* 使用後端 asmx 為 API
|
||||
* 關帳年月存入 BWEX 表
|
||||
* BSNUM = '領據關帳年月'
|
||||
* BSITM = ' 1'
|
||||
* BSNAM = 關帳年月,格式 YYYY-MM
|
||||
|
||||
@@ -0,0 +1,233 @@
|
||||
|
||||
# 領據資料作業
|
||||
|
||||
## 前端程式碼:
|
||||
* 使用 Vue.js 實現動態資料綁定與操作。
|
||||
* 不使用 Server control
|
||||
* script 部分分離出來放置到 Scripts 目錄
|
||||
* 使用現代寫法,不要管 IE 相容性
|
||||
* 比照 付款設定.ascx 以及 付款設定.js 的作法
|
||||
|
||||
## 後端程式碼:
|
||||
* 使用 WebService 實現非同步資料交換。
|
||||
* 提供 API 端點處理領據、勞務費、差旅費資料的新增、修改、刪除、作廢、列印等需求。
|
||||
|
||||
## 主畫面檔:~/Forms/領據系統/領據資料作業.aspx
|
||||
|
||||
### 子畫面檔
|
||||
* Tab、MultiView、View 以及 User Control 已經放好了:
|
||||
* 查詢: ~/Forms/領據系統/領據查詢.ascx
|
||||
* 領據登錄與修改:~/Forms/領據系統/領據處理.ascx
|
||||
* 列印: ~/Forms/領據系統/領據列印.ascx
|
||||
* 匯入與匯出: ~/Forms/領據系統/領據匯出匯入.ascx
|
||||
|
||||
### 寫碼規範
|
||||
* 把 script 部分分開寫在 Scripts 目錄
|
||||
* 使用現代寫法,不要管 IE 相容性
|
||||
* 比照 付款設定.ascx 以及 付款設定.js 的作法
|
||||
|
||||
## 資料存取類別
|
||||
### Education.DAC_領據
|
||||
* 既有程式
|
||||
* 分為兩個檔案 ~/DAC/領據系統/DAC_領據1.cs 和 ~/DAC/領據系統/DAC_領據2.cs
|
||||
* 若需要擴充,加在結尾 2.cs 裡
|
||||
* DAC_領據:資料處理類別
|
||||
* 分頁查詢資料:public 領據List SelectPage(bool noInputReturnAll, int startRowIndex, int maximumRows, DateTime? 活動日期_1, DateTime? 活動日期_2, string 身分別, string 講師_非講師編號, string 憑證類別, string 計畫代號, string 計畫名稱, string 活動類別, string 付款方式, string orderBy = "")
|
||||
* 查詢筆數: public int SelectCount(bool noInputReturnAll, DateTime? 活動日期_1, DateTime? 活動日期_2, string 身分別, string 講師_非講師編號, string 憑證類別, string 計畫代號, string 計畫名稱, string 活動類別, string 付款方式, string orderBy = "")
|
||||
* 新增: public 領據Item InsertOne(領據Item value)
|
||||
* 修改: public 領據Item UpdateOne(領據Item value)
|
||||
* 刪除: public int DeleteOne(string 編號, int DB_APPNO)
|
||||
* 領據List:資料集類別
|
||||
* 領據Item:資料項目類別
|
||||
|
||||
### Education.DAC_勞務費
|
||||
* 既有程式
|
||||
* 分為兩個檔案 ~/DAC/領據系統/DAC_勞務費1.cs 和 ~/DAC/領據系統/DAC_勞務費2.cs
|
||||
* 若需要擴充,加在結尾 2.cs 裡
|
||||
* DAC_勞務費:資料處理類別
|
||||
* 查詢:SelectOne(string 領據編號)
|
||||
* 新增:InsertOne(勞務費Item value)
|
||||
* 修改:UpdateOne(勞務費Item value)
|
||||
* 刪除:DeleteOne(string 領據編號, int DB_APPNO)
|
||||
|
||||
### Education.DAC_差旅費
|
||||
* 既有程式
|
||||
* 分為兩個檔案 ~/DAC/領據系統/DAC_差旅費1.cs 和 ~/DAC/領據系統/DAC_差旅費2.cs
|
||||
* 若需要擴充,加在結尾 2.cs 裡
|
||||
* DAC_差旅費:資料處理類別
|
||||
* 查詢:SelectOne(string 領據編號)
|
||||
* 新增:InsertOne(差旅費Item value)
|
||||
* 修改:UpdateOne(差旅費Item value)
|
||||
* 刪除:DeleteOne(string 領據編號, int DB_APPNO)
|
||||
|
||||
### 資料關聯
|
||||
* 1 領據 (編號) <-----> 0-1 勞務費 (領據編號)
|
||||
* 1 領據 (編號) <-----> 0-1 差旅費 (領據編號)
|
||||
|
||||
|
||||
## WebService 端點
|
||||
|
||||
### 領據資料:Services/領據處理.asmx
|
||||
|
||||
* EnableSession(True)
|
||||
|
||||
* SelectPage(int pageIndex, int pageSize, DateTime? 活動日期_1, DateTime? 活動日期_2, string 身分別, string 講師_非講師編號, string 憑證類別, string 計畫代號, string 計畫名稱, string 活動類別, string 付款方式, string orderBy = "")
|
||||
- pageIndex 從 1 開始
|
||||
- pageSize 預設 20
|
||||
- 查詢 function 用 DAC_領據.SelectPage
|
||||
- 筆數 function 用 DAC_領據.SelectCount
|
||||
bool noInputReturnAll (固定傳 true)
|
||||
int startRowIndex (分頁起點)
|
||||
int maximumRows (分頁大小)
|
||||
|
||||
- 空白條件視為不限制(noInputReturnAll = true)
|
||||
- 回傳:ServiceResponse(Success, Message, Data: 領據List, TotalCount: 總筆數 )
|
||||
|
||||
* Save(bool isNew, 領據Item mainItem, 勞務費Item laborItem, 差旅費Item travelItem):存檔
|
||||
- isNew:是否為新增
|
||||
- mainItem:新增或更正的領據資料
|
||||
- laborItem:新增或更正的勞務費資料
|
||||
- travelItem:新增或更正的差旅費資料
|
||||
- 新增呼叫 DAC_領據.InsertOne(領據Item value)
|
||||
- 修改呼叫 DAC_領據.UpdateOne(領據Item value)
|
||||
- 回傳:ServiceResponse(Success, Message)
|
||||
|
||||
* Delete(string no):刪除領據
|
||||
- no:要刪除的領據編號
|
||||
- 呼叫 DAC_領據.DeleteOne(string 編號, int DB_APPNO)
|
||||
- 一併刪除關聯的勞務費與差旅費資料
|
||||
- 回傳:ServiceResponse(Success, Message)
|
||||
|
||||
* Void(string no):作廢/取消作廢領據
|
||||
- no:要作廢/取消作廢的領據編號
|
||||
- 呼叫 DAC_領據.UpdateOne(領據Item value) 只修改作廢欄位 1=作廢 0=未作廢
|
||||
- 回傳:ServiceResponse(Success, Message)
|
||||
|
||||
* CalcTax(int laborFee, string category):計算稅額
|
||||
* 輸入勞務費計算稅額
|
||||
* 執行業務 (category 是 9A, 9B 開頭) laborFee >= 20000:laborFee * 10% 四捨五入至整數
|
||||
* 薪資 (category 是 50) laborFee >= 88501:laborFee * 5% 四捨五入至整數
|
||||
|
||||
* Print(List<int> iDList): 列印領據
|
||||
* 一張一張的列印領據
|
||||
* 領據列印有兩個單據:勞務費和差旅費
|
||||
* 先實作取資料以及跑迴圈部分,列印的實作先留空,我後續補充
|
||||
* 若有勞務費,且勞務費的編號是空的,要給勞務費自動編號,詳情我自己寫,你加個 TODO 就好
|
||||
* 若有差旅費,且差旅費的編號是空的,要給差旅費自動編號,詳情我自己寫,你加個 TODO 就好
|
||||
* 如同火車票價匯出一樣返回一個 Excel 檔
|
||||
|
||||
### 火車票價:Services/火車票價.asmx
|
||||
|
||||
* EnableSession(True)
|
||||
* 車站自動完成搜尋:SelectStation(string key)
|
||||
* 查詢呼叫 DAC_火車票價.查詢車站(key)
|
||||
* 回傳:ServiceResponse(Success, Message, Data: 查詢結果)
|
||||
* 計算票價:SelectFare(起點, 訖點)
|
||||
* 查詢呼叫 DAC_火車票價.查詢票價(起點, 訖點)
|
||||
* 回傳:ServiceResponse(Success, Message, Data: 票價)
|
||||
|
||||
## 畫面排列:
|
||||
### 查詢:
|
||||
|
||||
* 上方:搜尋列
|
||||
- 查詢條件
|
||||
| 編號 | 顯示名稱 | 查詢參數 | 輸入元件 | 下拉資料來源 |
|
||||
| ---- | ------------ | ---------- | -------- | ----------------------------------- |
|
||||
| 1 | 計畫代號 | 計畫代號 | 文字 | |
|
||||
| 2 | 計畫名稱 | 計畫名稱 | 文字 | |
|
||||
| 3 | 活動日期(起) | 活動日期_1 | 日期 | |
|
||||
| 4 | 活動日期(迄) | 活動日期_2 | 日期 | |
|
||||
| 5 | 身分別 | 身分別 | 下拉 | Education.身分別.SearchSelectList |
|
||||
| 6 | 憑證類別 | 憑證類別 | 下拉 | Education.憑證類別.SearchSelectList |
|
||||
| 7 | 活動類別 | 活動類別 | 文字 | |
|
||||
| 8 | 付款方式 | 付款方式 | 下拉 | Education.付款方式.SearchSelectList |
|
||||
|
||||
- 操作按鈕
|
||||
- 查詢
|
||||
- 列印領據
|
||||
- 製作勾選項目的領據單據
|
||||
- 作廢
|
||||
- 作廢 / 取消作廢勾選項目
|
||||
- 領據登錄
|
||||
- 新增領據,跳至 "領據登錄與修改" 分頁標籤
|
||||
* 下方:搜尋結果列表
|
||||
- 分頁大小選項 10, 20, 30 / 預設 20
|
||||
- 標題一律水平齊中
|
||||
- 顯示欄位
|
||||
| 編號 | 表頭文字 | 資料欄位 | 輸入元件 | 格式化 | 水平對齊 |
|
||||
| ---- | -------------- | -------------- | -------- | --------- | -------- |
|
||||
| 1 | 操作 | | 勾選 | | 中 |
|
||||
| 2 | 計畫代號 | 計畫代號 | | | 中 |
|
||||
| 3 | 活動日期 | 活動日期 | | | 中 |
|
||||
| 4 | 領款人姓名 | 領款人姓名 | | | 中 |
|
||||
| 5 | 身分證字號 | 身分證字號 | | | 中 |
|
||||
| 6 | 憑證類別 | 憑證類別 | | | 中 |
|
||||
| 7 | 活動類別 | 活動類別 | | | 中 |
|
||||
| 8 | 活動名稱事由 | 活動名稱事由 | | | 左 |
|
||||
| 9 | 費用別 | 費用別 | | | 中 |
|
||||
| 10 | 單價 | 單價 | | | 右 |
|
||||
| 11 | 數量 | 數量 | | | 右 |
|
||||
| 12 | 單位 | 單位 | | | 右 |
|
||||
| 13 | 扣繳類別 | 扣繳類別 | | | 中 |
|
||||
| 14 | 勞務費合計金額 | 勞務費合計金額 | | | 右 |
|
||||
| 15 | 應扣繳稅額 | 應扣繳稅額 | | | 右 |
|
||||
| 16 | 服務費 | 服務費 | | | 右 |
|
||||
| 17 | 差旅費合計金額 | 差旅費合計金額 | | | 右 |
|
||||
| 18 | 付款金額 | 付款金額 | | | 右 |
|
||||
| 19 | 製單人員 | 製單人員 | | | 中 |
|
||||
| 20 | 作廢紀錄 | 作廢 | | 1=是 0=否 | 中 |
|
||||
| 21 | 列印次數 | 列印次數 | | | 中 |
|
||||
|
||||
### 領據登錄與修改:
|
||||
|
||||
* 從上到下分三個區塊
|
||||
* 領據
|
||||
|
||||
| 編號 | 顯示名稱 | 資料欄位 | 輸入元件 | 必要 | 唯讀 | 最大長度 | 下拉資料來源 | 自動帶入 / 自動完成 |
|
||||
| ---- | ------------- | ------------ | -------- | ---- | ---- | -------- | ----------------------------------- | ---------------------- |
|
||||
| 1 | 表單編號 | 表單編號 | 文字 | | 是 | | | 自動編號,細節我來處理 |
|
||||
| 2 | 活動日期 | 活動日期 | 日期 | | | | | |
|
||||
| 3 | 身分別 | 身分別 | 下拉 | 是 | | | | |
|
||||
| 4 | 領款人姓名 | 領款人姓名 | 文字 | 是 | | | | |
|
||||
| 5 | 身分證字號 | 身分證字號 | 文字 | | | | | 領款人姓名自動完成帶出 |
|
||||
| 6 | 憑證類別 | 憑證類別 | 下拉 | | | | Education.憑證類別.SearchSelectList | |
|
||||
| 7 | 計畫代號 | 計畫代號 | 文字 | 是 | | | | |
|
||||
| 8 | 計畫名稱 | 計畫名稱 | 文字 | | 是 | | | |
|
||||
| 9 | 活動地點 | 活動地點 | 文字 | | | | | |
|
||||
| 10 | 活動類別 | 活動類別 | 文字 | | | | | |
|
||||
| 11 | 活動名稱/事由 | 活動名稱事由 | 文字 | | | | | |
|
||||
| 12 | 製單人員 | DB_CRUSR | 文字 | | | | | CurrentUserId |
|
||||
| 13 | 付款方式 | 付款方式 | 下拉 | | | | Education.付款方式.SearchSelectList | |
|
||||
|
||||
|
||||
* 勞務費
|
||||
| 編號 | 顯示名稱 | 資料欄位 | 輸入元件 | 必要 | 唯讀 | 最大長度 | 下拉資料來源 | 計算 |
|
||||
| ---- | ---------- | ---------- | -------- | ---- | ---- | -------- | ---------------------------------------- | --------------------------------------------------------------------- |
|
||||
| 1 | 費用別 | 費用別 | 下拉 | 否 | | | Education.勞務費_費用別.SearchSelectList | |
|
||||
| 2 | 單價 | 單價 | 數字 | 否 | | | | |
|
||||
| 3 | 數量 | 數量 | 數字 | 否 | | | | |
|
||||
| 4 | 單位 | 單位 | 文字 | 否 | | | | |
|
||||
| 5 | 扣繳類別 | 扣繳類別 | 下拉 | 否 | | | Education.扣繳類別.SearchSelectList | |
|
||||
| 6 | 合計金額 | 合計金額 | 數字 | 否 | 是 | | | 單價 * 數量 |
|
||||
| 7 | 應扣繳稅額 | 應扣繳稅額 | 數字 | 否 | | | | Services/領據處理.asmx/CalcTax (laborFee=合計金額, category=扣繳類別) |
|
||||
| 8 | 服務費 | 服務費 | 數字 | 否 | | | | |
|
||||
|
||||
* 差旅費
|
||||
| 編號 | 顯示名稱 | 資料欄位 | 輸入元件 | 必要 | 唯讀 | 最大長度 | 資料來源 | 計算 |
|
||||
| ---- | ------------- | ------------ | -------- | ---- | ---- | -------- | ---------------------------------------- | ---------------------------------------------------------- |
|
||||
| 1 | 費用別 | 費用別 | 下拉 | | | | Education.差旅費_費用別.SearchSelectList | |
|
||||
| 2 | 起點 | 起點 | 自動完成 | | | | Services/火車票價.asmx/SelectStation | |
|
||||
| 3 | 訖點 | 訖點 | 自動完成 | | | | Services/火車票價.asmx/SelectStation | |
|
||||
| 4 | 捷運/公車 | 捷運公車 | 數字 | | | | | |
|
||||
| 5 | 火車 | 火車 | 數字 | | | | | Services/火車票價.asmx/SelectFare(起點, 訖點) |
|
||||
| 6 | 計程車 | 計程車 | 數字 | | | | | |
|
||||
| 7 | 高鐵/飛機 | 高鐵飛機 | 數字 | | | | | |
|
||||
| 8 | 自行開車 | 自行開車 | 數字 | | | | | |
|
||||
| 9 | 過路費/停車費 | 過路費停車費 | 數字 | | | | | |
|
||||
| 10 | 住宿費 | 住宿費 | 數字 | | | | | |
|
||||
| 11 | 合計金額 | 合計 | 純顯示 | | 是 | | | 捷運公車+火車+計程車+高鐵飛機+自行開車+過路費停車費+住宿費 |
|
||||
|
||||
### 列印:
|
||||
將勾選的領據編號發送到後端 Print 方法,會如同匯出那樣回傳一個 Excel 檔,儲存起來就可以了
|
||||
### 匯入與匯出:
|
||||
* 待補充
|
||||
Reference in New Issue
Block a user