---
# System prepended metadata

title: "\U0001F4CC[R]2020/02/11前端會議"
tags: [會議紀錄]

---

###### tags: `會議紀錄`
###### Thunder: `權限設定`
###### CodeReview: `OneSignal(訊息推播)` `GoogleMap(地圖)` `this.injector.get()`
###### Announcement: `SD需求 #GA碼` `SD需求 #權限需求`
###### Attendee: 政儀、永佳、偉恩、弘翊、政儒
# 📌[R]2020/02/11前端會議
## 踩雷事件
### ⚡權限設定
:::info
說明: 
* 新增CRM模組，權限判斷需要大改。
* 舊的AuthGuard(auth-guard.service.ts)決定不維護。
=>已經修改太多次裡面東西太多了
* 新增一支新的CrmGaurd(crm-auth.guard.ts)來做新的權限判斷。
=>舊的還是留著
:::

A1的權限判斷是寫在xxx-routing.module.ts裡面，透過canActicate執行AuthGuard這支程式來判斷權限。例:
```typescript
const routes: Routes = [
  { path: 'auth_pos', component: AuthPosComponent, canActivate: [AuthGuard], data: { jobID: JOBID.GENERAL }}
];
```

新增CRMAuthGuard後，也將他加在canActivate裡，
```typescript
const routes: Routes = [
    { path: 'auth_pos', component: AuthPosComponent, canActivate: [AuthGuard, CRMAuthGuard], data: { jobID: JOBID.GENERAL }},
    { ... canActivate: [AuthGuard, CRMAuthGuard] ...}
];
```
但因為canActivate的陣列，型別要屬於下列三種之一
 * Observable<boolean | UrlTree>
 * Promise<boolean | UrlTree>
 * boolean | UrlTree;

AuthGuard是屬於Promise，CrmGaurd目前可能會回傳Observable/boolean，因此就會有非同步問題。

#### #1 canActivate兩支為非同步
如果兩個同時向後端發出相同請求，後面發出請求的會被取消發生錯誤。

==💡解決方法: 將共同呼叫API寫在一支service內一起管理(有一方先拿到值就將它存進變數裡，後面的就直接拿變數內的值)。==

#### #2 取得不同份service資料(#1延伸問題)
在不同的**.module.ts providers掛上service，導致service實體化兩次(會優先取上一層的service)，兩支canActivate內的資料不一致。

==💡解決方法:將共用的service掛在最外層。==

