SyuanYu 1 年間 前
コミット
4f0807486b
74 ファイル変更469 行追加169 行削除
  1. 1 0
      .env.development
  2. 1 0
      .env.production
  3. 11 1
      index.html
  4. 9 1
      src/assets/css/style.css
  5. 0 0
      src/assets/css/style.css.map
  6. 9 1
      src/assets/css/style.scss
  7. BIN
      src/assets/img/banner-0615.webp
  8. BIN
      src/assets/img/college-group/banner-mb.png
  9. BIN
      src/assets/img/college-group/banner-mb.webp
  10. BIN
      src/assets/img/college-group/future/素材-16.png
  11. BIN
      src/assets/img/college-group/future/素材-17.png
  12. BIN
      src/assets/img/college-group/future/素材-18.png
  13. BIN
      src/assets/img/college-group/future/素材-19.png
  14. BIN
      src/assets/img/college-group/future/素材-20.png
  15. BIN
      src/assets/img/college-group/future/素材-21.png
  16. BIN
      src/assets/img/college-group/future/素材-22.png
  17. BIN
      src/assets/img/college-group/future/素材-23.png
  18. BIN
      src/assets/img/college-group/future/素材-24.png
  19. BIN
      src/assets/img/college-group/life/apprentice/about.jpg
  20. BIN
      src/assets/img/college-group/life/apprentice/about.webp
  21. BIN
      src/assets/img/college-group/life/shop/一日咖啡.jpg
  22. BIN
      src/assets/img/college-group/life/shop/光山行.jpg
  23. BIN
      src/assets/img/college-group/life/shop/初窯工坊.jpg
  24. BIN
      src/assets/img/college-group/life/shop/品工藝.jpg
  25. BIN
      src/assets/img/college-group/life/shop/手民石匠.jpg
  26. BIN
      src/assets/img/college-group/life/shop/木島TïmbormOsA.jpg
  27. BIN
      src/assets/img/college-group/life/shop/苗栗陶青年創意協會.jpg
  28. BIN
      src/assets/img/default.png
  29. BIN
      src/assets/img/default.webp
  30. BIN
      src/assets/img/home/banner-mb.webp
  31. BIN
      src/assets/img/home/首頁元素-05.png
  32. BIN
      src/assets/img/home/首頁元素-05.webp
  33. BIN
      src/assets/img/home/首頁元素-06.png
  34. BIN
      src/assets/img/home/首頁元素-06.webp
  35. BIN
      src/assets/img/home/首頁元素-07.png
  36. BIN
      src/assets/img/home/首頁元素-07.webp
  37. BIN
      src/assets/img/home/首頁元素-08.png
  38. BIN
      src/assets/img/home/首頁元素-08.webp
  39. BIN
      src/assets/img/home/首頁元素-09.png
  40. BIN
      src/assets/img/home/首頁元素-09.webp
  41. BIN
      src/assets/img/home/首頁元素-10.png
  42. BIN
      src/assets/img/home/首頁元素-10.webp
  43. BIN
      src/assets/img/home/首頁元素-11.png
  44. BIN
      src/assets/img/home/首頁元素-11.webp
  45. BIN
      src/assets/img/home/首頁元素-12.png
  46. BIN
      src/assets/img/home/首頁元素-12.webp
  47. BIN
      src/assets/img/img-01.jpg
  48. BIN
      src/assets/img/img-02.jpg
  49. BIN
      src/assets/img/news/news-02(邊框).png
  50. BIN
      src/assets/img/news/news-02.png
  51. BIN
      src/assets/img/news/news-bg.webp
  52. BIN
      src/assets/img/news/news-detail-banner.png
  53. BIN
      src/assets/img/text_1.jpg
  54. BIN
      src/assets/img/text_2.jpg
  55. BIN
      src/assets/img/text_3.jpg
  56. 2 2
      src/components/CourseCard.vue
  57. 1 1
      src/components/CoursesTutorial.vue
  58. 76 18
      src/stores/store.js
  59. 1 1
      src/views/ArticleDetail.vue
  60. 1 1
      src/views/CollegeGroup/Life/Apprentice/About.vue
  61. 111 68
      src/views/CollegeGroup/Life/Shop.vue
  62. 1 1
      src/views/CollegeGroup/Main.vue
  63. 26 2
      src/views/CollegeGroup/Online.vue
  64. 22 12
      src/views/CourseDetail.vue
  65. 28 6
      src/views/Courses/Create.vue
  66. 1 1
      src/views/Courses/SetUp.vue
  67. 9 8
      src/views/Home.vue
  68. 56 0
      src/views/Login.vue
  69. 1 1
      src/views/News.vue
  70. 1 1
      src/views/NewsDetail.vue
  71. 16 30
      src/views/User/Courses.vue
  72. 2 2
      src/views/User/Dashboard.vue
  73. 1 0
      src/views/User/FavoriteClass.vue
  74. 82 11
      src/views/User/Passport.vue

+ 1 - 0
.env.development

@@ -0,0 +1 @@
+VITE_API_URL=https://cmm.ai:8088

+ 1 - 0
.env.production

@@ -0,0 +1 @@
+VITE_API_URL=http://127.0.0.1:8088

+ 11 - 1
index.html

@@ -10,8 +10,18 @@
   <link rel="preconnect" href="https://fonts.googleapis.com">
   <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
   <link href="https://fonts.googleapis.com/css2?family=Noto+Sans+TC:wght@100;300;400;500&display=swap" rel="stylesheet">
-  
+
   <title>臺灣工藝學校全球學習共享平台</title>
+
+  <!-- Google tag (gtag.js) -->
+  <script async src="https://www.googletagmanager.com/gtag/js?id=G-57B1K83C1N"></script>
+  <script>
+    window.dataLayer = window.dataLayer || [];
+    function gtag() { dataLayer.push(arguments); }
+    gtag('js', new Date());
+
+    gtag('config', 'G-57B1K83C1N');
+  </script>
 </head>
 
 <body>

+ 9 - 1
src/assets/css/style.css

@@ -530,6 +530,14 @@ input:focus-visible {
   background-color: #f3f3f3;
 }
 
