---
# System prepended metadata

title: 前端文件

---

前端文件
===

## 規則參考
### 資料夾結構(D)＆檔案(F)說明
* views(D)
    * 主畫面依照route規則命名資料夾，index.vue
* components(D)
    * 依照畫面功能命名資料夾
    * 先以垂直擴充為主，如有重複功能元件再以水平擴充
* lang(D)
    * i18n配著元件進行
* router(D)
    * 路由設定，url轉導、驗證定義
* style(D)
    * 共用style 以scss開發為主
* utils(D)
    * 可共用的 js function
* .editorconfig(F)
    * 開發編輯規則 (IDE需下載擴充執行) 目前規則: 縮排統一兩格

* 開發coding style規則參照airbnbのeslint

* *.vue
    * 以pug語法開發為主


## 開發端相關

### Vuex
* 只允許在View內使用Vuex

### Router
* 連結請使用<router-link></router-link>
```xml=
<template>
  <div>
    <router-link :to="{ name: 'router-name' }"></router-link>
  </div>
</template>
```
* router請記得取name
```javascript=
[
  {
    path: '/test/test',
    name: 'this-is-test-page', // 記得取名
    component: () => import('@/views/test/test/index.vue'),
    hidden: true,
  },
]
```

### Loading 使用方法

```javascript=
/**
 * Loading example
 */
import WuwowLoadingMixin from '@/components/wuwowLoading/mixin/index.vue';

export default {

  mixins: [WuwowLoadingMixin],

  data() {
    return {};
  },
  async created() {
    // 取得標籤，啟動loading
    const tag = this.startLoading();
    await new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('done 1');
      }, 10 * 1000);
    });
    // 關閉當前標籤程序，並關閉loading
    this.endLoading(tag);
  },
  async mounted() {
    // 取得標籤，啟動loading
    const tag = this.startLoading();
    await new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('done 1');
      }, 5 * 1000);
    })
    // 關閉當前標籤程序，並關閉loading
    this.endLoading(tag);
  }
  methods: {
  },
};
```

### 命名規則

#### Camel Case
* Java script
```javascript=
// thisIsATest資料夾
import '~/thisIsATest/index.vue';

// Upper camel case
class ThisIsATest {
    
}

// Lower camel case
let thisIsATest = 'this is a test.';
```
#### Snake Case
* Java script
```javascript=
let i18n = {
    message: {
        tw: {
            // 內部的key
            this_is_a_test: 'this is a test',
        },
    },
};
```

* JSON
```json=
{
    "message": {
        "tw": {
            "this_is_a_test": "this is a test"
        }
    }
}
```
#### Kebab Case
* pug
```pug=
this-is-a-test-component
  inner-component
```

#### Const Case
* Java script
```javascript=
const THIS_IS_A_TEST = 'this is a test';
```
#### 相關範例
* Java script
```javascript=
// 開發coding style依照airbnb的eslint為主


// 請務必將每一行的分號寫出來
// 變數宣告都以CamelStyle做宣告
// 後端傳來的變數需要透過camelcase-keys套件切換過
// 要傳給後端的參數需透過
// 常數都以ConstStyle做宣告

import '~/thisIsATest/index.vue';

// 全域變數請用const以及全大寫以及下底線隔開來做命名
const GOOGLE_URL = 'https://google.com';
console.log(`The google url is: ${GOOGLE_URL}`);

// 參考用的變數請用const宣告
const iAmEating = 'I am eating ';

const apple = 'apple';
const banana = 'banana';

// 區域變數請都以小駝峰宣告，並且禁止使用var做宣告
let iAmEatintSomething = `${iAmEating}${apple}`;
console.log(iAmEatSomething);

// 請勿使用+來做字串相加，請使用``來做字串相加
iAmEatingSomething = `${iAmEating}${banana}`;
console.log(iAnEatSomething);


// 註解請參考 > https://jsdoc.app/
// @return > https://jsdoc.app/tags-returns.html
// @param > https://jsdoc.app/tags-param.html

/**
 * 檢查是否成年
 * 
 * @param {number} age 年紀
 * 
 * @returns {boolean} 是否成年
 */
function adultOrNot(age = 0) {
    if (age > 18) {
        return true;
    }
    
    return false;
}

adultOrNot(10);

// 陣列或者物件的最後一個元素後請加上逗號
// 一行即可宣告完畢的就可審略最後一個元素的逗號
const data = [
    1, 
    2, 
    3, 
    4,
];

// “建議”都使用箭頭函式，如有需要再使用function
const isOdd = (num) => {
    return num % 2 === 0;
};

const isEven = (num) => {
    return num % 2 !== 0;
}

const odd = data.filter(isOdd);
const even = data.filter(isEven);

```

