SyuanYu 1 年之前
父節點
當前提交
ba1109ab56
共有 35 個文件被更改,包括 843 次插入54 次删除
  1. 30 0
      src/assets/css/style.css
  2. 0 0
      src/assets/css/style.css.map
  3. 33 0
      src/assets/css/style.scss
  4. 二進制
      src/assets/img/article/background.png
  5. 二進制
      src/assets/img/article/知識文章-05.png
  6. 二進制
      src/assets/img/article/知識文章-06.png
  7. 二進制
      src/assets/img/article/知識文章-07.png
  8. 二進制
      src/assets/img/article/知識文章-08.png
  9. 二進制
      src/assets/img/article/知識文章-09.png
  10. 二進制
      src/assets/img/article/知識文章-10.png
  11. 二進制
      src/assets/img/article/知識文章-14.png
  12. 二進制
      src/assets/img/article/知識文章-15.png
  13. 二進制
      src/assets/img/article/知識文章-16.png
  14. 二進制
      src/assets/img/article/知識文章-17.png
  15. 二進制
      src/assets/img/article/知識文章-18.png
  16. 二進制
      src/assets/img/article/知識文章-19.png
  17. 二進制
      src/assets/img/article/知識文章-20.png
  18. 二進制
      src/assets/img/article/知識文章-21.png
  19. 二進制
      src/assets/img/article/知識文章-22.png
  20. 二進制
      src/assets/img/article/知識文章-23.png
  21. 二進制
      src/assets/img/article/知識文章-24.png
  22. 1 1
      src/components/Navbar.vue
  23. 16 4
      src/components/PDFViewer.vue
  24. 12 0
      src/router/index.js
  25. 441 0
      src/views/Article.vue
  26. 196 0
      src/views/ArticleDetail.vue
  27. 22 2
      src/views/CollegeGroup/Craft.vue
  28. 1 3
      src/views/CollegeGroup/Cross.vue
  29. 1 2
      src/views/CollegeGroup/Future.vue
  30. 2 2
      src/views/CollegeGroup/Generation.vue
  31. 1 2
      src/views/CollegeGroup/Life.vue
  32. 42 8
      src/views/CollegeGroup/Repair.vue
  33. 1 2
      src/views/CollegeGroup/Teenager.vue
  34. 14 5
      src/views/CourseDetail.vue
  35. 30 23
      src/views/Home.vue

+ 30 - 0
src/assets/css/style.css

@@ -58,6 +58,10 @@ a {
   font-family: "Noto Sans TC", sans-serif;
 }
 
+html {
+  scroll-behavior: smooth;
+}
+
 input:focus-visible {
   outline: 2px solid var(--sub-color);
 }
@@ -284,4 +288,30 @@ input:focus-visible {
   left: 50%;
   transform: translate(-50%, -50%);
   z-index: 1000;
+}
+
+@media (max-width: 960px) {
+  .tag-btn {
+    margin: auto !important;
+    max-width: 300px;
+    flex-direction: column;
+  }
+}
+.tag-btn .item {
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  color: #bda2b5;
+  border: 1px solid #bda2b5;
+  border-radius: 20px;
+  text-align: center;
+  transition: all 0.3s;
+}
+.tag-btn .item:hover {
+  color: #bb8bad;
+  border-color: #bb8bad;
+}
+.tag-btn .item a {
+  width: 100%;
+  display: block;
 }/*# sourceMappingURL=style.css.map */

File diff suppressed because it is too large
+ 0 - 0
src/assets/css/style.css.map


+ 33 - 0
src/assets/css/style.scss

@@ -61,6 +61,10 @@ a {
   font-family: 'Noto Sans TC', sans-serif;
 }
 
+html {
+  scroll-behavior: smooth;
+}
+
 input:focus-visible {
   outline: 2px solid (var(--sub-color));
 }
@@ -297,4 +301,33 @@ input:focus-visible {
   left: 50%;
   transform: translate(-50%, -50%);
   z-index: 1000;
+}
+
+.tag-btn {
+  @media (max-width: 960px) {
+    margin: auto !important;
+    max-width: 300px;
+    flex-direction: column;
+  }
+
+  .item {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    color: #bda2b5;
+    border: 1px solid #bda2b5;
+    border-radius: 20px;
+    text-align: center;
+    transition: all .3s;
+
+    &:hover {
+      color: #bb8bad;
+      border-color: #bb8bad;
+    }
+
+    a {
+      width: 100%;
+      display: block;
+    }
+  }
 }

二進制
src/assets/img/article/background.png


二進制
src/assets/img/article/知識文章-05.png


二進制
src/assets/img/article/知識文章-06.png


二進制
src/assets/img/article/知識文章-07.png


二進制
src/assets/img/article/知識文章-08.png


二進制
src/assets/img/article/知識文章-09.png


二進制
src/assets/img/article/知識文章-10.png


二進制
src/assets/img/article/知識文章-14.png


二進制
src/assets/img/article/知識文章-15.png


二進制
src/assets/img/article/知識文章-16.png


二進制
src/assets/img/article/知識文章-17.png


二進制
src/assets/img/article/知識文章-18.png


二進制
src/assets/img/article/知識文章-19.png


二進制
src/assets/img/article/知識文章-20.png


二進制
src/assets/img/article/知識文章-21.png


二進制
src/assets/img/article/知識文章-22.png


二進制
src/assets/img/article/知識文章-23.png


二進制
src/assets/img/article/知識文章-24.png


+ 1 - 1
src/components/Navbar.vue

@@ -117,7 +117,7 @@ const collegeList = reactive([
         </div>
       </li>
       <li>
-        <router-link :to="'/'">知識文章</router-link>
+        <router-link :to="'/article'">知識文章</router-link>
       </li>
       <li>
         <!-- <router-link :to="'/login'">

+ 16 - 4
src/components/PDFViewer.vue

@@ -1,9 +1,21 @@
-<script setup></script>
+<script setup>
+import { ref, onMounted } from "vue";
+
+const isIOS = ref(false);
+
+// 判斷是否為 iOS
+onMounted(() => {
+  isIOS.value =
+    /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
+});
+</script>
 
 <template>
   <div>
+    <!-- iOS 顯示預設樣式 -->
     <iframe
-      src="../src/plugins/pdfjs-dist/web/viewer.html?file=/ntcri/pdf/2023ntcri.pdf"
+      v-if="isIOS"
+      src="/pdf/2023ntcri.pdf"
       width="100%"
       height="700px"
       frameborder="0"
@@ -11,9 +23,9 @@
       cellspacing="0"
     ></iframe>
 
-    <!-- iOS 顯示預設樣式 -->
     <iframe
-      src="/ntcri/pdf/2023ntcri.pdf"
+      v-else
+      src="../src/plugins/pdfjs-dist/web/viewer.html?file=/pdf/2023ntcri.pdf"
       width="100%"
       height="700px"
       frameborder="0"

+ 12 - 0
src/router/index.js

@@ -6,6 +6,8 @@ const Home = defineAsyncComponent(() => import('@/views/Home.vue'));
 const Login = defineAsyncComponent(() => import('@/views/Login.vue'));
 const News = defineAsyncComponent(() => import('@/views/News.vue'));
 const NewsDetail = defineAsyncComponent(() => import('@/views/NewsDetail.vue'));
+const Article = defineAsyncComponent(() => import('@/views/Article.vue'));
+const ArticleDetail = defineAsyncComponent(() => import('@/views/ArticleDetail.vue'));
 const CourseList = defineAsyncComponent(() => import('@/views/CourseList.vue'));
 const CourseDetail = defineAsyncComponent(() => import('@/views/CourseDetail.vue'));
 // 八大學群
@@ -134,6 +136,16 @@ const routes = [
     name: 'NewsDetail',
     component: NewsDetail
   },
+  {
+    path: '/article',
+    name: 'Article',
+    component: Article,
+  },
+  {
+    path: '/article/:id',
+    name: 'ArticleDetail',
+    component: ArticleDetail
+  },
   {
     path: '/course-list',
     name: 'CourseList',

+ 441 - 0
src/views/Article.vue

@@ -0,0 +1,441 @@
+<script setup>
+import { ref, reactive, watch, computed } from "vue";
+import { useMainStore } from "@/stores/store";
+import axios from "axios";
+import moment from "moment";
+import Navbar from "@/components/Navbar.vue";
+import PDFViewer from "@/components/PDFViewer.vue";
+
+const store = useMainStore();
+let searchInput = ref("");
+let searchError = ref(false);
+let currentPage = ref(1); // 當前頁數(預設第一頁)
+let itemsPerPage = ref(5); // 每頁顯示筆數
+let totalPages = ref(1); // 總頁數
+const newsAll = reactive({
+  list: [],
+});
+const newsData = reactive({
+  list: [],
+});
+
+(async function getData() {
+  try {
+    const response = await axios.get("https://cmm.ai:8088/api/get_news");
+    console.log("response", response.data.news);
+    newsAll.list = response.data.news;
+    newsData.list = response.data.news;
+    totalPages.value = store.getTotalPages(response.data.news.length, 5); // 計算頁數
+  } catch (error) {
+    console.error(error);
+  }
+})();
+
+// 搜尋
+async function search() {
+  searchError.value = false;
+  let keyword = searchInput.value;
+  if (keyword !== "") {
+    try {
+      const response = await axios.get(
+        `https://cmm.ai:8088/api/search_news_like?keyword=${keyword}`
+      );
+      if (response.data.news.length !== 0) {
+        newsData.list = response.data.news;
+      } else {
+        searchError.value = true;
+      }
+    } catch (error) {
+      console.error(error);
+    }
+  } else {
+    newsData.list = newsAll.list;
+  }
+}
+
+const searchLocation = ref(null);
+
+// 切換分頁時回到列表上方
+watch(currentPage, () => {
+  searchLocation.value.scrollIntoView({ behavior: "smooth", block: "start" });
+});
+
+// 分頁顯示
+const paginatedList = computed(() => {
+  const startIndex = (currentPage.value - 1) * itemsPerPage.value;
+  const endIndex = startIndex + itemsPerPage.value;
+  return newsData.list.slice(startIndex, endIndex);
+});
+
+const breadcrumbs = reactive([
+  {
+    title: "首頁",
+    disabled: false,
+    href: "/",
+  },
+  {
+    title: "知識文章",
+    disabled: true,
+    href: "/article",
+  },
+]);
+
+const tagList = reactive([
+  {
+    title: "工藝書單",
+    url: "",
+  },
+  {
+    title: "線上閱讀",
+    url: "",
+  },
+  {
+    title: "國際專欄",
+    url: "#articleList",
+  },
+  {
+    title: "工藝中心圖書館",
+    url: "https://ntcrilib.blogspot.com/",
+  },
+  {
+    title: "線上影音",
+    url: "",
+  },
+]);
+
+const articleList = reactive([
+  {
+    title: "法國工藝中心雜誌",
+    depiction: "CMA, artisans of the new economy_Magazin",
+    img: store.getImageUrl("article/知識文章-14.png"),
+    url: "https://www.artisanat.fr/magazine/actus",
+  },
+  {
+    title: "法國不同地區的工藝匠結合各地特色的作品",
+    depiction: "8 Skills of French Craftsmen",
+    img: store.getImageUrl("article/知識文章-15.png"),
+    url: "https://www.france.fr/zh-Hant/%E6%97%85%E9%81%8A%E7%9B%AE%E7%9A%84%E5%9C%B0/%E6%B8%85%E5%96%AE/ateliers-savoir-faire-francais-%E6%B3%95%E5%9C%8B%E8%83%BD%E5%B7%A5%E5%B7%A7%E5%8C%A0%E7%9A%84-8-%E9%A0%85%E6%8A%80%E8%97%9D",
+  },
+  {
+    title: "從古至今的里昂絲綢工藝演變",
+    depiction: "Approaching Lyon's silk",
+    img: store.getImageUrl("article/知識文章-16.png"),
+    url: "https://www.france.fr/zh-Hant/%E9%87%8C%E6%98%82/%E6%B8%85%E5%96%AE/experiences-soie-%E8%B5%B0%E8%BF%91%E9%87%8C%E6%98%82%E7%9A%84%E7%B5%B2%E7%B6%A2",
+  },
+  {
+    title: "義大利威尼斯琉璃工藝",
+    depiction: "Artisanat verrier vénitien",
+    img: store.getImageUrl("article/知識文章-17.png"),
+    url: "https://www.sightseeinginitaly.com/fr/le-nord-est-de-litalie/region-venetie/artisanat-de-la-venetie/verre-de-murano-technique-verriere-artisanale/",
+  },
+  {
+    title: "日本北海道小樽玻璃工藝",
+    depiction: "小樽ガラスの特徴|歴史ある有名工芸品の魅力を探る",
+    img: store.getImageUrl("article/知識文章-18.png"),
+    url: "https://chiikihyaku-jp.translate.goog/goods/734.html?_x_tr_sl=ja&_x_tr_tl=zh-TW&_x_tr_hl=zh-TW&_x_tr_pto=sc",
+  },
+  {
+    title: "日本漆藝介紹",
+    depiction: "GALLERY JAPAN",
+    img: store.getImageUrl("article/知識文章-19.png"),
+    url: "https://www-galleryjapan-com.translate.goog/locale/ja_JP/technique/urushiwork/?_x_tr_sl=ja&_x_tr_tl=zh-TW&_x_tr_hl=zh-TW&_x_tr_pto=sc",
+  },
+  {
+    title: "捷克木偶工藝",
+    depiction: "Puppetry",
+    img: store.getImageUrl("article/知識文章-20.png"),
+    url: "https://www.visitczechrepublic.com/en-US/ff6094fa-b99b-4bb5-9643-2f4d2d375710/place/c-unesco-puppetry",
+  },
+  {
+    title: "美國印地安人傳統工藝品介紹",
+    depiction: "Southwestern Arts and Crafts",
+    img: store.getImageUrl("article/知識文章-21.png"),
+    url: "https://www.desertusa.com/desert-people/indian-craft.html",
+  },
+]);
+
+const readList = reactive([
+  {
+    title: "陶廢X重生 <br> 永續設計如何翻轉陶廢",
+    depiction:
+      "How Sustainable Design Provides a New Perspective for Ceramic Scrap",
+    img: store.getImageUrl("article/知識文章-23.png"),
+    url: "https://www.artisanat.fr/magazine/actus",
+  },
+  {
+    title: "工藝製造現場 <br> 擾動,臺灣工藝、設計、工業與數位製造",
+    depiction:
+      "Taiwan crafts, design, and industrial and digital manufacturing",
+    img: store.getImageUrl("article/知識文章-24.png"),
+    url: "https://www.france.fr/zh-Hant/%E6%97%85%E9%81%8A%E7%9B%AE%E7%9A%84%E5%9C%B0/%E6%B8%85%E5%96%AE/ateliers-savoir-faire-francais-%E6%B3%95%E5%9C%8B%E8%83%BD%E5%B7%A5%E5%B7%A7%E5%8C%A0%E7%9A%84-8-%E9%A0%85%E6%8A%80%E8%97%9D",
+  },
+]);
+
+const bookList = reactive([
+  {
+    tag: "文章",
+    depiction:
+      "《生活工藝誌》2月號 <br>「雨水」過後,趁著陽光微露臉的閒暇, <br> 帶上《生活工藝誌》,找一片綠蔭, <br> 坐下來,迎著春光, <br> 好好地與自己對話:最珍視的是什麼? <br>《生活工藝誌》2月號上市!",
+    img: store.getImageUrl("article/知識文章-05.png"),
+  },
+  {
+    tag: "文章|影音",
+    depiction:
+      "全民竹起來 <br> 內容呈現「全民竹起來」系列工作坊主題,以多元趣味、輕鬆且生活化的主題引導大眾將與竹交會的良好經驗帶入自身生活,共創並延展全民對竹文化、竹產業的想像與可能,一系列精彩活動內容收入於此竹書內。",
+    img: store.getImageUrl("article/知識文章-06.png"),
+  },
+  {
+    tag: "文章",
+    depiction:
+      "職人之器-臺灣細木作手工具概覽職,是一種專業的態度 <br> 人,是人文的溫度,手作所注入之靈魂  <br> 器,是百善之先的概念 <br> 所有的作品、創作、設計都必須透過「器」對利與「人」之用",
+    img: store.getImageUrl("article/知識文章-07.png"),
+  },
+  {
+    tag: "文章",
+    depiction:
+      "纖維實踐─月桃 <br> 植物可以是一則故事,一個表徵。 <br> 植物可以是一種文化,也可以是一種生命或孕育生命的所在。 <br> 臺灣作為一座古老的生物島,生態種類豐富,尤其對於當地與自然資源交融的族群",
+    img: store.getImageUrl("article/知識文章-08.png"),
+  },
+  {
+    tag: "文章",
+    depiction:
+      "職人之器-臺灣細木作手工具概覽職,是一種專業的態度 <br> 人,是人文的溫度,手作所注入之靈魂  <br> 器,是百善之先的概念 <br> 所有的作品、創作、設計都必須透過「器」對利與「人」之用",
+    img: store.getImageUrl("article/知識文章-09.png"),
+  },
+  {
+    tag: "文章",
+    depiction:
+      "旅讀臺灣農村/社區工藝記 <br> 繞一圈臺灣,在日常中探索在地工藝 <br> 生活風景、時光故事 <br> 人情溫度、社區事物 <br> 感受臺灣土地力量,遇見工藝笑顏 <br> 刻劃15個工藝社區",
+    img: store.getImageUrl("article/知識文章-10.png"),
+  },
+]);
+
+function isAnchorLink(url) {
+  console.log("url", url, url.startsWith("#"));
+  // 檢查 URL 是否為錨點
+  return url.startsWith("#");
+}
+</script>
+
+<template>
+  <Navbar />
+  <div class="bg-img">
+    <v-container class="position-relative">
+      <!-- <img src="@/assets/img/article/background.png" alt="" class="bg-img" /> -->
+      <div class="article-content">
+        <v-breadcrumbs
+          :items="breadcrumbs"
+          divider="/"
+          class="my-5"
+        ></v-breadcrumbs>
+
+        <v-row class="px-10 pb-3 tag-btn">
+          <v-col
+            v-for="(item, index) in tagList"
+            :key="index"
+            class="ma-2 item"
+          >
+            <a
+              v-if="isAnchorLink(item.url)"
+              :href="item.url"
+              class="py-3 py-lg-6"
+            >
+              <!-- 錨點 -->
+              {{ item.title }}
+            </a>
+            <a v-else :href="item.url" target="_blank" class="py-3 py-lg-6">
+              <!-- 網址 -->
+              {{ item.title }}
+            </a>
+          </v-col>
+        </v-row>
+
+        <h2 id="articleList">國際專欄</h2>
+
+        <div class="search pt-5 mb-10 me-16" ref="searchLocation">
+          <span>
+            <input v-model="searchInput" type="text" @keyup.enter="search()" />
+            <button @click="search()">
+              <img src="@/assets/img/news/news-search-icon.png" alt="" />
+            </button>
+          </span>
+          <div
+            v-if="searchError"
+            class="d-flex justify-center align-center error me-4"
+          >
+            <v-icon color="primary" icon="mdi-alert" class="me-2"></v-icon>
+            沒有符合搜尋條件的項目
+          </div>
+        </div>
+
+        <v-row class="list">
+          <v-col
+            cols="12"
+            sm="6"
+            v-for="(item, index) in articleList"
+            :key="index"
+          >
+            <a :href="item.url" target="_blank">
+              <img :src="item.img" alt="" />
+            </a>
+            <section>
+              <p>{{ item.depiction }}</p>
+              <h3>{{ item.title }}</h3>
+            </section>
+          </v-col>
+        </v-row>
+
+        <h2>線上閱讀</h2>
+
+        <v-row class="align-center justify-center my-16 read-list">
+          <v-col
+            cols="12"
+            sm="6"
+            v-for="(item, index) in readList"
+            :key="index"
+            class="d-flex flex-column align-center px-3"
+          >
+            <a :href="item.url" target="_blank">
+              <img :src="item.img" alt="" />
+            </a>
+            <section>
+              <h3 v-html="item.title"></h3>
+              <p>{{ item.depiction }}</p>
+            </section>
+          </v-col>
+        </v-row>
+
+        <PDFViewer />
+
+        <h2>工藝書單</h2>
+
+        <div class="search pt-10 pb-5 me-16" ref="searchLocation ">
+          <span>
+            <input v-model="searchInput" type="text" @keyup.enter="search()" />
+            <button @click="search()">
+              <img src="@/assets/img/news/news-search-icon.png" alt="" />
+            </button>
+          </span>
+          <div
+            v-if="searchError"
+            class="d-flex justify-center align-center error me-4"
+          >
+            <v-icon color="primary" icon="mdi-alert" class="me-2"></v-icon>
+            沒有符合搜尋條件的項目
+          </div>
+        </div>
+
+        <v-row class="justify-center book-list">
+          <v-col
+            cols="12"
+            sm="10"
+            md="6"
+            v-for="(item, index) in bookList"
+            :key="index"
+            class="position-relative mt-10 mb-16 pb-16"
+          >
+            <a :href="item.url" target="_blank">
+              <img :src="item.img" alt="" />
+            </a>
+            <section class="info">
+              <p v-html="item.depiction"></p>
+              <span>{{ item.tag }}</span>
+            </section>
+          </v-col>
+        </v-row>
+
+        <!-- <v-pagination
+          v-model="currentPage"
+          class="my-4"
+          :length="totalPages"
+        ></v-pagination> -->
+      </div>
+    </v-container>
+  </div>
+</template>
+
+<style lang="scss" scoped>
+h2 {
+  padding-top: 100px;
+  font-size: 30px;
+  font-weight: 500;
+  text-align: center;
+}
+
+.bg-img {
+  background-image: url("@/assets/img/article/background.png");
+  background-size: cover;
+  background-position: top;
+  @media (max-width: 960px) {
+    background-size: contain;
+    background-repeat: repeat;
+  }
+}
+
+.list,
+.read-list,
+.book-list {
+  p {
+    margin-bottom: 10px;
+  }
+  h3,
+  p {
+    font-weight: 400;
+    text-align: center;
+    line-height: 30px;
+  }
+}
+
+.read-list {
+  img {
+    width: 100%;
+    height: 500px;
+    max-width: 400px;
+    object-fit: cover;
+    @media (max-width: 960px) {
+      height: 40vw;
+    }
+  }
+
+  p {
+    width: 290px;
+  }
+}
+
+.book-list {
+  margin-bottom: 300px;
+  .info {
+    width: 430px;
+    padding: 10px 20px;
+    position: absolute;
+    right: -40px;
+    bottom: -60px;
+    z-index: 1;
+    background: #fff;
+    border: 2px solid #c8cbcc;
+
+    @media (max-width: 1280px) {
+      width: 400px;
+    }
+
+    @media (max-width: 600px) {
+      width: 330px;
+      right: -3px;
+      bottom: -100px;
+    }
+
+    p {
+      width: 300px;
+      margin-bottom: 0;
+      text-align: start;
+    }
+    span {
+      display: block;
+      margin-top: auto;
+      position: absolute;
+      bottom: 15px;
+      right: 15px;
+    }
+  }
+}
+</style>

+ 196 - 0
src/views/ArticleDetail.vue

@@ -0,0 +1,196 @@
+<script setup>
+import { reactive } from "vue";
+import { useRoute } from "vue-router";
+import axios from "axios";
+import moment from "moment";
+import Navbar from "@/components/Navbar.vue";
+
+const route = useRoute();
+const articleId = route.params.id; // 網址參數
+const news = reactive({
+  data: [],
+});
+
+(async function getData() {
+  try {
+    const response = await axios.get(
+      `https://cmm.ai:8088/api/get_article?article_id=${articleId}&group_id=${newsId}`
+    );
+    // news.data = response.data.news[0];
+    console.log("article.data", response);
+  } catch (error) {
+    console.error(error);
+  }
+})();
+</script>
+
+<template>
+  <Navbar />
+  <div class="position-relative">
+    <img src="@/assets/img/news/news-01.png" alt="" class="material-img" />
+    <v-container class="pa-0 pt-16 position-relative">
+      <!-- <img
+        src="@/assets/img/news/news-detail-banner.png"
+        alt=""
+        class="bg-img"
+      /> -->
+
+      <div class="content">
+        <div class="article">
+          <v-row>
+            <v-col cols="12">
+              <div class="d-flex align-center mb-5">
+                <v-chip size="large" variant="elevated" class="px-8 me-3">
+                  {{ news.data.category }}
+                </v-chip>
+                <p>
+                  {{ moment(`${news.data.create_time}`).format("YYYY.MM.DD") }}
+                </p>
+              </div>
+              <h2>【{{ news.data.title }}】</h2>
+              <img src="@/assets/img/img-04.jpg" alt="" class="cover-img" />
+              <!-- <img :src="`https://cmm.ai/ntcri/${news.data.cover_img}`" alt="" /> -->
+            </v-col>
+            <v-col cols="12">
+              <section class="d-flex flex-column pa-0">
+                <p v-html="news.data.content"></p>
+
+                <div class="btn-block mt-10">
+                <v-btn rounded="xl" color="grey-darken-2" class="px-7">
+                  檔案下載
+                </v-btn>
+                <v-btn rounded="xl" color="grey-darken-2" class="px-7 ms-3">
+                  前往連結
+                </v-btn>
+              </div>
+              </section>
+            </v-col>
+          </v-row>
+        </div>
+      </div>
+    </v-container>
+    <router-link to="/news" class="mt-16 back-link"
+      >< 返回重要訊息</router-link
+    >
+    <img src="@/assets/img/news/news-01.png" alt="" class="material-img" />
+  </div>
+</template>
+
+<style lang="scss" scoped>
+.btn-block {
+  display: flex;
+  justify-content: end;
+  // position: absolute;
+  // bottom: 80px;
+  // right: 180px;
+  // @media (max-width: 600px) {
+  //   bottom: 65px;
+  //   right: unset;
+  //   width: 100%;
+  //   display: flex;
+  //   justify-content: center;
+  // }
+}
+
+.content {
+  padding: 20px;
+  background-image: url("@/assets/img/news/news-02.png");
+  background-position: center;
+  background-size: cover;
+  border-radius: 50px;
+}
+.article {
+  // position: absolute;
+  // right: 0;
+  // left: 0;
+  // top: 75px;
+  // height: 780px;
+  // overflow-y: scroll;
+  // overflow-x: hidden;
+  margin: auto;
+  padding: 80px 50px;
+  display: flex;
+  justify-content: center;
+  border: 1px solid #d4d6d8;
+  border-radius: 50px;
+
+  // background-image: url('@/assets/img/news/news-detail-banner.png');
+  // background-position: center;
+  // background-size: cover;
+
+  @media (max-width: 960px) {
+    width: 80%;
+  }
+
+  @media (max-width: 600px) {
+    top: 55px;
+    height: 470px;
+    padding-top: 10px;
+  }
+
+  h2 {
+    margin: 40px auto;
+    font-size: 28px;
+    font-weight: 500;
+    line-height: 38px;
+    letter-spacing: 2px;
+  }
+  section {
+    height: 100%;
+    padding: 30px;
+    p {
+      // padding: 20px;
+      // margin-bottom: 20px;
+      font-size: 18px;
+      font-weight: 400;
+      line-height: 32px;
+      letter-spacing: 1px;
+    }
+  }
+
+  .cover-img {
+    width: 100%;
+    height: 500px;
+    object-fit: cover;
+    @media (max-width: 600px) {
+      height: auto;
+    }
+  }
+}
+.bg-img {
+  height: 1000px;
+  position: relative;
+  z-index: -1;
+  @media (max-width: 600px) {
+    height: 650px;
+  }
+}
+
+.back-link {
+  display: block;
+  text-align: center;
+  transition: all 0.3s;
+  letter-spacing: 1px;
+
+  &:hover {
+    opacity: 0.8;
+  }
+}
+.material-img {
+  position: absolute;
+
+  &:first-child {
+    top: -15vw;
+  }
+
+  &:last-child {
+    bottom: -150px;
+    z-index: -5;
+    transform: scaleX(-1);
+
+    @media (max-width: 600px) {
+      bottom: -50px;
+    }
+  }
+}
+</style>

+ 22 - 2
src/views/CollegeGroup/Craft.vue

@@ -14,8 +14,7 @@ const breadcrumbs = reactive([
   },
   {
     title: "工藝學群",
-    disabled: false,
-    href: "/ntcri/college-group/craft",
+    disabled: true,
   },
   {
     title: "技藝工藝",
@@ -45,6 +44,27 @@ const testData = [
     address: "地方工藝館 工藝教室",
     img: store.getImageUrl("college-group/img.jpg"),
   },
+  {
+    title: "種子教師研習",
+    start_time: "2023/06/15",
+    end_time: "2023/06/20",
+    address: "地方工藝館 工藝教室",
+    img: store.getImageUrl("college-group/img.jpg"),
+  },
+  {
+    title: "種子教師研習",
+    start_time: "2023/06/15",
+    end_time: "2023/06/20",
+    address: "地方工藝館 工藝教室",
+    img: store.getImageUrl("college-group/img.jpg"),
+  },
+  {
+    title: "種子教師研習",
+    start_time: "2023/06/15",
+    end_time: "2023/06/20",
+    address: "地方工藝館 工藝教室",
+    img: store.getImageUrl("college-group/img.jpg"),
+  },
 ];
 </script>
 

+ 1 - 3
src/views/CollegeGroup/Cross.vue

@@ -6,7 +6,6 @@ import { useMainStore } from "@/stores/store";
 
 const store = useMainStore();
 
-
 const breadcrumbs = reactive([
   {
     title: "首頁",
@@ -15,8 +14,7 @@ const breadcrumbs = reactive([
   },
   {
     title: "工藝學群",
-    disabled: false,
-    href: "/ntcri/college-group/craft",
+    disabled: true,
   },
   {
     title: "跨域工藝",

+ 1 - 2
src/views/CollegeGroup/Future.vue

@@ -14,8 +14,7 @@ const breadcrumbs = reactive([
   },
   {
     title: "工藝學群",
-    disabled: false,
-    href: "/ntcri/college-group/craft",
+    disabled: true,
   },
   {
     title: "未來工藝",

+ 2 - 2
src/views/CollegeGroup/Generation.vue

@@ -55,8 +55,7 @@ const breadcrumbs = reactive([
   },
   {
     title: "工藝學群",
-    disabled: false,
-    href: "/ntcri/college-group/craft",
+    disabled: true,
   },
   {
     title: "世代工藝",
@@ -94,6 +93,7 @@ const breadcrumbs = reactive([
 .v-row {
   padding-bottom: 30px;
 }
+
 h3,
 h4 {
   font-weight: 400;

+ 1 - 2
src/views/CollegeGroup/Life.vue

@@ -13,8 +13,7 @@ const breadcrumbs = reactive([
   },
   {
     title: "工藝學群",
-    disabled: false,
-    href: "/ntcri/college-group/craft",
+    disabled: true,
   },
   {
     title: "生活工藝",

+ 42 - 8
src/views/CollegeGroup/Repair.vue

@@ -1,11 +1,34 @@
 <script setup>
 import { ref, reactive } from "vue";
-import moment from "moment";
-import Navbar from "@/components/Navbar.vue";
 import { useMainStore } from "@/stores/store";
+import axios from "axios";
+import moment from "moment";
 
 const store = useMainStore();
 
+const articles = reactive({
+  list: [],
+});
+
+(async () => {
+  let url = `https://cmm.ai:8088/api/get_group_classes_and_articles?group_id=6`;
+
+  try {
+    const response = await axios.get(url);
+    articles.list = response.data.articles;
+    console.log("修護 response", response);
+    console.log("articles.list", articles.list);
+  } catch (error) {
+    console.error(error);
+  }
+})();
+
+// 定義過濾器函數
+const removeImages = (value) => {
+  // 使用正則表達式刪除圖片標籤
+  return value.replace(/<img\b[^>]*>/gi, "");
+};
+
 const breadcrumbs = reactive([
   {
     title: "首頁",
@@ -14,8 +37,7 @@ const breadcrumbs = reactive([
   },
   {
     title: "工藝學群",
-    disabled: false,
-    href: "/ntcri/college-group/craft",
+    disabled: true,
   },
   {
     title: "修護工藝",
@@ -227,10 +249,10 @@ const testData_2 = [
   <h2 class="mt-16 mb-10">修護故事</h2>
 
   <ul class="story-list">
-    <li v-for="(item, index) in testData_2" :key="index" class="mb-5">
+    <li v-for="(item, index) in articles.list" :key="index" class="mb-5">
       <section class="d-flex">
         <p class="mx-3 my-5 date">
-          {{ moment(`${item.start_time}`).format("YYYY-MM-DD") }}
+          {{ moment(`${item.create_time}`).format("YYYY-MM-DD") }}
         </p>
       </section>
       <v-card
@@ -245,8 +267,10 @@ const testData_2 = [
           </v-col>
           <v-col cols="12" sm="7" md="9">
             <section class="d-flex flex-column py-5 py-md-0">
-              <h2 class="mb-8">{{ item.title }}</h2>
-              <p v-html="item.describe"></p>
+              <router-link :to="`/news/${item.news_id}`" class="cover-img">
+                <h2 class="mb-8">{{ item.title }}</h2>
+              </router-link>
+              <p v-html="removeImages(item.content)"></p>
             </section>
           </v-col>
         </v-row>
@@ -333,6 +357,16 @@ p {
       max-width: 100%;
     }
   }
+  p {
+    // 超過兩行則省略
+    overflow: hidden;
+    text-overflow: ellipsis;
+    display: -webkit-box;
+    -webkit-line-clamp: 4;
+    -webkit-box-orient: vertical;
+    line-break: after-white-space;
+  }
+
   .date {
     font-size: 20px;
     font-weight: 400;

+ 1 - 2
src/views/CollegeGroup/Teenager.vue

@@ -11,8 +11,7 @@ const breadcrumbs = reactive([
   },
   {
     title: "工藝學群",
-    disabled: false,
-    href: "/ntcri/college-group/craft",
+    disabled: true,
   },
   {
     title: "青年工藝",

+ 14 - 5
src/views/CourseDetail.vue

@@ -22,7 +22,7 @@ const breadcrumbs = reactive([
   {
     title: "探索課程",
     disabled: false,
-    href: "/ntcri/course-list",
+    href: "/course-list",
   },
   {
     title: "課程清單",
@@ -127,12 +127,20 @@ const dynamicCols = computed(() => {
     ></v-breadcrumbs>
     <v-row class="justify-center">
       <v-col cols="3" class="title pa-0">
-        <img src="@/assets/img/course/detail-background.png" alt="" class="bg-img" />
+        <img
+          src="@/assets/img/course/detail-background.png"
+          alt=""
+          class="bg-img"
+        />
         <h2>{{ course.data.name }}</h2>
       </v-col>
       <v-col :cols="dynamicCols" class="pa-0 d-flex justify-center">
         <img
-          :src="course.data.cover_img"
+          :src="
+            groupSort === 'pinkoi'
+              ? course.data.cover_img
+              : `https://ntcri.org/${course.data.cover_img}`
+          "
           alt=""
           class="cover-img"
           :class="{ small: groupSort === 'pinkoi' }"
@@ -268,8 +276,9 @@ const dynamicCols = computed(() => {
 <style lang="scss">
 .course-detail {
   .cover-img {
-    width: 100%;
-    height: 500px;
+    // width: 100%;
+    height: 100%;
+    max-height: 400px;
     object-fit: cover;
     &.small {
       width: auto;

+ 30 - 23
src/views/Home.vue

@@ -154,12 +154,12 @@ const getClassList = async (locationId) => {
     <div class="map-block">
       <h3 class="mb-10 title">全台工藝地圖</h3>
       <div class="v-row">
-        <v-col md="7" cols="12">
+        <v-col md="8" cols="12">
           <div class="map">
             <Map @locationId="getClassList" />
           </div>
         </v-col>
-        <v-col md="5" cols="12">
+        <v-col md="4" cols="12">
           <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">
@@ -167,11 +167,7 @@ const getClassList = async (locationId) => {
                   :to="`/course-detail/${item.class_name_id}`"
                   class="link"
                 >
-                <v-img
-                    :lazy-src="item.cover_img"
-                    cover
-                    :src="item.cover_img"
-                  >
+                  <v-img :lazy-src="item.cover_img" cover :src="item.cover_img">
                     <template v-slot:placeholder>
                       <div
                         class="d-flex align-center justify-center fill-height"
@@ -280,13 +276,15 @@ const getClassList = async (locationId) => {
 
   .list {
     .link {
-      min-width: 180px;
+      // min-width: 180px;
+      width: 40%;
       margin-right: 20px;
       border-radius: 5px;
       overflow: hidden;
       .v-img {
         // width: 100%;
-        height: 175px;
+        // height: 175px;
+        width: 200px;
         margin-right: 20px;
         border-radius: 5px;
         box-shadow: 2px 2px 4px #aaaaaa;
@@ -298,21 +296,30 @@ const getClassList = async (locationId) => {
       }
     }
 
-    h2 {
-      font-size: 18px;
-      margin-bottom: 20px;
-    }
+    section {
+      width: 60%;
 
-    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;
+      h2 {
+        font-size: 16px;
+        font-weight: 600;
+        margin-bottom: 10px;
+      }
+
+      p {
+        font-size: 14px;
+      }
+
+      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;
+      }
     }
 
     .v-list-item {

Some files were not shown because too many files changed in this diff