# SKB
## 參考連結
- 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

3. 設定environment management
## 測試
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畫面和此版相同)

新光測試IP:http 10.20.241.176:8082
後端:地球 右鍵 發布 開啟資料夾 停止啟動 刪除前檔案(除資料夾 & web) 貼上檔案(覆蓋原先檔案) 啟動
86800136
## 系統操作手冊
**文件截圖**
- 3.7.1 外部常用系統 (Ok)
- 3.10.1 企業資訊及績效查詢(OK)
**手機版功能與畫面確認**
1. 首頁-個人提醒事項清單

2. 首頁常用系統

3. 首頁-手機版

## API
Swagger: https://skbrmportaltest.azurewebsites.net/swagger/index.html#/CpParameter/CpParameter_GetParams
1. 打login api後,取得access token

2. 將token加入authorize

3. 再選擇要打的api

## 參數管理
### 參數查詢頁面
**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顯示自己的帳號呢?

## 開發問題
1. 新增與編輯是否改為pop out視窗,而非跳轉頁面?因其他功能皆為pop out視窗,除首頁設定功能(需填寫資料較多)
2. 確定下拉選單的api
- 取得單一參數(get):
- 取得ParmID列表(get):
- 取得itemID(get):

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;
}
}
```