### DNS
|用途|開發端|測試機(工程師)|測試機(公司)|正式機|
|-|-|-|-|-|
|太極內|portal-dev.lst-taichi.wuwow.tw|it-lst-taichi.wuwow.tw||lst.wuwow.tw|
|太極外(VUE)|portal-dev.lst-taichi-external-vue.wuwow.tw|it-lst-taichi-external-vue.wuwow.tw|company-lst-taichi.wuwow.tw|~~taichi.wuwow.tw~~ (暫時未上線)|
|太極外|portal-dev.lst-taichi-external.wuwow.tw|it-lst-taichi-external.wuwow.tw||taichi.wuwow.tw|
|API|portal-dev.taichi-api.wuwow.tw|it-taichi-api.wuwow.tw||api.wuwow.tw|
|官網|portal-dev.wuwow-portal.wuwow.tw|it-wuwow-portal.wuwow.tw||www.wuwow.tw|
|未知領域求大大填寫|portal-dev.media-source.wuwow.tw|it-media-source.wuwow.tw||未知領域求大大填寫|
|Wuwow Junior||it-wuwow-junior-vue.wuwow.tw|

### 開發文件

* [太極外部權限](https://docs.google.com/spreadsheets/d/1-_GnluwuHm47zXdrt-WOX9sYyIzz68_fNPhxxMYB0mw/edit#gid=33769320)

### Http status code

|狀態|原因||
|-|-|-|
|500|後端try catch|Internal Server Error|
|200|請求成功|OK|
|202|此請求已經被接受但尚未處理|Accepted|
|400|參數錯誤|Bad Request|
|401|Token失效|Unauthorized|
|403|不符權限|Forbidden|



### Docker

* 開啟Docker
```shell=
cd {自已的路徑}/211023_lioshutan/
docker-compose up -d php-worker laravel-echo-server nginx mysql phpmyadmin redis workspace php-fpm5.6 php-fpm7.0 php-fpm7.3 php-fpm8.0 php-fpm7.2
```

* 關閉Docker
```shell=
docker-compose down
```

* 進入Docker
```shell=
docker-compose exec workspace bash
```

* 拉專案

```shell=
# 太極外部
lst-taichi-external.sh

# 太極外部(VUE)
lst-taichi-external-vue.sh

# 太極內部
lst-taichi.sh

# API專案
taichi-api.sh

# 官網
wuwow-portal.sh

# 未知領域求大大填寫
media-source.sh
```


## 設定@lioshutan/api

* Step.1

複製以下程式碼貼上終端機上，windows請使用[git bash](https://gitforwindows.org/)操作

```bash=
cat <<EOF >>~/.ssh/config
Host lioshutan
  HostName gitlab.com
  User "git"
  IdentityFile "~/.ssh/lioshutan"
EOF

ssh-keygen -f lioshutan

```

* Step.2

複製以下程式碼貼上終端機上，windows請使用[git bash](https://gitforwindows.org/)操作

```bash=
cat ~/.ssh/lioshutan.pub
```

將輸出的結果設定至gitlab的ssh key

* Step.3

```bash=
npm i
```

### 版本號規範

詳細可以參考[版本號規範](https://semver.org/lang/zh-TW/)

```
版本格式：主版號.次版號.修訂號，版號遞增規則如下：

1. 主版號：當你做了不相容的 API 修改，
2. 次版號：當你做了向下相容的功能性新增，
3. 修訂號：當你做了向下相容的問題修正。
先行版號及版本編譯資訊可以加到「主版號.次版號.修訂號」的後面，作為延伸。
```

## 其他


### 相關markdown套件用法
* Test Graphviz

```graphviz
digraph graphname{
    a -> b;
    b -> c;
    a -> c;
}
```

```graphviz
digraph hierarchy {

		nodesep=1.0 // increases the separation between nodes
		
		node [color=Red,fontname=Courier,shape=box] //All nodes will this shape and colour
		edge [color=Blue, style=dashed] //All the lines look like this

		Headteacher->{Deputy1 Deputy2 BusinessManager}
		Deputy1->{Teacher1 Teacher2}
		BusinessManager->ITManager
		{rank=same;ITManager Teacher1 Teacher2}  // Put them on the same level
}
```

* Test UML
```sequence
Andrew->China: Says Hello
Note right of China: China thinks\nabout it
China-->Andrew: How are you?
Andrew->>China: I am good thanks!
```

* Test Flow
```flow
st=>start: Start:>http://www.google.com[blank]
e=>end:>http://www.google.com
op1=>operation: My Operation
sub1=>subroutine: My Subroutine
cond=>condition: Yes
or No?:>http://www.google.com
io=>inputoutput: catch something...
para=>parallel: parallel tasks

st->op1->cond
cond(yes)->io->e
cond(no)->para
para(path1, bottom)->sub1(right)->op1
para(path2, top)->op1
```


* 產生PEM
```shell=
openssl rsa -in ~/.ssh/id_rsa -out tmp_file.pem
```

* 連線
```shell=
# (正式)太極內部
ssh -i your.pem ubuntu@lst.wuwow.tw

# (正式)太極外部
ssh -i your.pem ubuntu@taichi.wuwow.tw

# (正式)太極官網
ssh -i your.pem ubuntu@www.wuwow.tw

# (正式)太極API
ssh -i your.pem ubuntu@api.wuwow.tw

# (測試)太極內部
ssh -i your.pem ubuntu@it-lst-taichi.wuwow.tw

# (測試)太極外部
ssh -i your.pem ubuntu@it-lst-taichi-external.wuwow.tw

# (正式)太極官網
ssh -i your.pem ubuntu@it-wuwow-portal.wuwow.tw

# (測試)太極API
ssh -i your.pem ubuntu@it-taichi-api.wuwow.tw

```

