|
@@ -1,300 +1,222 @@
|
|
<script setup>
|
|
<script setup>
|
|
-import { ref, reactive, onMounted, onBeforeUnmount } from "vue";
|
|
|
|
|
|
+import { ref, reactive, watch } from "vue";
|
|
import axios from "axios";
|
|
import axios from "axios";
|
|
|
|
+import moment from "moment";
|
|
import Map from "@/components/Map.vue";
|
|
import Map from "@/components/Map.vue";
|
|
import Navbar from "@/components/Navbar.vue";
|
|
import Navbar from "@/components/Navbar.vue";
|
|
|
|
|
|
-(async function getData() {
|
|
|
|
|
|
+let pageNum = ref(1); // 頁數(預設第一頁)
|
|
|
|
+let pageAmount = ref(4); // 每頁顯示筆數
|
|
|
|
+let totalPages = ref(1); // 總頁數
|
|
|
|
+
|
|
|
|
+// 取得所有課程總筆數
|
|
|
|
+(async () => {
|
|
try {
|
|
try {
|
|
- const response = await axios.get("https://cmm.ai:8088/api/get_school");
|
|
|
|
- console.log("response.data", response.data);
|
|
|
|
|
|
+ const response = await axios.get("https://cmm.ai:8088/api/get_class_name");
|
|
|
|
+ totalPages.value = getTotalPages(response.data.classes.length, 4);
|
|
} catch (error) {
|
|
} catch (error) {
|
|
console.error(error);
|
|
console.error(error);
|
|
}
|
|
}
|
|
})();
|
|
})();
|
|
|
|
|
|
-const scrollLeft = ref(0);
|
|
|
|
-let shouldAnimate = ref(false);
|
|
|
|
-let shouldFadeOut = ref(false);
|
|
|
|
-let scrollCount = 1;
|
|
|
|
|
|
+// 計算頁數
|
|
|
|
+function getTotalPages(totalRecords, recordsPerPage) {
|
|
|
|
+ return Math.ceil(totalRecords / recordsPerPage);
|
|
|
|
+}
|
|
|
|
|
|
-const handleScroll = () => {
|
|
|
|
- const windowWidth = window.innerWidth; // 螢幕寬度
|
|
|
|
- const windowHeight = window.innerHeight;
|
|
|
|
- const documentHeight = document.body.scrollHeight - windowHeight;
|
|
|
|
- const windowScrollable = windowWidth * scrollCount; // 可捲動寬度
|
|
|
|
- const scrollTop = window.pageYOffset;
|
|
|
|
- const steps = windowScrollable / documentHeight;
|
|
|
|
- const goLeft = scrollTop * steps;
|
|
|
|
|
|
+// 切換分頁
|
|
|
|
+watch(pageNum, () => {
|
|
|
|
+ getClass();
|
|
|
|
+});
|
|
|
|
|
|
- // console.log('windowWidth',windowWidth);
|
|
|
|
- // console.log('windowScrollable',windowScrollable);
|
|
|
|
|
|
+let classes = reactive({
|
|
|
|
+ data: [],
|
|
|
|
+});
|
|
|
|
|
|
- if (scrollTop > 0) {
|
|
|
|
- shouldAnimate.value = true;
|
|
|
|
- shouldFadeOut.value = false;
|
|
|
|
- } else {
|
|
|
|
- shouldFadeOut.value = true;
|
|
|
|
- }
|
|
|
|
|
|
+let assignState = ref(false);
|
|
|
|
+let assignLocationId = ref(null);
|
|
|
|
|
|
- scrollLeft.value = goLeft;
|
|
|
|
-};
|
|
|
|
|
|
+async function getClass() {
|
|
|
|
+ let url = `https://cmm.ai:8088/api/get_class_name?page_num=${pageNum.value}&page_amount=${pageAmount.value}`;
|
|
|
|
+ let assignUrl = `https://cmm.ai:8088/api/get_class_name?page_num=${pageNum.value}&page_amount=${pageAmount.value}&location_id=${assignLocationId.value}`;
|
|
|
|
|
|
-let innerWidth = ref("");
|
|
|
|
-const handleResize = () => {
|
|
|
|
- innerWidth.value = window.innerWidth;
|
|
|
|
- console.log(innerWidth.value);
|
|
|
|
- if (window.innerWidth <= 991) {
|
|
|
|
- scrollCount = 2;
|
|
|
|
- } else {
|
|
|
|
- scrollCount = 1;
|
|
|
|
|
|
+ try {
|
|
|
|
+ const response = await axios.get(assignState.value ? assignUrl : url);
|
|
|
|
+ console.log("response", response.data);
|
|
|
|
+ classes.data = response.data.classes;
|
|
|
|
+ } catch (error) {
|
|
|
|
+ console.error(error);
|
|
}
|
|
}
|
|
-};
|
|
|
|
-
|
|
|
|
-onMounted(() => {
|
|
|
|
- handleResize(); // 初始化檢查一次
|
|
|
|
- window.addEventListener("resize", handleResize);
|
|
|
|
-});
|
|
|
|
|
|
+}
|
|
|
|
|
|
-let classes = reactive({
|
|
|
|
- data: [],
|
|
|
|
-});
|
|
|
|
|
|
+getClass();
|
|
|
|
|
|
-// 取得該據點所有課程
|
|
|
|
|
|
+// 取得特定據點課程總筆數
|
|
const getClassList = async (locationId) => {
|
|
const getClassList = async (locationId) => {
|
|
console.log("locationId", locationId);
|
|
console.log("locationId", locationId);
|
|
|
|
+ assignState.value = true;
|
|
|
|
+ assignLocationId.value = locationId;
|
|
|
|
|
|
try {
|
|
try {
|
|
const response = await axios.get(
|
|
const response = await axios.get(
|
|
`https://cmm.ai:8088/api/get_class_name?location_id=${locationId}`
|
|
`https://cmm.ai:8088/api/get_class_name?location_id=${locationId}`
|
|
);
|
|
);
|
|
- console.log("response", response);
|
|
|
|
- classes.data = response.data.classes;
|
|
|
|
- console.log("classes.data", classes.data);
|
|
|
|
|
|
+ getClass();
|
|
|
|
+ pageNum.value = 1;
|
|
|
|
+ totalPages.value = getTotalPages(response.data.classes.length, 4);
|
|
} catch (error) {
|
|
} catch (error) {
|
|
console.log("error", error);
|
|
console.log("error", error);
|
|
}
|
|
}
|
|
};
|
|
};
|
|
-
|
|
|
|
-onMounted(() => {
|
|
|
|
- window.addEventListener("scroll", handleScroll);
|
|
|
|
-});
|
|
|
|
-
|
|
|
|
-onBeforeUnmount(() => {
|
|
|
|
- window.removeEventListener("scroll", handleScroll);
|
|
|
|
-});
|
|
|
|
-
|
|
|
|
-const previous = () => {
|
|
|
|
- window.scrollTo({ top: 0, behavior: "smooth" });
|
|
|
|
-};
|
|
|
|
</script>
|
|
</script>
|
|
|
|
|
|
<template>
|
|
<template>
|
|
- <div class="home-container">
|
|
|
|
- <div class="wrapper">
|
|
|
|
- <div>
|
|
|
|
- </div>
|
|
|
|
- <div class="scrollable" :style="{ transform: `translateX(-${scrollLeft}px)` }">
|
|
|
|
- <section class="main-block">
|
|
|
|
- <Navbar />
|
|
|
|
- <div class="img-item">
|
|
|
|
- <img src="@/assets/img/banner-0615.webp" alt="" />
|
|
|
|
- <p v-show="shouldAnimate" :class="{
|
|
|
|
- animate__animated: shouldAnimate,
|
|
|
|
- animate__fadeInRight: shouldAnimate && !shouldFadeOut,
|
|
|
|
- animate__fadeOutRight: shouldAnimate && shouldFadeOut,
|
|
|
|
- }">
|
|
|
|
- 臺灣工藝學校 <br />
|
|
|
|
- 以佈局具國際視野之工藝學習共享平台為目標,藉由「工藝學校」的主體概念,推動臺灣工藝學校全球學習平台,以共享、友善、全人、全民的終身工藝手作台進行人才、課程、知識、教材之工藝資源嫁接媒合與內容設計,以在地、就近、線上、線下等多元方式提供不同型態之學習體驗內容及選擇。
|
|
|
|
- </p>
|
|
|
|
- </div>
|
|
|
|
- </section>
|
|
|
|
- <section class="map-block">
|
|
|
|
- <div class="back-btn">
|
|
|
|
- <p @click="previous()">回到首頁</p>
|
|
|
|
- </div>
|
|
|
|
- <div class="content">
|
|
|
|
- <div class="map">
|
|
|
|
- <Map @locationId="getClassList" />
|
|
|
|
- </div>
|
|
|
|
- <v-list lines="three" class="list">
|
|
|
|
- <v-list-item v-for="item in classes.data" :key="item.id">
|
|
|
|
- <div class="d-flex align-center">
|
|
|
|
- <img :src="item.cover_img" alt="" />
|
|
|
|
- <section>
|
|
|
|
- <h2>{{ item.name }}</h2>
|
|
|
|
- <p>主辦單位:{{ item.organizer }}</p>
|
|
|
|
- <p>據點名稱:{{ item.school }}</p>
|
|
|
|
- </section>
|
|
|
|
- </div>
|
|
|
|
- </v-list-item>
|
|
|
|
- </v-list>
|
|
|
|
|
|
+ <div class="banner">
|
|
|
|
+ <img src="@/assets/img/home/banner.png" alt="" class="cover" />
|
|
|
|
+ <img src="@/assets/img/home/logo.png" alt="" class="logo" />
|
|
|
|
+ </div>
|
|
|
|
+ <Navbar />
|
|
|
|
+
|
|
|
|
+ <v-container class="pa-0 pt-16">
|
|
|
|
+ <v-row>
|
|
|
|
+ <v-col cols="4">
|
|
|
|
+ <img src="@/assets/img/home/首頁元素-12.png" alt="" />
|
|
|
|
+ </v-col>
|
|
|
|
+ <v-col cols="4">
|
|
|
|
+ <img src="@/assets/img/home/首頁元素-11.png" alt="" />
|
|
|
|
+ </v-col>
|
|
|
|
+ <v-col cols="4">
|
|
|
|
+ <img src="@/assets/img/home/首頁元素-10.png" alt="" />
|
|
|
|
+ </v-col>
|
|
|
|
+ <v-col cols="4">
|
|
|
|
+ <img src="@/assets/img/home/首頁元素-09.png" alt="" />
|
|
|
|
+ </v-col>
|
|
|
|
+ <v-col cols="4" class="d-flex justify-center align-center">
|
|
|
|
+ <h3 class="title">八大工藝學群</h3>
|
|
|
|
+ </v-col>
|
|
|
|
+ <v-col cols="4">
|
|
|
|
+ <img src="@/assets/img/home/首頁元素-05.png" alt="" />
|
|
|
|
+ </v-col>
|
|
|
|
+ <v-col cols="4">
|
|
|
|
+ <img src="@/assets/img/home/首頁元素-06.png" alt="" />
|
|
|
|
+ </v-col>
|
|
|
|
+ <v-col cols="4">
|
|
|
|
+ <img src="@/assets/img/home/首頁元素-07.png" alt="" />
|
|
|
|
+ </v-col>
|
|
|
|
+ <v-col cols="4">
|
|
|
|
+ <img src="@/assets/img/home/首頁元素-08.png" alt="" />
|
|
|
|
+ </v-col>
|
|
|
|
+ </v-row>
|
|
|
|
+
|
|
|
|
+ <div class="map-block">
|
|
|
|
+ <h3 class="mb-10 title">全台工藝地圖</h3>
|
|
|
|
+ <div class="v-row">
|
|
|
|
+ <v-col cols="7">
|
|
|
|
+ <div class="map">
|
|
|
|
+ <Map @locationId="getClassList" />
|
|
</div>
|
|
</div>
|
|
- </section>
|
|
|
|
|
|
+ </v-col>
|
|
|
|
+ <v-col cols="5">
|
|
|
|
+ <v-list lines="three" class="list pa-0">
|
|
|
|
+ <v-list-item v-for="item in classes.data" :key="item.id">
|
|
|
|
+ <div class="d-flex align-center">
|
|
|
|
+ <img :src="item.cover_img" alt="" />
|
|
|
|
+ <section>
|
|
|
|
+ <h2>{{ item.name }}</h2>
|
|
|
|
+ <p>主辦單位:{{ item.organizer }}</p>
|
|
|
|
+ <p>據點名稱:{{ item.school }}</p>
|
|
|
|
+ </section>
|
|
|
|
+ </div>
|
|
|
|
+ </v-list-item>
|
|
|
|
+ </v-list>
|
|
|
|
+ <v-pagination
|
|
|
|
+ v-model="pageNum"
|
|
|
|
+ class="my-4"
|
|
|
|
+ :length="totalPages"
|
|
|
|
+ ></v-pagination>
|
|
|
|
+ </v-col>
|
|
</div>
|
|
</div>
|
|
|
|
+ <!-- <div class="map">
|
|
|
|
+ <Map @locationId="getClassList" />
|
|
|
|
+ </div> -->
|
|
</div>
|
|
</div>
|
|
- </div>
|
|
|
|
|
|
+ </v-container>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
-<style lang="scss">
|
|
|
|
-@import "animate.css/animate.min.css";
|
|
|
|
-
|
|
|
|
-.home-container {
|
|
|
|
- height: 150vw; // 捲軸高度
|
|
|
|
- overflow: hidden;
|
|
|
|
-
|
|
|
|
- @media (max-width: 960px) {
|
|
|
|
- height: 300vw;
|
|
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
+.banner {
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: center;
|
|
|
|
+ position: relative;
|
|
|
|
+ .cover {
|
|
|
|
+ width: 100vw;
|
|
|
|
+ height: 100vh;
|
|
|
|
+ object-fit: cover;
|
|
}
|
|
}
|
|
-
|
|
|
|
- .wrapper {
|
|
|
|
- overflow: hidden;
|
|
|
|
- position: fixed;
|
|
|
|
|
|
+ .logo {
|
|
|
|
+ width: 800px;
|
|
|
|
+ position: absolute;
|
|
|
|
+ z-index: 10;
|
|
}
|
|
}
|
|
-
|
|
|
|
- .scrollable {
|
|
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.title {
|
|
|
|
+ font-size: 26px;
|
|
|
|
+ font-weight: 400;
|
|
|
|
+ letter-spacing: 2px;
|
|
|
|
+ text-align: center;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.map-block {
|
|
|
|
+ margin: 100px auto;
|
|
|
|
+ .map {
|
|
height: 100vh;
|
|
height: 100vh;
|
|
- display: flex;
|
|
|
|
- align-items: end;
|
|
|
|
-
|
|
|
|
- .img-item {
|
|
|
|
- width: 100%;
|
|
|
|
- height: 100%;
|
|
|
|
- position: relative;
|
|
|
|
-
|
|
|
|
- img {
|
|
|
|
- width: 100%;
|
|
|
|
- height: 100%;
|
|
|
|
- object-fit: cover;
|
|
|
|
- object-position: top;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- p {
|
|
|
|
- width: 600px;
|
|
|
|
- top: 170px;
|
|
|
|
- right: 7.5%;
|
|
|
|
- position: absolute;
|
|
|
|
- z-index: 100;
|
|
|
|
- font-size: 24px;
|
|
|
|
- line-height: 38px;
|
|
|
|
- color: #fff;
|
|
|
|
- text-shadow: 2px 2px 5px #333;
|
|
|
|
-
|
|
|
|
- @media (max-width: 1700px) {
|
|
|
|
- width: 33vw;
|
|
|
|
- top: 140px;
|
|
|
|
- right: 6%;
|
|
|
|
- }
|
|
|
|
|
|
+ }
|
|
|
|
|
|
- @media (max-width: 767px) {
|
|
|
|
- display: none !important;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ .list {
|
|
|
|
+ img {
|
|
|
|
+ width: 200px;
|
|
|
|
+ height: 175px;
|
|
|
|
+ margin-right: 20px;
|
|
|
|
+ border-radius: 5px;
|
|
|
|
+ box-shadow: 2px 2px 4px #aaaaaa;
|
|
}
|
|
}
|
|
|
|
|
|
- &::after {
|
|
|
|
- content: "";
|
|
|
|
- display: table;
|
|
|
|
- clear: both;
|
|
|
|
|
|
+ h2 {
|
|
|
|
+ font-size: 18px;
|
|
|
|
+ margin-bottom: 20px;
|
|
}
|
|
}
|
|
|
|
|
|
- .main-block,
|
|
|
|
- .map-block {
|
|
|
|
- width: 100vw;
|
|
|
|
- display: flex;
|
|
|
|
- align-items: center;
|
|
|
|
-
|
|
|
|
- @media (max-width: 1200px) {
|
|
|
|
- height: 84vh;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- @media (max-width: 960px) {
|
|
|
|
- width: 150vw;
|
|
|
|
- }
|
|
|
|
|
|
+ h2,
|
|
|
|
+ p {
|
|
|
|
+ line-height: 28px;
|
|
|
|
+ // 超過兩行則省略
|
|
|
|
+ overflow: hidden;
|
|
|
|
+ text-overflow: ellipsis;
|
|
|
|
+ display: -webkit-box;
|
|
|
|
+ -webkit-line-clamp: 2;
|
|
|
|
+ -webkit-box-orient: vertical;
|
|
|
|
+ line-break: after-white-space;
|
|
}
|
|
}
|
|
|
|
|
|
- .main-block {
|
|
|
|
- height: 82vh;
|
|
|
|
|
|
+ .v-list-item {
|
|
|
|
+ height: 215px;
|
|
|
|
+ padding: 20px 0;
|
|
|
|
+ border-bottom: 1px solid #cccccc;
|
|
|
|
|
|
- .navbar {
|
|
|
|
- right: 50.5%;
|
|
|
|
- position: absolute;
|
|
|
|
|
|
+ &:first-child {
|
|
|
|
+ padding: 0 0 20px;
|
|
}
|
|
}
|
|
- }
|
|
|
|
-
|
|
|
|
- .map-block {
|
|
|
|
- height: 100vh;
|
|
|
|
|
|
|
|
- .content {
|
|
|
|
- width: 100%;
|
|
|
|
- height: 100%;
|
|
|
|
- display: flex;
|
|
|
|
-
|
|
|
|
- .map,
|
|
|
|
- .list {
|
|
|
|
- @media (max-width: 960px) {
|
|
|
|
- width: 100%;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- .map {
|
|
|
|
- width: 60%;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- .list {
|
|
|
|
- width: 40%;
|
|
|
|
-
|
|
|
|
- img {
|
|
|
|
- width: 200px;
|
|
|
|
- margin-right: 20px;
|
|
|
|
- border-radius: 5px;
|
|
|
|
- box-shadow: 2px 2px 4px #aaaaaa;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- h2 {
|
|
|
|
- font-size: 18px;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- h2,
|
|
|
|
- p {
|
|
|
|
- line-height: 30px;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- .v-list-item {
|
|
|
|
- padding: 30px 20px;
|
|
|
|
- border-bottom: 1px solid #cccccc;
|
|
|
|
-
|
|
|
|
- .v-list-item__content {
|
|
|
|
- overflow: initial !important;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ &:last-child {
|
|
|
|
+ border-bottom: none;
|
|
}
|
|
}
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- .back-btn {
|
|
|
|
- height: 18vh;
|
|
|
|
- position: absolute;
|
|
|
|
- // top: 0;
|
|
|
|
- // right: 80px;
|
|
|
|
- top: -4%;
|
|
|
|
- right: 22%;
|
|
|
|
- z-index: 1000;
|
|
|
|
- display: flex;
|
|
|
|
- align-items: center;
|
|
|
|
-
|
|
|
|
- @media (max-width: 1200px) {
|
|
|
|
- height: 16vh;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- p {
|
|
|
|
- cursor: pointer;
|
|
|
|
- transition: all 0.3s;
|
|
|
|
|
|
|
|
- &:hover {
|
|
|
|
- opacity: 0.8;
|
|
|
|
|
|
+ .v-list-item__content {
|
|
|
|
+ overflow: initial !important;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
-}</style>
|
|
|
|
|
|
+}
|
|
|
|
+</style>
|