## 寫法交流
### ⛏OneSignal(訊息推播)
[永佳onesignal筆記](https://www.notion.so/onesignal-bff1478608c5461db012a6c45f4d671e)
#### #1 OneSignal設定
可以參考下面兩個網址設定
[OneSignal官網](https://onesignal.com/)
[OneSignal文件](https://documentation.onesignal.com/docs)

程式
```typescript
platform.ready().then(() => {
      statusBar.styleDefault();
      splashScreen.hide();
      const notificationOpenedCallback = function (jsonData) {
        console.log('notificationOpenedCallback: ' + JSON.stringify(jsonData));
      };
      window["plugins"].OneSignal
        .startInit("584f8cff-218c-4942-986e-2e6c647faa93", "614728355810")
        .handleNotificationOpened(notificationOpenedCallback)
        .inFocusDisplaying(window["plugins"].OneSignal.OSInFocusDisplayOption.Notification)
        .endInit()
});
```

#### #2 window["plugins"].OneSignal
[1]
```typescript
window["plugins"].OneSignal
        .startInit("584f8cff-218c-4942-986e-2e6c647faa93", "614728355810")
        .handleNotificationOpened(notificationOpenedCallback)
        .inFocusDisplaying(window["plugins"].OneSignal.OSInFocusDisplayOption.Notification)
        .endInit()
```
[2]
```typescript
window["plugins"].OneSignal.startInit("584f8cff-218c-4942-986e-2e6c647faa93", "614728355810")
window["plugins"].OneSignal.handleNotificationOpened(notificationOpenedCallback)
window["plugins"].OneSignal.inFocusDisplaying(window["plugins"].OneSignal.OSInFocusDisplayOption.Notification)
window["plugins"].OneSignal.endInit();
```
這兩個寫法是一樣的意思，.startInit/.handleNotificationOpened/.inFocusDisplaying/.endInit都是指向`window["plugins"].OneSignal`。

#### #3 sendTags()特別寫法
但是sendTags()不可以使用(#2)第一種寫法要用第二種寫法，若使用第一種的需要抽開寫。
```typescript
window["plugins"].OneSignal
        .startInit("584f8cff-218c-4942-986e-2e6c647faa93", "614728355810")
        .handleNotificationOpened(notificationOpenedCallback)
        .inFocusDisplaying(window["plugins"].OneSignal.OSInFocusDisplayOption.Notification)
        .endInit();
window["plugins"].OneSignal.sendTag("UserID4", "0")
```

#### #4 介面訊息
OneSignal> Audience> AllUsers
可以查看訂閱者的相關訊息(最近使用/第一次使用/用sendTag()傳送的訊息 等... ...)。
![](https://i.imgur.com/Q8uajeL.png)
![](https://i.imgur.com/qytf3OS.png)


### ⛏GoogleMap(地圖)
#### #1 轉址
使用GoogleMap會產生的費用: 經緯轉換地址/地址轉換經緯。
* 行動版: 無任何費用
* 網頁版: 需支付轉址費用(1000次7美金)

行動版使用ionic套件，所以可以免費使用
> 政儀寫在PositionProcessProvider(position-process.ts)裡，可以參考看看。
```typescript
import { NativeGeocoder } from '@ionic-native/native-geocoder';
```
```typescript
/**經緯轉換地址 行動裝置才可正常運做*/
getAddress(position: Position): Observable<string> {
    let subscriber: Subscriber<string>;
    const observable = new Observable((x: Subscriber<string>) => { subscriber = x; });
    console.log('currentLatitude = ', position.lat);
    console.log('currentLongitude = ', position.lng);
    this.nativeGeocoder.reverseGeocode(position.lat, position.lng)
      .then((result: NativeGeocoderReverseResult[]) => {
        // console.log('result 2 = ', JSON.stringify(result[0]));
        console.log('result = ', result);
        // const newResult: NativeGeocoderResultModel = JSON.parse(JSON.stringify(result));
        const newResult = result[0];
        const address = newResult.postalCode + newResult.administrativeArea + newResult.locality + newResult.subLocality + newResult.thoroughfare + newResult.subThoroughfare;
        console.log('address = ', address);
        subscriber.next(address);
        subscriber.complete();
      }, (error) => {
        console.log(error);
        const x = new CheckError('轉換地址失敗');
        subscriber.error(x);
      });
    return observable;
}

/**地址經緯轉換 行動裝置才可正常運做*/
forwardGeocode(address: string) {
    let subscriber: Subscriber<Position>;
    const observable = new Observable((x: Subscriber<Position>) => { subscriber = x; });
    this.nativeGeocoder.forwardGeocode(address)
      .then((result: NativeGeocoderForwardResult[]) => {
        console.log('result = ', result);
        const newResult = result[0];
        subscriber.next({ lat: +newResult.latitude, lng: +newResult.longitude });
        subscriber.complete();
      }, (error) => {
        console.log(error);
        const x = new CheckError('轉換地址失敗');
        subscriber.error(x);
      });
    return observable;
 }
```
但網頁版是交給後端轉址，但後端沒有套件可以使用，因此會產生費用。

#### #2  Google Cloud Platform
要使用google map的API，需要去Google Cloud Platform設定才可以使用。


#### #3 網址生成圖片
使用別人提供的網址，後面加上參數就可以改變顏色/數字。
> 政儀寫在ClockOnPage(clock-on.ts) getMarkerIcon，可以參考看看。
```typescript
private getMarkerIcon(character: number) {
    const colors = ['red', 'black', 'blue', 'green', 'grey', 'orange', 'purple', 'white', 'yellow'];
    const colorIndex = Math.floor((Math.random() * colors.length));
    const icon = `https://raw.githubusercontent.com/Concept211/Google-Maps-Markers/master/images/marker_${colors[colorIndex]}${character}.png`;
    return icon;
 }
```

### ⛏this.injector.get()
CommonFn內有些this.injector.get(***)的寫法

```typescript
const userPowerService = this.injector.get(UserPowerService);
```

是為了解決相依迴圈的不好寫法，所以***未來應要避免使用***。

## 事情公告
### 📢SD需求
#### #1 GA碼
埋GA碼的要求:希望可以知道使用者是由哪個入口進入、廣告點擊數=>所以先暫時不管

#### #2 權限需求
目前SD的權限需求太過奇怪，還會重新調整