---
# System prepended metadata

title: ＳＫＢ

---

# ＳＫＢ
## 參考連結
- UI組件：https://www.primefaces.org/primeng/v9-lts/#/
- 開發風格：https://www.ag-grid.com/angular-grid/
- icon(fontAwesome)：https://fontawesome.com/
- icon(PrimeNG): https://www.primefaces.org/primeng/v11/#/icons
## 開發帳號
網站：https://skbrmwebtest.azurewebsites.net/
api url: https://skbrmportaltest.azurewebsites.net
tello: https://trello.com/b/tp7K91JI/%E6%96%B0%E5%85%89%E6%99%BA%E8%83%BD%E5%8A%A9%E7%90%86
帳號：S03379
密碼：隨便key
**Admin帳號**

帳號：M03390
密碼：隨便key
**OnlyQuery帳號**

徐X婷：M26868
M02984

孟軒：M27418
審核：M01967

前端local: startlocal
chatbot TESTING: hello、台幣活存

## Postman設定
1. 更換有效access token
![](https://i.imgur.com/pxvbCBF.jpg)
3. 設定environment management![](https://i.imgur.com/jkHxvIe.jpg)

## 測試
1. Oracle JAVA https://www.java.com/zh_TW/download/windows-64bit.jsp
2. Apache Jmeter https://jmeter.apache.org/download_jmeter.cgi

Jmeter使用解壓縮檔案後，執行 bin 目錄下的 jmeter.bat ，Unix/Mac OS X 請執行 jmeter.sh(不保證舊版或新版JMeter畫面和此版相同)

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

新光測試IP：http  10.20.241.176:8082

後端：地球 右鍵 發布 開啟資料夾 停止啟動 刪除前檔案(除資料夾 & web) 貼上檔案(覆蓋原先檔案) 啟動
86800136


## 系統操作手冊
**文件截圖**
- 3.7.1 外部常用系統 (Ok)
- 3.10.1 企業資訊及績效查詢(OK)


**手機版功能與畫面確認**
1. 首頁-個人提醒事項清單
![](https://i.imgur.com/hOkhAWs.png)
2. 首頁常用系統
![](https://i.imgur.com/CgSivQA.png)
3. 首頁-手機版
![](https://i.imgur.com/T0rMBdZ.png)



## ＡＰＩ
Swagger: https://skbrmportaltest.azurewebsites.net/swagger/index.html#/CpParameter/CpParameter_GetParams

1. 打login api後，取得access token
![](https://i.imgur.com/J1CdM87.jpg)

2. 將token加入authorize
![](https://i.imgur.com/cd7N4Yl.png)

3. 再選擇要打的api
![](https://i.imgur.com/z4MGDOp.png)

## 參數管理
### 參數查詢頁面
**API**
1. 查詢參數(get)
- URL: ${environment.apiUrl}/api/ParameterManage?paramId=DOC_VERIFY&itemId=1&itemInfo=

2. 取得單一參數(get)
- URL:${environment.apiUrl}/api/ParameterManage/Test/1

3. 取得ParmID列表(get)
- URL: ${environment.apiUrl}/api/ParameterManage/ParmID

4. 取得itemID(get)
- URL: ${environment.apiUrl}/api/ParameterManage/ItemID/COLOR

### 參數新增頁面
#### API 
1. 新增參數(post)
- URL: ${environment.apiUrl}/api/ParameterManage
2. 取得單一參數(get)
- URL:${environment.apiUrl}/api/ParameterManage/Test/1
#### 驗證
1. 必填欄位：參數Param、參數ID、參數名稱（formControl)
2.



### 參數編輯
**API** 
1. 更新參數(put)
- URL: ${environment.apiUrl}/api/ParameterManage

### 參數刪除
 **API**
 1. 刪除參數(delete)
- URL: ${environment.apiUrl}/api/ParameterManage/Test/1

## VScode命名
### Interface
system -> Create New Folder
1. 開頭加上「 I 」
2. response: vm.ts
3. request: param.ts 
### Service


## 操作手冊問題
1. 目前無畫面：pg.5 潛在動撥名單、pg.22 法人知識圖譜 ＆ 外部常用系統、pg.23 帳號管理
``新光自行開發``
3. 名詞：pg.14 RM客戶 & 額度與授信屆期
``新光自行開發``
5. 畫面呈現：pg.29 節點 ＆ 浮水印（3.8.2.1)
``節點：沒有畫面，僅有資料夾；浮水印：畫面上有浮水印``
## 其他問題
1. GitKraken上的remote目前只有origin，但Tim的會跑出bitbucket帳號，請問要如何在remote顯示自己的帳號呢？
![](https://i.imgur.com/NayVK1t.jpg)

## 開發問題
1. 新增與編輯是否改為pop out視窗，而非跳轉頁面？因其他功能皆為pop out視窗，除首頁設定功能（需填寫資料較多）
2. 確定下拉選單的api
- 取得單一參數(get)：
- 取得ParmID列表(get)：
- 取得itemID(get)：
![](https://i.imgur.com/PEAYOLq.jpg)
3. ag-grid實現Data Grid 


## 智慧助理拖曳功能

1. html: parm-setting.html
```javascript=
<div [class.d-none]="mode !== switchModeEnum.search" style="box-sizing: border-box" data-Grid class="ag-grid-table" (resizeColumn)="resizeColumn()">
  <ag-grid-angular
  #agGrid
  class="ag-theme-alpine h-100"
  [rowHeight]="48"
  rowSelection="multiple"
  [gridOptions]="gridOptions"
  (gridReady)="onGridReady($event)"
  (paginationChanged)="pageChanged()"
    (sortChanged)="sortChange()"
  >
  </ag-grid-angular>
</div>
```
2. app.main.component.html
```javascript=
 <div class="helper-boundary" [ngClass]="helperDragStart ? 'helper-drag-shade' : ''" >
        <div class="helper-img helper-box" *ngIf="!isMobileDevice" (click)="chatBotShow()" 
        cdkDragBoundary=".helper-boundary" cdkDragLockAxis="y" 
        (cdkDragStarted)="dragStarted()"
        (cdkDragMoved)="dragMoved($event)"
        (cdkDragEnded)="hideBoxShadow()"
        cdkDrag>
          <img src="/assets/layout/images/chatBot-pre.png" alt="" />
        </div>
      </div>
```

3. _ag-grid.css
```javascript=
///放在最上層
.ag-grid-table{
  z-index: 10;
  position: relative;
}
```

4. _helperStyle.css
```javascript=
.helper-boundary{
  width: 400px;
  height: 400px;
  max-width: 100%;
  border: dotted #ccc 2px;
  // pointer-events: none;
  position: fixed;
  right: 0;
  bottom: 0;
  // z-index: 10;
}

.helper-box {
  width: 200px;
  height: 200px;
  border: solid 1px #ccc;
  color: rgba(0, 0, 0, 0.87);
  cursor: move;
}

.helper-img {
  position: absolute;
  z-index: 12;
  bottom: 20px;
  right: 20px;
  cursor: pointer;
  box-shadow: 2px 2px 10px 1px #a0a0a0;
  overflow: hidden;
  width: 60px;
  height: 60px;
  background-color: #d8dee9;
  border-radius: 50%;
  transition: 0.3s transform;
  
  img {
    width: 100%;
  }
  &:hover {
    transform: translateY(-10px);
  }
}

```
5. app.main.component.ts
```javascript=
 dragStarted() {
    if (this.isMobileDevice) {
      return;
    }
    this.helperDragStart = true;
  }

  dragMoved(event){
    event.preventDefault();
  }
 
  /** 關閉拖曳遮罩 */
   hideBoxShadow() {
    if (this.isMobileDevice) {
      return;
    }
    this.helperDragStart = false;
   }
```

手機＆查詢
```javascript=
 ngOnInit() {
    Array.from(this.utilService.menuMap).reduce((accur, current, index) => {
      const [key, value] = current;
      
      if (value.parentId) return accur;
     
      // 查詢
       if (!(value.hasOwnProperty('queryFlag') && value.queryFlag === true) && !this.isMobile) return accur;
      
      //手機
      if(!(value.hasOwnProperty('mobileFlag') && value.mobileFlag === true) && this.isMobile) return accur;
      accur.push({ ...value, funcCode: key, layer: 1 });
      return accur;
    }, this.model);
    console.log(this.model)
    this.addItems(this.model, 2);
    this.model.sort((a, b) => {
      return a.sort - b.sort;
    });
  }
  
  addItems(targetList: MenuModel[], layer: number) {
    targetList.reduce((accur, current, index) => {
      if (current.itemKey && current.itemKey.length !== 0) {
        current.items = [];
        // 根據 itemKey 找出, 對應的單一item塞入items陣列
        current.itemKey.forEach(itemKey => {
          let value = this.utilService.menuMap.get(itemKey);
          
           //查詢
       if (!(value.hasOwnProperty('queryFlag') && value.queryFlag === true) && !this.isMobile) return;
       
       //手機
       if(!(value.hasOwnProperty('mobileFlag') && value.mobileFlag === true) && this.isMobile) return;

          current.items.push({ funcCode: itemKey, ...value, layer: layer });
        });

        // 排序
        current.items.sort((a, b) => {
          return a.sort - b.sort;
        });
        if (layer === 4) return accur; // 限制四層層數
        this.addItems(current.items, layer + 1);
      }

      return accur;
    }, targetList);
  }
```

假資料
```javascript=
ngOnInit() {
    console.log('menuMap',this.utilService.menuMap)
        this.newArray = [["reminder",{addFlag: true,
          deleteFlag: true,
          executeFlag: false,
          exportFlag: false,
          icon: "pi pi-fw pi-bell",
          isNode: false,
          isWatermark: true,
          label: "提醒事項",
          mobileFlag: true,
          queryFlag: true,
          reportFlag: false,
          routerLink: ["/root/reminder"],
          sort: 4,
          updateFlag: true}],
          ["full-calendar",
          {addFlag: true,
          deleteFlag: true,
          executeFlag: false,
          exportFlag: false,
          icon: "far fa-calendar-check",
          isNode: false,
          isWatermark: true,
          label: "行事曆",
          mobileFlag: false,
          queryFlag: true,
          reportFlag: false,
          routerLink: ["/root/calendar"],
          sort: 3,
          updateFlag: true}
          ],["document-management",
    {addFlag: false,
    deleteFlag: false,
    executeFlag: false,
    exportFlag: false,
    icon: "fas fa-tools",
    isNode: true,
    isWatermark: false,
    itemKey: ["doc-file", "doc-audit", "doc-category"],
    label: "文件管理",
    mobileFlag: true,
    queryFlag: false,
    reportFlag: false,
    routerLink: ["/document-management"],
    sort: 16,
    updateFlag: false}]];

    Array.from(this.utilService.menuMap).reduce((accur, current, index) => {
     console.log(current)
    if(index===0){
      for( let i = 0; this.newArray.length > i; i++){
        console.log(this.newArray)
        console.log(this.newArray.length)
       //const [key, value] = this.newArray;
       const key = this.newArray[i][0];
       const value= this.newArray[i][1];
 
       
       if (value.parentId) return accur;
       
       // 查詢
       if (!(value.hasOwnProperty('queryFlag') && value.queryFlag === true) && !this.isMobile) return accur;
      
      //手機
      if(!(value.hasOwnProperty('mobileFlag') && value.mobileFlag === true) && this.isMobile) return accur;
      
       accur.push({ ...value, funcCode: key, layer: 1 });
      
      }
    }
    return accur; 
     
     
      accur.push({ ...value, funcCode: key, layer: 1 });
      return accur;
    }, this.model);
    
    
    this.addItems(this.model, 2);
    this.model.sort((a, b) => {
      return a.sort - b.sort;
    });
  }
```

限定範圍拖曳
```javascript=
@HostListener('window:scroll', ['$event'])
  doSomething(event) {
    if (window.pageYOffset > 0) {
      this.top =
        Math.round(document.querySelector('.layout-content').getBoundingClientRect().height / window.innerHeight) *
        window.pageYOffset;
    } else {
      this.top = 0;
    }
  }
```
