---
# System prepended metadata

title: 投注記錄 UI 需求及到職滿月的觀察與心得

---

# 投注記錄 UI 需求及到職滿月的觀察與心得

[toc]

## 投注記錄提供了什麼功能
1. 一般查詢條件與進階查詢條件。
![一般查詢](https://i.imgur.com/dT1bAa4.png)
![進階查詢條件](https://i.imgur.com/iYViCo0.png)
3. 點選 `重設`，會清空一般查詢條件與進階查詢條件。
4. 分頁顯示資料。點選分頁可切換頁面資料查詢。
5. 可選顯示筆數。點選筆數，分頁與選擇資料筆數會立即切換。
6. `匯出 Excel` 會依查詢條件將資料轉入至 Excel 後，回應給使用者
![查詢畫面](https://i.imgur.com/hCrEvAJ.png)
8. 切換至進階查詢時，會將一般查詢的查詢條件帶至進階查詢。
9. 進階查詢實作動態載入，一開始會先下戴 100 筆，當畫面往下來時，會再載入接下來的 100 筆資料，直到沒有更多的資料載入為止。
10. `進階查詢匯出 Excel`功能，匯出的資料欄位與`一般查詢的匯出 Excel` 不同

## 需求內容
1. 投注紀錄的查詢條件下拉選單"會員"、"所屬代理"，增加"完全"及"部分"搜索功能。(參照會員查詢的"完全/包含"按鈕之邏輯，依照投注時間先後進行展示)→ **調整到第二階段處理**
  
2. 調整總筆數及各欄位總計位置到查詢結果列表上方，參考附圖位置。
 ![](https://i.imgur.com/5cinzW7.png)
3. 投注紀錄的`序號`、`帳號`、`遊戲類型`、`遊戲名稱`、`投注時間`、`派彩時間`、`投注額`、`派彩`等欄位需增加欄位排序功能。需要增加排序的欄位標示在附圖。

4. 投注紀錄-進階顯示的`序號`、`帳號`、`遊戲種類`、`提供者`、`遊戲名稱`、`投注時間`、`派彩時間`、`投注額`、`派彩`等欄位需增加欄位排序功能。需要增加排序的欄位標示在附圖。
![](https://i.imgur.com/xGI3oJt.png)
5. 排序操作規則：
    - 重複點擊按鈕進行 升冪 / 降冪 排序的切換，點一次預設升冪 "上箭頭"，再點一次為降冪 "下箭頭"，且箭頭顯示也須變換為"上箭頭" 或 "下箭頭"。
    - 通過切換欄位的方式，一次僅能針對一個欄位操作排序。
    - 各欄位排序方式補充：
        - a) 金額類型欄位：依照金額大小進行排序
        - b) 時間類型欄位：無資料自動排到最後，其他依照自然時間進行排序
        - c) 帳號、序號欄位：依照字母或數字大小排序
- ※ 點擊重設可重置該頁面的篩選器及排序
- ※ 匯出EXCEL需要按照最後排序結果進行展示

## Class Diagram

![](https://i.imgur.com/lk1xRtq.png)

## 遇到什麼樣的困難？
### 關於後端
- 使用帳號排序，但 BetRecord 資料表內沒有 Account 欄位
- 需求要求帳號、代理能夠使用"完整、部份"搜尋，這些在 BetRecord 裡都沒有提供。原本的做法是先取得 BetRecord，再從 BetRecord.MemberId 去查 Account 後合併資料。
    ![](https://i.imgur.com/Nrd3lyK.png)
    - 用 BetRecord Join 相關的資料表可以達到。
    - 先找出符合條件的帳號、代理相關的資料，再當作 BetRecord 的查詢條件。
    :::info
    :information_source: 修改幅度巨大。
    :::
    
- 使用 `帳號` 欄位排序。
    - 原程式是先將 BetRecord 資料撈出來後，再去查詢對應的 帳號、代理帳號，但這樣根本無法排序。
    :::info
    :information_source: 資料取得來源方式不同，因此要重複寫類似的程式碼。
    :::
    

- 使用`遊戲種類`欄位排序，需求要求用遊戲種類的`文字`進行排序，但 BetRecord 資料表內只有代碼。文字是透過程式事後 Mapping 出來的。
    - 與 PM 討論後決定修改需求，提供排序後的列表。
    - UI 排序又與後端程式碼不同。
    :::info
    :information_source: 因為技術債而額外新增的需求。
    :::
    
- 查詢時實際資料筆數與總筆數會因為查詢條件而產生不一致的現象
    ![](https://i.imgur.com/ZZUVeym.png)
    - 該不該將取得資料的方法統一使用 EF 來完成？該不該將 Function 簡化？
    - 一般查詢功能使用 Function(三個) 組合 T-SQL Statement
    - 分頁頁數使用另一組 Function(七個) 組合 T-SQL Statement
    - 進階查詢與 Excel 匯出使用 EF 來進行查詢
    :::info
    :information_source: 因為技術債而要重複寫類似的程式碼。
    :::

- 排序規則前後端不一致。
    - 一般查詢時，拆開成已派彩與未派彩的資料，撈出來之後資料會進行合併，導致撈資料時要排序一次，資料合併後又要再排序一次。
    - 進階查詢排序使用 AngularJs 進行排序，Excel 匯出是後端排序規則。
    - 一般查詢、進階查詢、匯出 Excel、匯出 Excel 功能在切換時排序要一致。
    :::info
    :information_source: 因為技術債而要重複寫類似的程式碼。
    :::


### 關於前端
- TypeScript 與 AngularJs 不熟，花了幾天的時間去查相關文件，一開始查錯方向，Angular 與 AngularJs 是不同的。
- 前端查詢參數眾多，挺繁雜的。
- 命名習慣不同，習慣 Pascal Case，在 TypeScript 是用 Camel Case。
    - Pascal Case: 每個字的第一個字母大寫。例如：UserName
    - Camel Case: 首字的第一個字母小寫，其餘每字首字字母大寫。例如：userName
    - Web API 回傳 Json 使用 Pascal Case, 與 Typescript 慣例不同
- 弱型別轉換常踩到坑
    - 盡可能在 TypeScript 上使用強型別，少使用 null、nullable。
    - 需要前端的單元測試。

## 做了什麼改變？
- 加入後端單元(整合)測試
![](https://i.imgur.com/nDGtMsa.png)
- 稍微重構了部份 C# Code、刪除掉不使用的程式，簡化部份程式。
- 在 TypeScript 盡量去宣告型別，少用 Any、object 的型別
- Method 盡量宣告回傳型別，讓 IDE 幫你找到潛在的轉型錯誤。
    ```typescript=
        //❌ Bad
        doSomething() {
            //...some code...
        }

        //✔️ Good
        doSomething(): void {
            //...some code...
        }

        //✔️ Good
        doSomethingAndReturnString(): string {
            //...some code...
            return "string result";
            //缺少 return 時, IDE 會提示錯誤
        }
    ```
## 如果再重新來一次我會做什麼改變
- 再更謹慎的進行評估
  - 沒有測試、文件、僅能對【祖產】進行考古
- 使用絞殺者模式(Strangler Pattern)
  ![](https://i.imgur.com/0PUTJ61.png)
  - 逐步更換後端程式
- 使用 Feature Toggle (Feature Flag) 更換前端 UI
  ![](https://i.imgur.com/AdX29NL.png)
  - 持續進行整合
  - 減少退版或 Hotfix 的需求

## 未來可以持續改善的方向
- 訂定 Code Style and Guidline
    - 有初版定義
    - 統一命名規則
        - 建立團隊 Coding Style、Naming Rule，讓大家可以有一個規範知道該怎麼寫 Code、Format
        - 建立共通語言(Ubiquitous Language)或資料辭典(Data Dictionary)，專有名詞的用字固定，在程式碼裡就使用這些字來表達意圖。例如：
            - 是 `Payoff` 還是 `PayOff`？
            - 是 `RawDataType` 還是 `GameCategory`？
            - `GameCategory` 代表的是遊戲種類？還是娛樂商？
    - [Clean Code：童子軍規則 | iThome](https://www.ithome.com.tw/voice/150680)
        - 離開營地前，讓營地比使用前更加乾淨
        - 完成功能前，讓程式比我修改前更乾淨

- 程式版本升級
    - .NET Framework 4.5.2, 4.6, and 4.6.1 retired on April 26, 2022.
        - [Microsoft .NET Framework - Microsoft Lifecycle | Microsoft Learn](https://learn.microsoft.com/en-us/lifecycle/products/microsoft-net-framework)
    - 第三方套件漸漸不直接支援 .NET Framework，支援 .NET Standard 與 .NET Core
      ![](https://i.imgur.com/GB56fGa.png)
        - [.NET Standard | Microsoft Learn](https://learn.microsoft.com/zh-tw/dotnet/standard/net-standard?tabs=net-standard-2-0)
    - 考慮 .NET Framework 升級至 4.8.1

- 管理技術債
    - 量化與視覺化債務
        - 量化重複程式碼數量
        - 量化程式複雜度
        - 量化測試覆蓋率
        ![](https://i.imgur.com/9dXJCUN.png)

    - 證明重構的可行性
        - 訂定重構計劃
        - 量化重構前後的設計品質

    - 建立回饋機制
        - 搭配 CI 做自動化測試
        - 搭配 CI 做程式碼品質度量

- DB 資料儲存的規劃
    - OLTP(Online Transactional Processing) vs OLAP(Online Analytical Processing)
    - OLTP 
        - OLTP 針對處理大量事務進行優化
        - 追求新增、更新的成本低 -> 正規化
        - 確保資料完整性、快速處理
        - 取得完整資料得透過 Join 處理
    - OLAP 進行大量資料的分析 -> 反正規化

- 軟體架構的制定
    - 架構的目的是為了最大化生產力與最小化開發成本
      ![](https://i.imgur.com/CuXnUaL.jpg)
      [Twitter 上的 Bytebytego："How to scale a website to support millions of users?](https://twitter.com/bytebytego/status/1593509490808172544/photo/1)
    - 軟體架構的切分與定義
      ![](https://i.imgur.com/FZhBmoe.png)


## 4L (Liked – Learned – Lacked – Longed For)
### Liked
- 開發流程較為單純
- 團隊給予很多協助
- Code Review 機制

### Learned
- 看到了一些滿特殊的程式寫法
- 少用 null
    ```javascript=
        this.temp = null;
        let aa = 10;
        this.temp = this.temp + aa;
        console.log(this.temp);
        //印出來的內容是？
    ```
- 正在學 TypeScript、AngularJs
- 正在看的幾本書
    - [大規模重構｜奪回源碼庫的控制權 (Refactoring at Scale: Regaining Control of Your Codebase)](https://www.tenlong.com.tw/products/9789865027780?list_name=srh)
    - [設計重構：25個管理技術債的技巧消除軟體設計臭味 (Refactoring for Software Design Smells: Managing Technical Debt)](https://www.tenlong.com.tw/products/9789864345229?list_name=srh)
    - [資料密集型應用系統設計 (Designing Data-Intensive Applications: The Big Ideas Behind Reliable, Scalable, and Maintainable Systems)](https://www.tenlong.com.tw/products/9789865028350?list_name=srh)

### Lacked
- 只有接觸 Master，對於其他系統還不熟悉。
- 整體系統架構只有概括性的認識，仍不夠深入。
- 前端技術的測試實踐

### Longed For
- 準備 Feature Toggle、Dependency Injection(DI) 實作分享
- 準備 [團隊協作] 分享
    - 釐清需求
    - 進行分析、設計
    - 開發流程
        - Pair Programming
        - ATDD/BDD、SBE(Specification By Example)
        - TDD
        - Trunk-Base Development
        - Feature Toggle
        - Dependency Injection
    - 驗證、部署(CI/CD)

## Feedback
- 有什麼是覺得我做得好的？
- 有什麼是可以做得更好的？
