Skip to content

Commit 5dc01a7

Browse files
1. 加入 axios 套件。
2. 為了在 JS 中能夠區別 protected 變數及方法而使用下底線命名,並在 ESLint 中加入不可隨意使用下底線變數的規則。 3. 將標籤的樣式獨立出來,不與 button 混在一起。 4. 將 dev 與 production 的環境設定分開。 5. 增加 JS 測試。 6. 調整專案程式分類及結構。
1 parent 85f1d75 commit 5dc01a7

35 files changed

+1537
-466
lines changed

Diff for: .env

-4
This file was deleted.

Diff for: .env.development

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
## 圖片存放路徑
2+
VITE_IMG_BASIC_PATH = /src/assets/images/
3+
4+
## API URL
5+
VITE_API_BASE_URL = http://localhost:3000/

Diff for: .env.production

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
## API URL
2+
#VITE_API_BASE_URL = http://localhost:3000/

Diff for: eslint.config.js

+11-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,17 @@ export default [
1515

1616
{
1717
rules: {
18-
semi: "error", // 必須要有分號
18+
// 必須要有分號
19+
semi: "error",
20+
// 不允許使用以底線命名的變數及方法
21+
"no-underscore-dangle": [
22+
"error",
23+
{
24+
allowAfterThis: true, // 允許接在 this 之後
25+
allowAfterSuper: true, // 允許接在 super 之後
26+
allowAfterThisConstructor: true, // 允許接在 this.constructor 之後
27+
},
28+
],
1929
},
2030
},
2131

Diff for: package-lock.json

+471-192
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: package.json

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
"dependencies": {
1515
"@vee-validate/i18n": "^4.15.0",
1616
"@vee-validate/rules": "^4.15.0",
17+
"axios": "^1.8.1",
1718
"bootstrap": "^5.3.3",
1819
"pinia": "^2.3.0",
1920
"swiper": "^11.2.1",

Diff for: src/App.vue

+2-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565

6666
<script setup>
6767
import { RouterLink, RouterView } from "vue-router";
68-
import CollapseMenu from "./components/CollapseMenu.vue";
68+
import CollapseMenu from "./components/global/CollapseMenu.vue";
6969
</script>
7070

7171
<style lang="scss" scoped>
@@ -91,6 +91,7 @@ import CollapseMenu from "./components/CollapseMenu.vue";
9191
background-color: var(--bs-body-bg);
9292
position: absolute;
9393
width: 100%;
94+
z-index: 1;
9495
}
9596
9697
// 搜尋功能

Diff for: src/api/api.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import axios from "axios";
2+
3+
/**
4+
* API 共用設定
5+
*/
6+
export class Api {
7+
static _axios = axios.create({
8+
baseURL: import.meta.env.VITE_API_BASE_URL,
9+
});
10+
}

Diff for: src/api/eventApi.js

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { Api } from "./api";
2+
import { DateUtils } from "@/utils";
3+
4+
/**
5+
* Event 相關資料處理
6+
*/
7+
export class EventApi extends Api {
8+
static #eventUrl = "/events";
9+
10+
// 主分類標籤的 index,預設以第一個標籤為主要分類
11+
static get mainTagIndex() {
12+
return 0;
13+
}
14+
15+
/**
16+
* 取得所有未過期活動,預設以日期由近至遠排序。
17+
* @returns {Promise} 由後端取回的資料。
18+
*/
19+
static async fetchEvents() {
20+
let result;
21+
22+
await this._axios
23+
.get(`${this.#eventUrl}?date_gte=${DateUtils.getTomorrow()}&_sort=date`)
24+
.then((res) => {
25+
result = res.data;
26+
})
27+
.catch((error) => {
28+
console.error(error);
29+
});
30+
31+
return result;
32+
}
33+
34+
/**
35+
* 取得 banner 活動,預設以日期由近至遠排序。
36+
* @returns {Promise} 由後端取回的資料。
37+
*/
38+
static async fetchBanners() {
39+
let result;
40+
41+
await this._axios
42+
.get(`${this.#eventUrl}?isBanner=true&_sort=date`)
43+
.then((res) => {
44+
result = res.data;
45+
})
46+
.catch((error) => {
47+
console.error(error);
48+
});
49+
50+
return result;
51+
}
52+
53+
/**
54+
* 取得主分類標籤 ID。
55+
* @param {Object} event 活動資料。
56+
* @returns {number} 主分類標籤的 ID。
57+
*/
58+
static getMainTagId(event) {
59+
return event?.tags[this.mainTagIndex];
60+
}
61+
62+
/**
63+
* 取得主分類之外的其它分類標籤 ID。
64+
* @param {Object} event 活動資料。
65+
* @returns {Array} 其它分類標籤的 ID。
66+
* @throws 沒有 tags 資料時拋出錯誤。
67+
*/
68+
static getOtherTagId(event) {
69+
const tags = event?.tags;
70+
if (!tags) {
71+
throw Error("必須要有 tags 資料!");
72+
}
73+
return tags.slice(this.mainTagIndex + 1);
74+
}
75+
}

Diff for: src/api/index.js

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { Api } from "./api";
2+
import { EventApi } from "./eventApi";
3+
import { TagApi } from "./tagApi";
4+
5+
export { Api, EventApi, TagApi };

Diff for: src/api/tagApi.js

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { Api } from "./api";
2+
3+
/**
4+
* Tag 相關資料處理
5+
*/
6+
export class TagApi extends Api {
7+
static #tagUrl = "/tags";
8+
9+
/**
10+
* 取得所有 tag 資料。
11+
* @returns {Promise} 由後端取回的資料。
12+
*/
13+
static async fetchTags() {
14+
let result;
15+
16+
await this._axios
17+
.get(`${this.#tagUrl}`)
18+
.then((res) => {
19+
result = res.data;
20+
})
21+
.catch((error) => {
22+
console.error(error);
23+
});
24+
25+
return result;
26+
}
27+
28+
/**
29+
* 整理成以 tag ID 為鍵項的鍵值對應資料。
30+
* @param {Array} tags 資料。
31+
* @returns {Object} 以 tag ID 為鍵項的鍵值資料集合 {id: name}。
32+
*/
33+
static getIdMap(tags) {
34+
const idMap = tags.reduce((map, item) => {
35+
map[item.id] = item.name;
36+
return map;
37+
}, {});
38+
39+
return idMap;
40+
}
41+
42+
/**
43+
* 以名稱搜尋資料,會先使用完全比對,若查無資料再使用模糊比對。
44+
* @param {string} str 要比對名稱的字串。
45+
* @returns {Object} 第一個找到的 tag 資料。
46+
*/
47+
static searchByName(tags, str) {
48+
// 完全比對
49+
let result = tags.find((item) => {
50+
return item.name === str;
51+
});
52+
53+
// 若查無資料
54+
if (!result) {
55+
// 模糊比對
56+
result = tags.find((item) => {
57+
return item.name.includes(str);
58+
});
59+
}
60+
61+
return result;
62+
}
63+
}

Diff for: src/assets/js/index.js

-4
This file was deleted.

Diff for: src/assets/js/sysConstants.js

-66
This file was deleted.

Diff for: src/assets/scss/all.scss

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
// Components
77
@use "./components/button";
8+
@use "./components/tag";
89
@use "./components/title";
910
@use "./components/form";
1011
@use "./components/navbar";

Diff for: src/assets/scss/base/_variables-utilities.scss

+29-5
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22

33
// TODO 整理
44
$utilities: (
5-
// 覆寫 font-sizeRWDvalues
5+
// 覆寫 font-size (RWD, values)
66
"font-size": (
77
responsive: true,
88
property: font-size,
99
class: fs,
1010
values: variables.$font-sizes,
1111
),
12-
// 覆寫 border-widthRWD
12+
// 覆寫 border-width (RWD)
1313
"border-width": (
1414
responsive: true,
1515
property: border-width,
@@ -22,22 +22,46 @@ $utilities: (
2222
5: 5px,
2323
),
2424
),
25-
// 覆寫 line-heightvalues
25+
// 覆寫 line-height (values)
2626
"line-height": (
2727
responsive: true,
28-
property: line-height,
2928
class: lh,
29+
property: line-height,
3030
values: (
3131
1: 1,
3232
1d155: 1.155,
3333
1d25: 1.25,
3434
1d333: 1.333,
3535
1d437: 1.437,
36+
1d438: 1.438,
37+
1d444: 1.444,
3638
1d448: 1.448,
39+
1d45: 1.45,
3740
1d5: 1.5,
3841
),
3942
),
40-
// 覆寫 height(RWD、values)
43+
// 覆寫 text-align (values)
44+
"text-align": (
45+
responsive: true,
46+
class: text,
47+
property: text-align,
48+
values: (
49+
start: left,
50+
end: right,
51+
center: center,
52+
justify: justify,
53+
),
54+
),
55+
"white-space": (
56+
property: white-space,
57+
values: (
58+
nowrap: nowrap,
59+
pre: pre,
60+
pre-wrap: pre-wrap,
61+
pre-line: pre-line,
62+
),
63+
),
64+
// 覆寫 height (RWD, values)
4165
// "height": (
4266
// responsive: true,
4367
// property: height,

Diff for: src/assets/scss/components/_button.scss

-24
Original file line numberDiff line numberDiff line change
@@ -24,27 +24,3 @@
2424
opacity: 1;
2525
}
2626
}
27-
28-
// 標籤按鈕
29-
.btn-tag {
30-
color: var(--bs-primary);
31-
font-size: 14px;
32-
font-weight: 700;
33-
line-height: 1;
34-
height: 28px;
35-
border-width: 1px 1px 1px 4px;
36-
background-color: transparent;
37-
padding: 0 15px 0 12px;
38-
39-
&:hover {
40-
border-left-color: var(--bs-secondary);
41-
background-color: black;
42-
color: white;
43-
}
44-
45-
@include rwd.pad-up {
46-
font-size: 16px;
47-
height: 31px;
48-
padding: 0 23px 0 20px;
49-
}
50-
}

0 commit comments

Comments
 (0)