+.date-reminder {
+  position: absolute;
+  bottom: -25px;
+  left: 100px;
+  font-size: 0.75em;
+  line-height: 1.2;
+}
+
 .tag-btn .item {
   display: flex;
   align-items: center;
@@ -750,7 +758,7 @@ input:focus-visible {
   position: relative;
   border-collapse: collapse;
 }
-@media (max-width: 1280px) {
+@media (max-width: 1000px) {
   .main-table table {
     width: 800px;
   }

ファイルの差分が大きいため隠しています
+ 0 - 0
src/assets/css/style.css.map


+ 9 - 1
src/assets/css/style.scss

@@ -574,6 +574,14 @@ input:focus-visible {
   }
 }
 
+.date-reminder {
+  position: absolute;
+  bottom: -25px;
+  left: 100px;
+  font-size: 0.75em;
+  line-height: 1.2;
+}
+
 .tag-btn {
   // @media (max-width: 960px) {
   //   margin: auto !important;
@@ -825,7 +833,7 @@ input:focus-visible {
     position: relative;
     border-collapse: collapse;
 
-    @media (max-width: 1280px) {
+    @media (max-width: 1000px) {
       width: 800px;
     }
 

BIN
src/assets/img/banner-0615.webp


BIN
src/assets/img/college-group/banner-mb.png


BIN
src/assets/img/college-group/banner-mb.webp


BIN
src/assets/img/college-group/future/素材-16.png


BIN
src/assets/img/college-group/future/素材-17.png


BIN
src/assets/img/college-group/future/素材-18.png


BIN
src/assets/img/college-group/future/素材-19.png


BIN
src/assets/img/college-group/future/素材-20.png


BIN
src/assets/img/college-group/future/素材-21.png


BIN
src/assets/img/college-group/future/素材-22.png


BIN
src/assets/img/college-group/future/素材-23.png


BIN
src/assets/img/college-group/future/素材-24.png


BIN
src/assets/img/college-group/life/apprentice/about.jpg


BIN
src/assets/img/college-group/life/apprentice/about.webp


BIN
src/assets/img/college-group/life/shop/一日咖啡.jpg


BIN
src/assets/img/college-group/life/shop/光山行.jpg


BIN
src/assets/img/college-group/life/shop/初窯工坊.jpg


BIN
src/assets/img/college-group/life/shop/品工藝.jpg


BIN
src/assets/img/college-group/life/shop/手民石匠.jpg


BIN
src/assets/img/college-group/life/shop/木島TïmbormOsA.jpg


BIN
src/assets/img/college-group/life/shop/苗栗陶青年創意協會.jpg


BIN
src/assets/img/default.png


BIN
src/assets/img/default.webp


BIN
src/assets/img/home/banner-mb.webp


BIN
src/assets/img/home/首頁元素-05.png


BIN
src/assets/img/home/首頁元素-05.webp


BIN
src/assets/img/home/首頁元素-06.png


BIN
src/assets/img/home/首頁元素-06.webp


BIN
src/assets/img/home/首頁元素-07.png


BIN
src/assets/img/home/首頁元素-07.webp


BIN
src/assets/img/home/首頁元素-08.png


BIN
src/assets/img/home/首頁元素-08.webp


BIN
src/assets/img/home/首頁元素-09.png


BIN
src/assets/img/home/首頁元素-09.webp


BIN
src/assets/img/home/首頁元素-10.png


BIN
src/assets/img/home/首頁元素-10.webp


BIN
src/assets/img/home/首頁元素-11.png


BIN
src/assets/img/home/首頁元素-11.webp


BIN
src/assets/img/home/首頁元素-12.png


BIN
src/assets/img/home/首頁元素-12.webp


BIN
src/assets/img/img-01.jpg


BIN
src/assets/img/img-02.jpg


BIN
src/assets/img/news/news-02(邊框).png


BIN
src/assets/img/news/news-02.png


BIN
src/assets/img/news/news-bg.webp


BIN
src/assets/img/news/news-detail-banner.png


BIN
src/assets/img/text_1.jpg


BIN
src/assets/img/text_2.jpg


BIN
src/assets/img/text_3.jpg


+ 2 - 2
src/components/CourseCard.vue

@@ -82,7 +82,7 @@ function isClassFavorite(classId) {
 //   } else if (data.group_id === 9) {
 //     return store.getImageUrl("cfa-default.jpg");
 //   } else if (data.special_class_list_name === "one_day_class") {
-//     return store.getImageUrl("default.png");
+//     return store.getImageUrl("default.webp");
 //   } else if (data.org === "Udemy") {
 //     return data.cover_img;
 //   } else {
@@ -131,7 +131,7 @@ function isClassFavorite(classId) {
         <small class="text-gray">編號:{{ data.encode }}</small>
       </div>
       <!-- </router-link> -->
-      
+
       <ul v-if="data.org !== 'Udemy'">
         <li class="d-flex align-center mb-5">
           <div class="description">

+ 1 - 1
src/components/CoursesTutorial.vue

@@ -429,7 +429,7 @@ h3 {
 
 // Swiper
 .background-image {
-  background-image: url("@/assets/img/default.png");
+  background-image: url("@/assets/img/default.webp");
   width: 100%;
   height: 100%;
   position: absolute;

+ 76 - 18
src/stores/store.js

@@ -1,10 +1,13 @@
 import { defineStore, } from 'pinia';
+import { useRoute } from "vue-router";
 import axios from "axios";
 
 export const useMainStore = defineStore('mainStore', {
   state: () => ({
+    apiUrl: import.meta.env.VITE_API_URL,
     count: 0,
     token: "",
+    authCode: "", // 藝文中心登入回傳參數
     loginState: false, // 登入狀態
     loginDialog: false, // 登入視窗
     profile: {}, // 使用者資訊
@@ -23,19 +26,69 @@ export const useMainStore = defineStore('mainStore', {
   },
   actions: {
     // 檢查登入狀態
+    // checkToken() {
+    //   const token = localStorage.getItem('token');
+    //   console.log('checkToken', token);
+    //   if (token) {
+    //     this.token = token;
+    //     this.loginState = true;
+    //   } else {
+    //     this.token = null;
+    //     this.loginState = false;
+    //   }
+
+    //   return this.loginState;
+    // },
     checkToken() {
-      const token = localStorage.getItem('token');
-      console.log('checkToken', token);
-      if (token) {
-        this.token = token;
+      const queryParams = this.getURLParams();
+
+      console.log('queryParams', queryParams);
+      if (queryParams.AuthCode) {
         this.loginState = true;
+        this.authCode = queryParams.AuthCode;
+        console.log('AuthCode', this.authCode);
+        localStorage.setItem("AuthCode", this.authCode);
+        this.getAuthToken();
       } else {
-        this.token = null;
         this.loginState = false;
       }
+      console.log(queryParams.AuthCode);
 
       return this.loginState;
     },
+    async getAuthToken() {
+      console.log('getAuthToken');
+      // https://member.moc.gov.tw/MOCMC/T0001/ottGetAuthToken
+
+      try {
+        // const response1 = await axios.get(
+        //   `https://member.moc.gov.tw/MOCMC/T0001/ottGetAuthToken?SYS_ID=CRAFT_NTCRI&SYS_PASSWORD=luZ2le0W&AuthCode=${this.authCode}&IS_DEV=Y`
+        // );
+        // const response2 = await axios.get(
+        //   `https://10.40.100.32/MOCMC/T0001/ottGetAuthToken?SYS_ID=CRAFT_NTCRI&SYS_PASSWORD=luZ2le0W&AuthCode=${this.authCode}&IS_DEV=Y`
+        // );
+        const response3 = await axios.post(
+          `https://member.moc.gov.tw/MOCMC/T0001/ottGetAuthToken?SYS_ID=CRAFT_NTCRI&SYS_PASSWORD=luZ2le0W&AuthCode=${this.authCode}&IS_DEV=Y`
+        );
+        // console.log('取得 AuthToken-1', response1);
+        // console.log('取得 AuthToken-2', response2);
+        console.log('取得 AuthToken-3', response3);
+
+      } catch (error) {
+        console.error(error);
+      }
+    },
+    // 取得網址參數
+    getURLParams() {
+      const urlParams = new URLSearchParams(window.location.search);
+      const params = {};
+
+      urlParams.forEach((value, key) => {
+        params[key] = value;
+      });
+
+      return params;
+    },
     logout() {
       localStorage.removeItem("token");
       console.log('logout');
@@ -104,19 +157,12 @@ export const useMainStore = defineStore('mainStore', {
     // 處理時間格式(日期+時間)
     mergeAndFormatDateTime(dateString, timeInfo) {
       const date = new Date(dateString);
+      const year = date.getFullYear();
+      const month = date.getMonth() + 1; // 月份是從 0 開始計算的,所以要加 1
+      const day = date.getDate();
 
-      date.setHours(timeInfo.hours);
-      date.setMinutes(timeInfo.minutes);
-      date.setSeconds(timeInfo.seconds);
-
-      const year = date.getUTCFullYear();
-      const month = String(date.getUTCMonth() + 1).padStart(2, "0");
-      const day = String(date.getUTCDate()).padStart(2, "0");
-      const hours = String(date.getUTCHours()).padStart(2, "0");
-      const minutes = String(date.getUTCMinutes()).padStart(2, "0");
-      const seconds = String(date.getUTCSeconds()).padStart(2, "0");
-
-      return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.000Z`;
+      return `${year}-${month}-${day}T${timeInfo.hours < 10 ? '0' : ''}${timeInfo.hours}:${timeInfo.minutes < 10 ? '0' : ''}${timeInfo.minutes}:00.000Z`;
+      // return `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.000Z`;
     },
     // 將 UTC 時間轉換為台灣時間
     convertUTCtoTaiwanTime(utcTimeString) {
@@ -125,6 +171,18 @@ export const useMainStore = defineStore('mainStore', {
       console.log('轉台灣時間', localTime);
       return localTime;
     },
+    // 判斷兩組日期是否相同
+    isSameDay(date1, date2) {
+      const year1 = date1.getFullYear();
+      const month1 = date1.getMonth() + 1;
+      const day1 = date1.getDate();
+
+      const year2 = date2.getFullYear();
+      const month2 = date2.getMonth() + 1;
+      const day2 = date2.getDate();
+
+      return `${year1}${month1}${day1}` === `${year2}${month2}${day2}`;
+    },
     getPDF(name) {
       return `https://ntcri.org/pdf/${name}.pdf`;
     },
@@ -162,7 +220,7 @@ export const useMainStore = defineStore('mainStore', {
       if (data.group_id === 9) {
         return this.getImageUrl("cfa-default.jpg");
       } else if (data.special_class_list_name === "one_day_class") {
-        return this.getImageUrl("default.png");
+        return this.getImageUrl("default.webp");
       } else if (regex.test(data.cover_img)) {
         return data.cover_img;
       } else {

+ 1 - 1
src/views/ArticleDetail.vue

@@ -179,7 +179,7 @@ ul {
 
 .content {
   padding: 1.25em;
-  background-image: url("@/assets/img/news/news-02.png");
+  background-image: url("@/assets/img/news/news-bg.webp");
   background-position: center;
   background-size: cover;
   border-radius: 3.125em;

+ 1 - 1
src/views/CollegeGroup/Life/Apprentice/About.vue

@@ -2,7 +2,7 @@
   <div>
     <h3 class="sub-title">關於一日學徒</h3>
     <img
-      src="@/assets/img/college-group/life/apprentice/about.jpg"
+      src="@/assets/img/college-group/life/apprentice/about.webp"
       alt="臺灣工藝學校全球學習共享平台"
       class="mb-10"
     />

+ 111 - 68
src/views/CollegeGroup/Life/Shop.vue

@@ -32,7 +32,7 @@ let article = reactive({
       "https://cmm.ai:8088/api/get_article?group_sort=旅物SHOP"
     );
     article.list = response.data.articles;
-    console.log("response", article.list);
+    console.log("旅物 SHOP", article.list);
   } catch (error) {
     console.error(error);
   }
@@ -77,28 +77,28 @@ const shopImgs = [
   },
 ];
 
-const youthImgs = [
-  {
-    img: store.getImageUrl("college-group/life/shop/苗栗陶青年創意協會.jpg"),
-    title: "苗栗陶青年創意協會",
-  },
-  {
-    img: store.getImageUrl("college-group/life/shop/初窯工坊.jpg"),
-    title: "初窯工坊 – 郭琦、逄家妤",
-  },
-  {
-    img: store.getImageUrl("college-group/life/shop/光山行.jpg"),
-    title: "光山行 – 賴信佑",
-  },
-  {
-    img: store.getImageUrl("college-group/life/shop/木島TïmbormOsA.jpg"),
-    title: "木島TïmbormOsA – 張嘉哲、吳欣容",
-  },
-  {
-    img: store.getImageUrl("college-group/life/shop/手民石匠.jpg"),
-    title: "手民石匠 – 蔡安婷、林育賢",
-  },
-];
+// const youthImgs = [
+//   {
+//     img: store.getImageUrl("college-group/life/shop/苗栗陶青年創意協會.jpg"),
+//     title: "苗栗陶青年創意協會",
+//   },
+//   {
+//     img: store.getImageUrl("college-group/life/shop/初窯工坊.jpg"),
+//     title: "初窯工坊 – 郭琦、逄家妤",
+//   },
+//   {
+//     img: store.getImageUrl("college-group/life/shop/光山行.jpg"),
+//     title: "光山行 – 賴信佑",
+//   },
+//   {
+//     img: store.getImageUrl("college-group/life/shop/木島TimbormOsA.jpg"),
+//     title: "木島TïmbormOsA – 張嘉哲、吳欣容",
+//   },
+//   {
+//     img: store.getImageUrl("college-group/life/shop/手民石匠.jpg"),
+//     title: "手民石匠 – 蔡安婷、林育賢",
+//   },
+// ];
 </script>
 
 <template>
@@ -110,7 +110,7 @@ const youthImgs = [
 
   <h2 class="title">旅物 SHOP</h2>
 
-  <div class="px-md-8">
+  <div class="px-md-8 shop-block">
     <v-slide-group center-active show-arrows>
       <v-slide-group-item v-for="item in shopImgs" :key="item">
         <div class="ma-3">
@@ -163,12 +163,41 @@ const youthImgs = [
       </v-col>
     </v-row>
 
-    <section class="block">
+    <v-row>
+      <v-col cols="12" v-for="(item, index) in article.list" :key="index">
+        <section class="list-item">
+          <h3 class="block-title mb-7">{{ item.title }}</h3>
+          <img
+            v-if="item.cover_img !== ''"
+            :src="`https://ntcri.org/${item.cover_img}`"
+            alt="臺灣工藝學校全球學習共享平台"
+            class="mb-7"
+          />
+          <div class="content">
+            <div v-html="item.content"></div>
+            <span
+              v-if="item.title === '臺灣綠工藝 Taiwan Green Craft'"
+              class="d-flex"
+            >
+              <a
+                href="https://tcc.ntcri.gov.tw/home/zh-tw/object"
+                class="link-btn ms-auto mt-10"
+                target="_blank"
+              >
+                品牌選物主題網站
+              </a>
+            </span>
+          </div>
+        </section>
+      </v-col>
+    </v-row>
+
+    <!-- <section class="block">
       <h3 class="block-title">臺灣綠工藝 Taiwan Green Craft</h3>
       <img
         src="@/assets/img/college-group/life/shop/旅物shop-03.png"
         alt="臺灣工藝學校全球學習共享平台"
-        class="my-7"
+        class="mb-7"
       />
       <div class="content d-flex flex-column">
         <p>
@@ -218,7 +247,7 @@ const youthImgs = [
       <img
         src="@/assets/img/college-group/life/shop/品工藝.jpg"
         alt="臺灣工藝學校全球學習共享平台"
-        class="my-7"
+        class="mb-7"
       />
       <div class="content">
         <p>
@@ -235,7 +264,7 @@ const youthImgs = [
       <img
         src="@/assets/img/college-group/life/shop/一日咖啡.jpg"
         alt="臺灣工藝學校全球學習共享平台"
-        class="my-7"
+        class="mb-7"
       />
       <div class="content">
         <p>
@@ -245,55 +274,69 @@ const youthImgs = [
           「一日咖啡」由國際咖啡品鑑師Q-Grader領軍的南投在地「日晨咖啡烘焙」及傳承70年的「什一堂烘焙坊」第三代共同合作經營,提供旅人休憩享用,也為展陳空間增添嗅覺、味覺體驗。
         </p>
       </div>
-    </section>
+    </section> -->
   </div>
 </template>
 
-<style lang="scss" scoped>
-p,
-li {
-  line-height: 1.875em;
-  letter-spacing: 0.0625em;
-}
-.block {
-  margin: 6.25em 0;
-  .content {
-    padding: 1.5625em;
-    border-radius: 1.25em;
-    border: 0.125em solid var(--purple);
+<style lang="scss">
+.shop-block {
+  p,
+  li {
+    line-height: 1.875em;
+    letter-spacing: 0.0625em;
   }
-  .youth-imgs {
-    img {
-      width: 100%;
-      height: 13.75em;
-      object-fit: cover;
-      @media (max-width: 1280px) {
-        height: 15vw;
+  .list-item {
+    margin: 3em 0;
+    .content {
+      padding: 1.5625em;
+      border-radius: 1.25em;
+      border: 0.125em solid var(--purple);
+
+      table {
+        td {
+          padding: 10px;
+          img {
+            width: 100%;
+            height: 200px;
+            object-fit: cover;
+          }
+        }
       }
-      @media (max-width: 960px) {
-        height: 25vw;
+    }
+
+    .youth-imgs {
+      img {
+        width: 100%;
+        height: 13.75em;
+        object-fit: cover;
+        @media (max-width: 1280px) {
+          height: 15vw;
+        }
+        @media (max-width: 960px) {
+          height: 25vw;
+        }
+        @media (max-width: 600px) {
+          height: 50vw;
+        }
       }
-      @media (max-width: 600px) {
-        height: 50vw;
+      h4 {
+        margin-top: 1.25em;
+        line-height: 1.5em;
       }
     }
-    h4 {
-      margin-top: 1.25em;
-      line-height: 1.5em;
+    .block-title,
+    .youth-imgs h4 {
+      font-weight: 500;
+      text-align: center;
+      letter-spacing: 0.0625em;
+    }
+    .block-title {
+      padding: 1.25em;
+      font-size: 1.25em;
+      line-height: 1.75em;
+      color: #fff;
+      background: var(--purple);
     }
-  }
-  .block-title,
-  .youth-imgs h4 {
-    font-weight: 500;
-    text-align: center;
-    letter-spacing: 0.0625em;
-  }
-  .block-title {
-    padding: 1.25em;
-    font-size: 1.25em;
-    line-height: 1.75em;
-    color: #fff;
-    background: var(--purple);
   }
 }
 </style>

+ 1 - 1
src/views/CollegeGroup/Main.vue

@@ -106,7 +106,7 @@ async function getGroup(id) {
         />
         <img
           class="d-block d-md-none"
-          src="@/assets/img/college-group/banner-mb.png"
+          src="@/assets/img/college-group/banner-mb.webp"
           alt="臺灣工藝學校全球學習共享平台"
         />
         <div class="description-item">

+ 26 - 2
src/views/CollegeGroup/Online.vue

@@ -131,6 +131,24 @@ async function selectFilter(type, val) {
 
   getClass();
 }
+
+// https://api.imedia.culture.tw/api/public_api/
+
+async function getImediaVideo() {
+  let url =
+    "https://api.imedia.culture.tw/api/public_api/tokens/08c9cdf9-a1d6-4997-943c-4f08f34ed2f7";
+
+  try {
+    const response = await axios.post(url);
+
+    console.log("Imedia", response);
+  } catch (error) {
+    loading.value = false;
+    console.error(error);
+  }
+}
+
+getImediaVideo();
 </script>
 
 <template>
@@ -150,7 +168,10 @@ async function selectFilter(type, val) {
           placeholder="關鍵字搜尋"
         />
         <button @click="search()">
-          <img src="@/assets/img/news/news-search-icon.png" alt="臺灣工藝學校全球學習共享平台" />
+          <img
+            src="@/assets/img/news/news-search-icon.png"
+            alt="臺灣工藝學校全球學習共享平台"
+          />
         </button>
       </span>
       <div
@@ -212,7 +233,10 @@ async function selectFilter(type, val) {
           placeholder="關鍵字搜尋"
         />
         <button @click="search()">
-          <img src="@/assets/img/news/news-search-icon.png" alt="臺灣工藝學校全球學習共享平台" />
+          <img
+            src="@/assets/img/news/news-search-icon.png"
+            alt="臺灣工藝學校全球學習共享平台"
+          />
         </button>
       </span>
       <div

+ 22 - 12
src/views/CourseDetail.vue

@@ -283,8 +283,8 @@ function isDateExpired(dateString) {
   // 獲取當前時間
   const currentDate = new Date();
 
-  console.log('registrationEndDate',registrationEndDate);
-  console.log('currentDate',currentDate);
+  console.log("registrationEndDate", registrationEndDate);
+  console.log("currentDate", currentDate);
 
   if (registrationEndDate > currentDate) {
     return true; // 日期已過期
@@ -440,7 +440,9 @@ function isDateExpired(dateString) {
               <tr>
                 <th>場次名稱</th>
                 <th>開始/結束時間</th>
-                <th v-show="session.data[0].location">課程教室</th>
+                <th v-show="session.data[0].location" style="width: 200px">
+                  課程教室
+                </th>
                 <th>課程費用</th>
                 <th>課程名額</th>
                 <th>講師</th>
@@ -452,10 +454,18 @@ function isDateExpired(dateString) {
               <tr v-for="(item, index) in session.data" :key="index">
                 <td width="20%">{{ item.class_name }}</td>
                 <td width="20%">
-                  {{ moment(`${item.start_time}`).format("YYYY/MM/DD H:mm") }}
+                  {{
+                    moment(`${item.start_time}`)
+                      .utcOffset(0)
+                      .format("YYYY/MM/DD HH:mm")
+                  }}
                   <br />
                   ~ <br />
-                  {{ moment(`${item.end_time}`).format("YYYY/MM/DD H:mm") }}
+                  {{
+                    moment(`${item.end_time}`)
+                      .utcOffset(0)
+                      .format("YYYY/MM/DD HH:mm")
+                  }}
                 </td>
                 <td v-show="item.location !== ''">
                   {{ item.location }}
@@ -468,9 +478,9 @@ function isDateExpired(dateString) {
                     v-if="item.registration_end && item.registration_end !== ''"
                   >
                     {{
-                      moment(`${item.registration_end}`).format(
-                        "YYYY/MM/DD H:mm"
-                      )
+                      moment(`${item.registration_end}`)
+                        .utcOffset(0)
+                        .format("YYYY/MM/DD HH:mm")
                     }}
                   </span>
                   <span v-else>無</span>
@@ -489,7 +499,7 @@ function isDateExpired(dateString) {
                   >
                     <template v-slot:activator="{ props }">
                       <v-btn
-                      v-if="isDateExpired(item.registration_end)"
+                        v-if="isDateExpired(item.registration_end)"
                         @click="signUp(index)"
                         v-bind="props"
                         text="報名"
@@ -498,11 +508,11 @@ function isDateExpired(dateString) {
                       >
                       </v-btn>
                       <v-btn
-                      v-else
+                        v-else
                         text="已截止"
                         rounded="xl"
                         color="brown"
-                       disabled
+                        disabled
                       >
                       </v-btn>
                     </template>
@@ -1162,7 +1172,7 @@ function isDateExpired(dateString) {
   }
 
   .sessions {
-    padding: 1.5em 1.5em .5em;
+    padding: 1.5em 1.5em 0.5em;
     letter-spacing: 0.1em;
     overflow-x: scroll;
     table {

+ 28 - 6
src/views/Courses/Create.vue

@@ -302,6 +302,14 @@ watch(eventType, (val) => {
   }
 });
 
+// 若為一日課程則起始日期 = 結束日期
+watch(date, (val) => {
+  if (isOneDay.value && val.start_date) {
+    date.end_date = val.start_date;
+  }
+});
+
+let dateReminder = ref(false);
 let eventData = reactive({
   list: [],
 });
@@ -323,6 +331,15 @@ let eventFieldValidate = ref(false); // 驗證場次欄位
 function addEventData() {
   // insertSession(); // 測試
   console.log("event", event);
+
+  let isSame = store.isSameDay(date.start_date, date.end_date);
+  // 起始日期不可等於結束日期(週期課程)
+  if (!isOneDay.value && isSame) {
+    dateReminder.value = true;
+    return;
+  }
+  dateReminder.value = false;
+
   eventForm.value.validate();
 
   // 檢查日期欄位
@@ -566,11 +583,6 @@ let sessionTime = reactive({
   end_week_time: [],
 });
 
-watch(sessionTime, (val) => {
-  console.log("sessionTime start_week_time", val.start_week_time);
-  console.log("sessionTime end_week_time", val.end_week_time);
-});
-
 let sessionStartTimeList = ref(["", "", "", "", "", "", ""]);
 let sessionEndTimeList = ref(["", "", "", "", "", "", ""]);
 
@@ -1962,7 +1974,11 @@ async function assignTeacher(item, index) {
                                       />
                                     </v-col>
 
-                                    <v-col cols="12" sm="6" class="date-item">
+                                    <v-col
+                                      cols="12"
+                                      sm="6"
+                                      class="date-item position-relative"
+                                    >
                                       <p class="mb-0 pe-3">
                                         結束日期<span class="mark">*</span>
                                       </p>
@@ -1972,7 +1988,13 @@ async function assignTeacher(item, index) {
                                         :enable-time-picker="false"
                                         :format="store.datePickerFormat"
                                         locale="cn"
+                                        :disabled="isOneDay"
                                       ></VueDatePicker>
+                                      <span
+                                        v-if="dateReminder"
+                                        class="date-reminder text-error"
+                                        >選擇週期課程時,起始日期與結束日期不可為同一天</span
+                                      >
                                     </v-col>
 
                                     <v-col cols="12" sm="6" class="date-item">

+ 1 - 1
src/views/Courses/SetUp.vue

@@ -202,7 +202,7 @@ onMounted(async () => {
 
 // Swiper
 .background-image {
-  background-image: url("@/assets/img/default.png");
+  background-image: url("@/assets/img/default.webp");
   width: 100%;
   height: 100%;
   position: absolute;

+ 9 - 8
src/views/Home.vue

@@ -251,7 +251,8 @@ async function getNews() {
   // 取得最新兩篇
   try {
     const response = await axios.get(
-      "https://cmm.ai:8088/api/get_news?page_num=1&page_amount=2"
+      `${store.apiUrl}/api/get_news?page_num=1&page_amount=2`
+      // "https://cmm.ai:8088/api/get_news?page_num=1&page_amount=2"
     );
     news.list = response.data.news;
     console.log("重要訊息(新聞)", news.list);
@@ -464,7 +465,7 @@ let closeBanner = ref(false);
       <v-col cols="6" md="4">
         <router-link to="/" class="img-info">
           <img
-            src="@/assets/img/home/首頁元素-12.png"
+            src="@/assets/img/home/首頁元素-12.webp"
             alt="臺灣工藝學校全球學習共享平台"
           />
           <section>
@@ -475,7 +476,7 @@ let closeBanner = ref(false);
       <v-col cols="6" md="4">
         <router-link to="/college-group/craft" class="img-info">
           <img
-            src="@/assets/img/home/首頁元素-11.png"
+            src="@/assets/img/home/首頁元素-11.webp"
             alt="臺灣工藝學校全球學習共享平台"
           />
           <section>
@@ -486,7 +487,7 @@ let closeBanner = ref(false);
       <v-col cols="6" md="4">
         <router-link to="/college-group/future" class="img-info">
           <img
-            src="@/assets/img/home/首頁元素-06.png"
+            src="@/assets/img/home/首頁元素-06.webp"
             alt="臺灣工藝學校全球學習共享平台"
           />
           <section>
@@ -497,7 +498,7 @@ let closeBanner = ref(false);
       <v-col cols="6" md="4">
         <router-link to="/college-group/cross" class="img-info">
           <img
-            src="@/assets/img/home/首頁元素-09.png"
+            src="@/assets/img/home/首頁元素-09.webp"
             alt="臺灣工藝學校全球學習共享平台"
           />
           <section>
@@ -519,7 +520,7 @@ let closeBanner = ref(false);
       <v-col cols="6" md="4">
         <router-link to="/college-group/life" class="img-info">
           <img
-            src="@/assets/img/home/首頁元素-07.png"
+            src="@/assets/img/home/首頁元素-07.webp"
             alt="臺灣工藝學校全球學習共享平台"
           />
           <section>
@@ -667,7 +668,7 @@ let closeBanner = ref(false);
                         item.is_inner === 0
                           ? item.cover_img
                           : item.special_class_list_name === 'one_day_class'
-                          ? store.getImageUrl('default.png')
+                          ? store.getImageUrl('default.webp')
                           : `https://ntcri.org/${item.cover_img}`
                       "
                       cover
@@ -675,7 +676,7 @@ let closeBanner = ref(false);
                         item.is_inner === 0
                           ? item.cover_img
                           : item.special_class_list_name === 'one_day_class'
-                          ? store.getImageUrl('default.png')
+                          ? store.getImageUrl('default.webp')
                           : `https://ntcri.org/${item.cover_img}`
                       "
                       alt="臺灣工藝學校全球學習共享平台"

+ 56 - 0
src/views/Login.vue

@@ -229,6 +229,32 @@ function toggleLoginInput() {
   console.log("showLogin");
   showLogin.value = !showLogin.value;
 }
+
+// let testAccount = ref("");
+
+async function testLogin() {
+  console.log("testLogin");
+  // window.location.href = "https://member.moc.gov.tw/MOCMC/T0001/list";
+
+  // let url = `http:// membertest.moc.gov.tw /MOCMC/T0001/list?SYS_ID=${testAccount.value}`;
+
+  let ott = "CRAFT_NTCRI";
+  let url = `http:// membertest.moc.gov.tw /MOCMC/T0001/list?SYS_ID=${ott}`;
+  console.log("url", url);
+
+  try {
+    const response = await axios.post(url);
+    console.log("測試登入", response);
+  } catch (error) {
+    console.error(error);
+  }
+}
+
+async function testLogin2() {
+  console.log("測試跳轉");
+  let ott = "CRAFT_NTCRI";
+  window.location.href = `http://membertest.moc.gov.tw/MOCMC/T0001/list?SYS_ID=${ott}`;
+}
 </script>
 
 <template>
@@ -282,6 +308,36 @@ function toggleLoginInput() {
           >
             使用平台帳號登入
           </v-btn>
+
+          <!-- <v-text-field
+            v-model="testAccount"
+            label="測試帳號"
+            prepend-inner-icon="mdi-account"
+            variant="solo"
+            density="compact"
+            hide-details
+            class="w-50 mt-5"
+          ></v-text-field> -->
+
+          <v-btn
+            @click="testLogin()"
+            class="login-btn"
+            variant="outlined"
+            color="gray"
+          >
+            登入測試
+          </v-btn>
+
+          <v-btn
+            @click="testLogin2()"
+            class="login-btn mb-10"
+            variant="outlined"
+            color="gray"
+          >
+            登入測試 2
+          </v-btn>
+
+          <a href="https://member.moc.gov.tw/MOCMC/A0001/list?SYS_ID=CRAFT_NTCRI">測試連結</a>
           <Transition>
             <v-form v-if="showLogin" @submit.prevent class="mt-7">
               <v-text-field

+ 1 - 1
src/views/News.vue

@@ -155,7 +155,7 @@ const categoryList = reactive([
       <div class="content py-10 mt-16">
         <div class="bg-img">
           <img
-            src="@/assets/img/news/news-02.png"
+            src="@/assets/img/news/news-bg.webp"
             alt="臺灣工藝學校全球學習共享平台"
           />
         </div>

+ 1 - 1
src/views/NewsDetail.vue

@@ -92,7 +92,7 @@ let loading = ref(false);
 <style lang="scss" scoped>
 .content {
   padding: 1.25em;
-  background-image: url("@/assets/img/news/news-02.png");
+  background-image: url("@/assets/img/news/news-bg.webp");
   background-position: center;
   background-size: cover;
   border-radius: 3.125em;

+ 16 - 30
src/views/User/Courses.vue

@@ -564,6 +564,10 @@ let date = reactive({
   registration_end_time: "", // 報名截止時間
 });
 
+watch(date, (val) => {
+  console.log("val", val);
+});
+
 // 取得場次(編輯)
 async function editEvent(id) {
   console.log("editEvent", id);
@@ -575,7 +579,7 @@ async function editEvent(id) {
     const response = await axios.get(url);
     const classes = response.data.classes[0];
     event.id = classes.event_id;
-    console.log("取得課程", response.data.classes);
+    console.log("取得課程 >>", response.data.classes);
 
     // 存入場次資料
     for (const key in classes) {
@@ -618,9 +622,9 @@ async function editEvent(id) {
 // 將時間字串轉為物件 (vue-datepicker格式)
 function dateToObject(dateString) {
   const date = new Date(dateString);
-  const hours = date.getHours();
-  const minutes = date.getMinutes();
-  const seconds = date.getSeconds();
+  const hours = date.getUTCHours();
+  const minutes = date.getUTCMinutes();
+  const seconds = date.getUTCSeconds();
 
   return { hours, minutes, seconds };
 }
@@ -802,24 +806,11 @@ async function updateSession() {
 
 let dateReminder = ref(false);
 
-// 判斷兩組日期是否相同
-function isSameDay(date1, date2) {
-  const year1 = date1.getFullYear();
-  const month1 = date1.getMonth() + 1;
-  const day1 = date1.getDate();
-
-  const year2 = date2.getFullYear();
-  const month2 = date2.getMonth() + 1;
-  const day2 = date2.getDate();
-
-  return `${year1}${month1}${day1}` === `${year2}${month2}${day2}`;
-}
-
 // 更新場次
 async function updateEvent() {
   console.log("date", date);
 
-  let isSame = isSameDay(date.start_date, date.end_date);
+  let isSame = store.isSameDay(date.start_date, date.end_date);
   // 起始日期不可等於結束日期(週期課程)
   if (!isOneDay.value && isSame) {
     dateReminder.value = true;
@@ -842,7 +833,10 @@ async function updateEvent() {
     date.registration_end_date,
     date.registration_end_time
   );
-
+  console.log("date.registration_start_date", date.registration_start_date);
+  console.log("date.registration_start_time", date.registration_start_time);
+  console.log("event.registration_start", event.registration_start);
+  console.log("event.registration_end", event.registration_end);
   console.log("event", event);
 
   let url = "https://cmm.ai:8088/api/update_event";
@@ -1233,8 +1227,8 @@ async function closeClass(id) {
             <th width="30%">名稱</th>
             <th>開課日期</th>
             <th width="20%">課程狀態</th>
-            <th>管理</th>
-            <th></th>
+            <th width="150px">管理</th>
+            <th width="100px"></th>
           </tr>
         </thead>
         <tbody>
@@ -2259,7 +2253,7 @@ async function closeClass(id) {
                       v-bind="props"
                       color="purple"
                       variant="flat"
-                      class="d-flex align-center mt-2"
+                      class="d-flex align-center mt-3"
                       :disabled="item.is_check === 2"
                     >
                       <!-- <v-icon
@@ -2608,12 +2602,4 @@ async function closeClass(id) {
     font-size: 0.8em;
   }
 }
-
-.date-reminder {
-  position: absolute;
-  bottom: -25px;
-  left: 100px;
-  font-size: 0.75em;
-  line-height: 1.2;
-}
 </style>

+ 2 - 2
src/views/User/Dashboard.vue

@@ -81,7 +81,7 @@ let items = [
   <Navbar />
   <v-container fluid class="pa-8 pa-sm-16 dashboard-container">
     <v-row>
-      <v-col cols="12" md="2">
+      <v-col cols="12" lg="2">
         <v-card class="pa-5">
           <div class="user-info">
             <div class="img">
@@ -116,7 +116,7 @@ let items = [
         </v-card>
       </v-col>
 
-      <v-col cols="12" md="10">
+      <v-col cols="12" lg="10">
         <router-view></router-view>
       </v-col>
     </v-row>

+ 1 - 0
src/views/User/FavoriteClass.vue

@@ -18,6 +18,7 @@ let token = store.token;
 async function getFavoriteClass() {
   try {
     const response = await axios.get(
+      // `${store.apiUrl}/api/get_favorite_class?access_token=${token}`
       `https://cmm.ai:8088/api/get_favorite_class?access_token=${token}`
     );
     console.log(

+ 82 - 11
src/views/User/Passport.vue

@@ -11,9 +11,18 @@ console.log("學習護照", store.token);
 let pageNum = ref(1); // 頁數(預設第一頁)
 let pageAmount = ref(5); // 每頁顯示筆數
 let totalPages = ref(1); // 總頁數
+let data = reactive({
+  list: [],
+});
 let register = reactive({
+  // 報名中課程
   list: [],
 });
+let records = reactive({
+  // 上課記錄
+  list: [],
+});
+let userId = store.profile.id;
 
 console.log("profile", store.profile);
 
@@ -22,6 +31,7 @@ async function getRegistration() {
     const response = await axios.get(
       `https://cmm.ai:8088/api/get_registration?access_token=${token}`
     );
+    data.list = response.data.registrations;
     register.list = response.data.registrations;
     console.log("報名資料", response.data.registrations);
   } catch (error) {
@@ -31,18 +41,38 @@ async function getRegistration() {
 
 getRegistration();
 
+async function getRecord() {
+  try {
+    const response = await axios.get(
+      `https://cmm.ai:8088/api/get_attend_record?user_id=${userId}`
+    );
+    records.list = response.data.attend_record_list;
+    console.log("上課紀錄", records.list);
+  } catch (error) {
+    console.error(error);
+  }
+}
+
+getRecord();
+
+function formatDateTime(inputDateTime) {
+  return inputDateTime.substring(0, 16);
+}
+
 let isCheck = ref(null);
-let assignTag = ref("all");
+let assignTag = ref("register");
 
 function selectTag(btn) {
   pageNum.value = 1;
 
-  if (btn === "all") {
+  if (btn === "register") {
     isCheck.value = null;
-    assignTag.value = "all";
+    assignTag.value = "register";
+    data.list = register.list;
   } else {
     isCheck.value = btn;
     assignTag.value = btn;
+    data.list = records.list;
   }
 
   // getClass();
@@ -133,8 +163,8 @@ function selectTag(btn) {
         <div class="d-flex flex-column flex-sm-row justify-center tab-btn mt-5">
           <v-btn
             variant="text"
-            @click="selectTag('all')"
-            :class="{ active: assignTag === 'all' }"
+            @click="selectTag('register')"
+            :class="{ active: assignTag === 'register' }"
           >
             報名中課程
           </v-btn>
@@ -150,7 +180,7 @@ function selectTag(btn) {
 
         <div class="main-table">
           <!-- <h6 class="table-title">報名中課程</h6> -->
-          <table>
+          <table v-if="assignTag === 'register'">
             <thead>
               <tr>
                 <th>報名日期</th>
@@ -161,22 +191,30 @@ function selectTag(btn) {
                 <!-- <th width="15%">繳款資訊</th> -->
               </tr>
             </thead>
-            <tbody v-if="register.list.length">
+            <tbody v-if="data.list.length">
               <!-- <tr v-if="!register.list.length">
                 <p class="hint-item">
                   目前沒有報名紀錄喔!點擊開始探索您的專屬課程!
                 </p>
               </tr> -->
-              <tr v-for="(item, index) in register.list" :key="index">
-                <td>
+              <tr v-for="(item, index) in data.list" :key="index">
+                <td v-if="item.create_time">
                   {{ moment(`${item.create_time}`).format("YYYY/MM/DD") }}
                 </td>
                 <td>{{ item.class_name }}</td>
                 <td>
-                  {{ moment(`${item.start_time}`).format("YYYY/MM/DD H:mm") }}
+                  {{
+                    moment(`${item.start_time}`)
+                      .utcOffset(0)
+                      .format("YYYY/MM/DD HH:mm")
+                  }}
                   <br />
                   ~ <br />
-                  {{ moment(`${item.end_time}`).format("YYYY/MM/DD H:mm") }}
+                  {{
+                    moment(`${item.end_time}`)
+                      .utcOffset(0)
+                      .format("YYYY/MM/DD HH:mm")
+                  }}
                 </td>
                 <td>{{ item.hours }} 小時</td>
                 <td>
@@ -202,6 +240,39 @@ function selectTag(btn) {
               </tr>
             </tbody>
           </table>
+
+          <table v-else>
+            <thead>
+              <tr>
+                <th>上課日期</th>
+                <th>上課時間</th>
+                <th>課程名稱</th>
+                <!-- <th width="110px">時數</th> -->
+                <!-- <th width="10%">報名狀態</th> -->
+                <!-- <th width="15%">繳款資訊</th> -->
+              </tr>
+            </thead>
+            <tbody v-if="data.list.length">
+              <!-- <tr v-if="!register.list.length">
+                <p class="hint-item">
+                  目前沒有報名紀錄喔!點擊開始探索您的專屬課程!
+                </p>
+              </tr> -->
+              <tr v-for="(item, index) in data.list" :key="index">
+                <td class="pa-7">
+                  {{ moment(`${item.start_time}`).format("YYYY/MM/DD") }}
+                </td>
+                <td>
+                  {{
+                    moment(`${item.start_time}`).utcOffset(0).format("HH:mm")
+                  }}
+                  —
+                  {{ moment(`${item.end_time}`).utcOffset(0).format("HH:mm") }}
+                </td>
+                <td>{{ item.class_name }}</td>
+              </tr>
+            </tbody>
+          </table>
         </div>
         <router-link
           v-if="!register.list.length"

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません