|
@@ -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>
|