新增产品列表 详情
This commit is contained in:
parent
90b957d261
commit
929253ffd2
@ -49,19 +49,10 @@
|
|||||||
{{ locale == 'zh' ? web_site_cate.biaoti7 : web_site_cate.biaoti7_en }}
|
{{ locale == 'zh' ? web_site_cate.biaoti7 : web_site_cate.biaoti7_en }}
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</li>
|
</li>
|
||||||
<li class="products">
|
<li>
|
||||||
<NuxtLink>{{ locale == 'zh' ? web_site_cate.biaoti5 : web_site_cate.biaoti5_en }}</NuxtLink>
|
<NuxtLink to="/index_products/" :class="{ 'active': route.path === '/index_products/' }">
|
||||||
<ul class="products_list">
|
{{ locale == 'zh' ? web_site_cate.biaoti5 : web_site_cate.biaoti5_en }}
|
||||||
<li><NuxtLink to="/index_product_f/" :class="{ 'active': route.path === '/index_product_f/' }">
|
</NuxtLink>
|
||||||
{{ locale == 'zh' ? top_two.home_two_left_title : top_two.en_home_two_left_title }}
|
|
||||||
</NuxtLink></li>
|
|
||||||
<li><NuxtLink to="/index_product_s/" :class="{ 'active': route.path === '/index_product_s/' }">
|
|
||||||
{{ locale == 'zh' ? top_two.home_two_center_title : top_two.en_home_two_center_title }}
|
|
||||||
</NuxtLink></li>
|
|
||||||
<li><NuxtLink to="/index_product_t/" :class="{ 'active': route.path === '/index_product_t/' }">
|
|
||||||
{{ locale == 'zh' ? top_two.home_two_right_title : top_two.en_home_two_right_title }}
|
|
||||||
</NuxtLink></li>
|
|
||||||
</ul>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -106,6 +97,11 @@
|
|||||||
{{ $t('index_contact') }}
|
{{ $t('index_contact') }}
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="py-2">
|
||||||
|
<NuxtLink to="/index_products/" :class="{ 'active': route.path === '/index_products/' }" @click="closeMenu">
|
||||||
|
{{ $t('index_products') }}
|
||||||
|
</NuxtLink>
|
||||||
|
</li>
|
||||||
<li class="py-3 flex space-x-4">
|
<li class="py-3 flex space-x-4">
|
||||||
<span @click="changeLanguage('zh')" class="cursor-pointer">中文版</span>
|
<span @click="changeLanguage('zh')" class="cursor-pointer">中文版</span>
|
||||||
<span @click="changeLanguage('en')" class="cursor-pointer">English</span>
|
<span @click="changeLanguage('en')" class="cursor-pointer">English</span>
|
||||||
|
@ -36,8 +36,8 @@
|
|||||||
<div class="clientxiah1 w-full h-[1px] bg-gray-200 my-8"></div>
|
<div class="clientxiah1 w-full h-[1px] bg-gray-200 my-8"></div>
|
||||||
<div class="mt-8">
|
<div class="mt-8">
|
||||||
<!-- 使用 Swiper 实现左右滚动 -->
|
<!-- 使用 Swiper 实现左右滚动 -->
|
||||||
<swiper
|
<Swiper
|
||||||
:modules="[SwiperAutoplay]"
|
:modules="[SwiperAutoplay,SwiperThumbs]"
|
||||||
:slides-per-view="slidesPerView"
|
:slides-per-view="slidesPerView"
|
||||||
:loop="true"
|
:loop="true"
|
||||||
:autoplay="{
|
:autoplay="{
|
||||||
@ -49,7 +49,7 @@
|
|||||||
<swiper-slide v-for="item in list" :key="item.id" class="flex justify-center">
|
<swiper-slide v-for="item in list" :key="item.id" class="flex justify-center">
|
||||||
<img @click="info = item" :src="item.image" class="w-[150px] md:w-[200px] h-auto cursor-pointer" alt="Client">
|
<img @click="info = item" :src="item.image" class="w-[150px] md:w-[200px] h-auto cursor-pointer" alt="Client">
|
||||||
</swiper-slide>
|
</swiper-slide>
|
||||||
</swiper>
|
</Swiper>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -64,7 +64,7 @@ import { useI18n } from 'vue-i18n'
|
|||||||
import { useStore } from '~/store'
|
import { useStore } from '~/store'
|
||||||
// 导入 Swiper 相关模块
|
// 导入 Swiper 相关模块
|
||||||
import { Swiper, SwiperSlide } from 'swiper/vue'
|
import { Swiper, SwiperSlide } from 'swiper/vue'
|
||||||
import { Navigation, Pagination, Autoplay } from 'swiper/modules'
|
import { Navigation, Pagination, Autoplay,Thumbs } from 'swiper/modules'
|
||||||
import 'swiper/css'
|
import 'swiper/css'
|
||||||
import 'swiper/css/navigation'
|
import 'swiper/css/navigation'
|
||||||
import 'swiper/css/pagination'
|
import 'swiper/css/pagination'
|
||||||
@ -76,6 +76,7 @@ const { locale } = useI18n()
|
|||||||
const SwiperNavigation = Navigation
|
const SwiperNavigation = Navigation
|
||||||
const SwiperPagination = Pagination
|
const SwiperPagination = Pagination
|
||||||
const SwiperAutoplay = Autoplay
|
const SwiperAutoplay = Autoplay
|
||||||
|
const SwiperThumbs = Thumbs
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getList();
|
getList();
|
||||||
|
@ -1,354 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="bg-white">
|
|
||||||
<!-- Banner section with background image -->
|
|
||||||
<div class="aboutimgBg">
|
|
||||||
<div class="pl-4 md:pl-[200px]">
|
|
||||||
<div class="newsTit">
|
|
||||||
<h2 class="animated fadeInLeft text-2xl md:text-[40px] font-bold">{{ $t('list_p1') }}</h2>
|
|
||||||
<h3 class="animated fadeInLeft text-lg md:text-[25px] font-medium mt-3 md:mt-[30px] text-[#606060]">{{ $t('list_p2') }}</h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Featured news section -->
|
|
||||||
<div class="newsBox1 container mx-auto px-4 py-8 flex flex-col md:flex-row flex-wrap" v-if="newsList.length > 0">
|
|
||||||
<div class="newsBox1lider w-full md:w-[38%] mb-6 md:mb-0">
|
|
||||||
<img id="featuredImage" :src="topImg" class="h-[200px] md:h-[300px] w-full object-cover rounded-[5px]" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="newsTit1 w-full md:w-[62%] relative pl-0 md:pl-4 mt-6 md:mt-0">
|
|
||||||
<div id="swipen_next" class="absolute left-0 md:left-4 top-[70%] -translate-y-1/2 cursor-pointer z-10" @click="prevSlide">
|
|
||||||
<img src="/images/group10.png" class="w-[40px] md:w-[50px]" alt="Previous" />
|
|
||||||
</div>
|
|
||||||
<div id="swipen_prev" class="absolute right-0 md:right-4 top-[70%] -translate-y-1/2 cursor-pointer z-10" @click="nextSlide">
|
|
||||||
<img src="/images/group9-1.png" class="w-[40px] md:w-[50px]" alt="Next" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex justify-end items-center mb-4">
|
|
||||||
<div class="relative pr-3 md:pr-5">
|
|
||||||
<h2 class="t7 m-0">
|
|
||||||
<span id="time1" class="newsSpan1 text-2xl md:text-[40px]">{{ formatYear(currentNews.inputtime || currentNews.add_time) }}/</span>
|
|
||||||
<span id="time2" class="newsSpan2 text-xl md:text-[28px]">{{ formatDate(currentNews.inputtime || currentNews.add_time) }}</span>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div class="text-right">
|
|
||||||
<span class="t6 text-lg md:text-[25px] font-semibold">{{ $t('list_p1') }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="newsdi w-full h-[1px] bg-gray-300 my-3 md:my-4"></div>
|
|
||||||
|
|
||||||
<div class="listSwiper overflow-hidden w-full md:w-[90%] h-[115px] md:h-[200px]">
|
|
||||||
<div class="swiper-wrapper w-full">
|
|
||||||
<span v-if="!isMobile" class="newsbs2 hidden md:inline-block"></span>
|
|
||||||
<div v-for="(news, index) in newsList" :key="index"
|
|
||||||
:class="['swiper-slide pl-[50px] pr-[40px] md:pl-[118px] pt-3 md:pt-[20px]', {'hidden': currentIndex !== index}]">
|
|
||||||
<h2 class="text-xl md:text-3xl font-bold mb-3 md:mb-4 line-clamp-1">
|
|
||||||
<NuxtLink :to="'/info/' + news.id" target="_blank" class="text-[#0c1923] hover:text-blue-600">
|
|
||||||
{{ getCurrentLanguage() === 'zh' ? news.title : news.en_title || news.title }}
|
|
||||||
</NuxtLink>
|
|
||||||
</h2>
|
|
||||||
<h3 class="line-clamp-2 text-gray-600 text-base md:text-lg mb-4 md:mb-6">
|
|
||||||
{{ getCurrentLanguage() === 'zh' ? news.synopsis : news.en_synopsis || news.synopsis }}
|
|
||||||
</h3>
|
|
||||||
<h4 v-if="!isMobile" class="mt-6 md:mt-10">
|
|
||||||
<NuxtLink :to="'/info/' + news.id" target="_blank"
|
|
||||||
class="text-[#0c1923] px-4 py-1 md:px-5 md:py-2.5 text-sm md:text-base rounded-[10px] border border-solid border-[#0c1923] hover:bg-gray-100">
|
|
||||||
{{ $t('list_b3') }}
|
|
||||||
</NuxtLink>
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- News list section -->
|
|
||||||
<div class="container mx-auto px-4 py-8 md:py-12">
|
|
||||||
<div v-for="(news, index) in allNewsList" :key="'all-'+index" class="newsBox2 min-h-[200px] md:min-h-[300px] h-auto md:h-[300px] flex flex-col md:flex-row flex-wrap items-start md:items-center p-4 md:p-[20px] mb-8 md:mb-12 border-b border-gray-200">
|
|
||||||
<NuxtLink :to="'/info/' + news.id" target="_blank" class="text-[#0c1923] hover:text-blue-600 md:h-[300px] flex md:p-[20px]">
|
|
||||||
<div class="newsTit2 w-full md:w-2/3 pr-0 md:pr-6 mb-4 md:mb-0">
|
|
||||||
<h2>
|
|
||||||
<span class="newsSpan1 text-2xl md:text-[40px]">{{ formatYear(news.add_time) }}/</span>
|
|
||||||
<span class="newsSpan2 text-xl md:text-[28px]">{{ formatDate(news.add_time) }}</span>
|
|
||||||
</h2>
|
|
||||||
<div class="newsBox2di w-full md:w-[473px]"></div>
|
|
||||||
<h3 class="text-xl md:text-2xl font-bold mb-2 md:mb-4 pt-3 md:pt-[20px] line-clamp-1">
|
|
||||||
|
|
||||||
{{ getCurrentLanguage() == 'zh' ? news.title : (news.en_title || news.title) }}
|
|
||||||
|
|
||||||
</h3>
|
|
||||||
<h4 class="text-gray-600 text-base md:text-lg line-clamp-2">
|
|
||||||
{{ getCurrentLanguage() == 'zh' ? news.synopsis : (news.en_synopsis || news.synopsis) }}
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
<img :src="news.image_input[0]" class="news2g10 w-full md:w-1/3 h-[200px] md:h-full object-cover rounded-lg" alt="News thumbnail" />
|
|
||||||
</NuxtLink>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Pagination -->
|
|
||||||
<div id="pages" class="text-center mt-6 md:mt-8">
|
|
||||||
<button
|
|
||||||
v-for="page in totalPages"
|
|
||||||
:key="page"
|
|
||||||
@click="changePage(page)"
|
|
||||||
:class="['mx-1 px-3 py-1 md:px-4 md:py-2 text-sm md:text-base rounded', currentPage === page ? 'bg-blue-500 text-white' : 'bg-gray-200 hover:bg-gray-300']">
|
|
||||||
{{ page }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ref, computed, onMounted } from 'vue'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
import $api from '@/service/webRequest'
|
|
||||||
|
|
||||||
// 分页相关变量
|
|
||||||
const currentPage = ref(1)
|
|
||||||
const itemsPerPage = 5
|
|
||||||
const totalItems = ref(0)
|
|
||||||
|
|
||||||
// 新闻数据
|
|
||||||
const mockNewsData = ref([])
|
|
||||||
const allNewsList = ref([])
|
|
||||||
const isMobile = ref(false)
|
|
||||||
onMounted(() => {
|
|
||||||
isMobile.value = window.innerWidth < 768
|
|
||||||
getNewsList()
|
|
||||||
getFeaturedNews()
|
|
||||||
})
|
|
||||||
|
|
||||||
const topImg = ref('')
|
|
||||||
// 获取轮播展示的新闻(前5条)
|
|
||||||
const getFeaturedNews = () => {
|
|
||||||
$api.get("/api/article/list/8", { params: { page: 1, limit: 5 } })
|
|
||||||
.then((res: any) => {
|
|
||||||
mockNewsData.value = res.data.data.list
|
|
||||||
topImg.value = res.data.data.list[0].image_input[0]
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.error("获取轮播新闻失败:", err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取分页新闻列表
|
|
||||||
const getNewsList = () => {
|
|
||||||
$api.get("/api/article/list/8", { params: { page: currentPage.value, limit: itemsPerPage } })
|
|
||||||
.then((res: any) => {
|
|
||||||
allNewsList.value = res.data.data.list
|
|
||||||
// 获取总条数用于分页
|
|
||||||
totalItems.value = res.data.data.count
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.error("获取新闻列表失败:", err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const { locale } = useI18n()
|
|
||||||
const currentIndex = ref(0)
|
|
||||||
|
|
||||||
// 轮播新闻列表
|
|
||||||
const newsList = computed(() => mockNewsData.value)
|
|
||||||
|
|
||||||
// 计算总页数
|
|
||||||
const totalPages = computed(() => Math.ceil(totalItems.value / itemsPerPage))
|
|
||||||
|
|
||||||
// 当前轮播的新闻
|
|
||||||
const currentNews = computed(() => {
|
|
||||||
return newsList.value[currentIndex.value] || {
|
|
||||||
id: 0,
|
|
||||||
title: '',
|
|
||||||
description: '',
|
|
||||||
inputtime: ''
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 轮播控制方法
|
|
||||||
const prevSlide = () => {
|
|
||||||
topImg.value = mockNewsData.value[currentIndex.value - 1].image_input[0]
|
|
||||||
currentIndex.value = (currentIndex.value - 1 + newsList.value.length) % newsList.value.length
|
|
||||||
}
|
|
||||||
|
|
||||||
const nextSlide = () => {
|
|
||||||
topImg.value = mockNewsData.value[currentIndex.value + 1].image_input[0]
|
|
||||||
currentIndex.value = (currentIndex.value + 1) % newsList.value.length
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分页方法
|
|
||||||
const changePage = (page: number) => {
|
|
||||||
currentPage.value = page
|
|
||||||
getNewsList() // 切换页码时重新获取数据
|
|
||||||
}
|
|
||||||
|
|
||||||
// 格式化年份 - 处理字符串格式的日期 "2023-02-15 16:50"
|
|
||||||
const formatYear = (dateStr: string) => {
|
|
||||||
if (!dateStr) return ''
|
|
||||||
// 从日期字符串中提取年份
|
|
||||||
const year = dateStr.split(' ')[0].split('-')[0]
|
|
||||||
return year
|
|
||||||
}
|
|
||||||
|
|
||||||
// 格式化日期 - 处理字符串格式的日期 "2023-02-15 16:50"
|
|
||||||
const formatDate = (dateStr: string) => {
|
|
||||||
if (!dateStr) return ''
|
|
||||||
// 从日期字符串中提取月和日
|
|
||||||
const dateParts = dateStr.split(' ')[0].split('-')
|
|
||||||
if (dateParts.length < 3) return ''
|
|
||||||
|
|
||||||
const month = dateParts[1]
|
|
||||||
const day = dateParts[2]
|
|
||||||
return `${month}/${day}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const getCurrentLanguage = () => {
|
|
||||||
return locale.value
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
@import "@/assets/animate/animate.min.css";
|
|
||||||
|
|
||||||
.container {
|
|
||||||
width: 100%;
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
max-width: 1310px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.aboutimgBg {
|
|
||||||
background-image: url(/images/newsgroup3.png);
|
|
||||||
background-size: cover;
|
|
||||||
height: 300px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: start;
|
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
height: 600px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsTit h2::after {
|
|
||||||
content: '';
|
|
||||||
width: 120px;
|
|
||||||
height: 20px;
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
width: 100%;
|
|
||||||
height: 28px;
|
|
||||||
margin: 0 auto;
|
|
||||||
margin-top: -15px;
|
|
||||||
}
|
|
||||||
background: #A8CBFF;
|
|
||||||
display: block;
|
|
||||||
margin-top: -20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ellipsis-3 {
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-line-clamp: 3;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsBox1 {
|
|
||||||
margin-top: 20px;
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
margin-top: 50px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsBox2 {
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsBox2:hover {
|
|
||||||
transform: translateY(-5px);
|
|
||||||
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsSpan1 {
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsSpan2 {
|
|
||||||
color: #1C1C1C;
|
|
||||||
letter-spacing: 2px;
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
letter-spacing: 5px;
|
|
||||||
padding-left: 10px;
|
|
||||||
}
|
|
||||||
padding-left: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsbs2 {
|
|
||||||
position: absolute;
|
|
||||||
margin-left: 81px;
|
|
||||||
border-right: 2px solid #1C1C1C;
|
|
||||||
display: inline-block;
|
|
||||||
height: 300px;
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
height: 344px;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.t6::after {
|
|
||||||
content: '';
|
|
||||||
width: 100px;
|
|
||||||
height: 15px;
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
width: 175px;
|
|
||||||
height: 20px;
|
|
||||||
margin-top: -18px;
|
|
||||||
}
|
|
||||||
background: #A3C8FF;
|
|
||||||
display: block;
|
|
||||||
margin-top: -14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.t7::after {
|
|
||||||
content: '';
|
|
||||||
width: 2px;
|
|
||||||
height: 16px;
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
width: 3px;
|
|
||||||
height: 21px;
|
|
||||||
top: 20px;
|
|
||||||
}
|
|
||||||
background: #000000;
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
top: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsTit2 h2::after {
|
|
||||||
content: '';
|
|
||||||
margin-top: -20px;
|
|
||||||
width: 120px;
|
|
||||||
height: 20px;
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
margin-top: -29px;
|
|
||||||
width: 200px;
|
|
||||||
height: 31px;
|
|
||||||
margin-left: 2px;
|
|
||||||
}
|
|
||||||
background: #A8CBFF;
|
|
||||||
display: block;
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsBox2di {
|
|
||||||
width: 100%;
|
|
||||||
border-top: 1px solid #1C1C1C;
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
width: 473px;
|
|
||||||
border-top: 2px solid #1C1C1C;
|
|
||||||
margin-left: 0px;
|
|
||||||
margin-top: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,354 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="bg-white">
|
|
||||||
<!-- Banner section with background image -->
|
|
||||||
<div class="aboutimgBg">
|
|
||||||
<div class="pl-4 md:pl-[200px]">
|
|
||||||
<div class="newsTit">
|
|
||||||
<h2 class="animated fadeInLeft text-2xl md:text-[40px] font-bold">{{ $t('list_p1') }}</h2>
|
|
||||||
<h3 class="animated fadeInLeft text-lg md:text-[25px] font-medium mt-3 md:mt-[30px] text-[#606060]">{{ $t('list_p2') }}</h3>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Featured news section -->
|
|
||||||
<div class="newsBox1 container mx-auto px-4 py-8 flex flex-col md:flex-row flex-wrap" v-if="newsList.length > 0">
|
|
||||||
<div class="newsBox1lider w-full md:w-[38%] mb-6 md:mb-0">
|
|
||||||
<img id="featuredImage" :src="topImg" class="h-[200px] md:h-[300px] w-full object-cover rounded-[5px]" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="newsTit1 w-full md:w-[62%] relative pl-0 md:pl-4 mt-6 md:mt-0">
|
|
||||||
<div id="swipen_next" class="absolute left-0 md:left-4 top-[70%] -translate-y-1/2 cursor-pointer z-10" @click="prevSlide">
|
|
||||||
<img src="/images/group10.png" class="w-[40px] md:w-[50px]" alt="Previous" />
|
|
||||||
</div>
|
|
||||||
<div id="swipen_prev" class="absolute right-0 md:right-4 top-[70%] -translate-y-1/2 cursor-pointer z-10" @click="nextSlide">
|
|
||||||
<img src="/images/group9-1.png" class="w-[40px] md:w-[50px]" alt="Next" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex justify-end items-center mb-4">
|
|
||||||
<div class="relative pr-3 md:pr-5">
|
|
||||||
<h2 class="t7 m-0">
|
|
||||||
<span id="time1" class="newsSpan1 text-2xl md:text-[40px]">{{ formatYear(currentNews.inputtime || currentNews.add_time) }}/</span>
|
|
||||||
<span id="time2" class="newsSpan2 text-xl md:text-[28px]">{{ formatDate(currentNews.inputtime || currentNews.add_time) }}</span>
|
|
||||||
</h2>
|
|
||||||
</div>
|
|
||||||
<div class="text-right">
|
|
||||||
<span class="t6 text-lg md:text-[25px] font-semibold">{{ $t('list_p1') }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="newsdi w-full h-[1px] bg-gray-300 my-3 md:my-4"></div>
|
|
||||||
|
|
||||||
<div class="listSwiper overflow-hidden w-full md:w-[90%] h-[115px] md:h-[200px]">
|
|
||||||
<div class="swiper-wrapper w-full">
|
|
||||||
<span v-if="!isMobile" class="newsbs2 hidden md:inline-block"></span>
|
|
||||||
<div v-for="(news, index) in newsList" :key="index"
|
|
||||||
:class="['swiper-slide pl-[50px] pr-[40px] md:pl-[118px] pt-3 md:pt-[20px]', {'hidden': currentIndex !== index}]">
|
|
||||||
<h2 class="text-xl md:text-3xl font-bold mb-3 md:mb-4 line-clamp-1">
|
|
||||||
<NuxtLink :to="'/info/' + news.id" target="_blank" class="text-[#0c1923] hover:text-blue-600">
|
|
||||||
{{ getCurrentLanguage() === 'zh' ? news.title : news.en_title || news.title }}
|
|
||||||
</NuxtLink>
|
|
||||||
</h2>
|
|
||||||
<h3 class="line-clamp-2 text-gray-600 text-base md:text-lg mb-4 md:mb-6">
|
|
||||||
{{ getCurrentLanguage() === 'zh' ? news.synopsis : news.en_synopsis || news.synopsis }}
|
|
||||||
</h3>
|
|
||||||
<h4 v-if="!isMobile" class="mt-6 md:mt-10">
|
|
||||||
<NuxtLink :to="'/info/' + news.id" target="_blank"
|
|
||||||
class="text-[#0c1923] px-4 py-1 md:px-5 md:py-2.5 text-sm md:text-base rounded-[10px] border border-solid border-[#0c1923] hover:bg-gray-100">
|
|
||||||
{{ $t('list_b3') }}
|
|
||||||
</NuxtLink>
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- News list section -->
|
|
||||||
<div class="container mx-auto px-4 py-8 md:py-12">
|
|
||||||
<div v-for="(news, index) in allNewsList" :key="'all-'+index" class="newsBox2 min-h-[200px] md:min-h-[300px] h-auto md:h-[300px] flex flex-col md:flex-row flex-wrap items-start md:items-center p-4 md:p-[20px] mb-8 md:mb-12 border-b border-gray-200">
|
|
||||||
<NuxtLink :to="'/info/' + news.id" target="_blank" class="text-[#0c1923] hover:text-blue-600 md:h-[300px] flex md:p-[20px]">
|
|
||||||
<div class="newsTit2 w-full md:w-2/3 pr-0 md:pr-6 mb-4 md:mb-0">
|
|
||||||
<h2>
|
|
||||||
<span class="newsSpan1 text-2xl md:text-[40px]">{{ formatYear(news.add_time) }}/</span>
|
|
||||||
<span class="newsSpan2 text-xl md:text-[28px]">{{ formatDate(news.add_time) }}</span>
|
|
||||||
</h2>
|
|
||||||
<div class="newsBox2di w-full md:w-[473px]"></div>
|
|
||||||
<h3 class="text-xl md:text-2xl font-bold mb-2 md:mb-4 pt-3 md:pt-[20px] line-clamp-1">
|
|
||||||
|
|
||||||
{{ getCurrentLanguage() == 'zh' ? news.title : (news.en_title || news.title) }}
|
|
||||||
|
|
||||||
</h3>
|
|
||||||
<h4 class="text-gray-600 text-base md:text-lg line-clamp-2">
|
|
||||||
{{ getCurrentLanguage() == 'zh' ? news.synopsis : (news.en_synopsis || news.synopsis) }}
|
|
||||||
</h4>
|
|
||||||
</div>
|
|
||||||
<img :src="news.image_input[0]" class="news2g10 w-full md:w-1/3 h-[200px] md:h-full object-cover rounded-lg" alt="News thumbnail" />
|
|
||||||
</NuxtLink>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Pagination -->
|
|
||||||
<div id="pages" class="text-center mt-6 md:mt-8">
|
|
||||||
<button
|
|
||||||
v-for="page in totalPages"
|
|
||||||
:key="page"
|
|
||||||
@click="changePage(page)"
|
|
||||||
:class="['mx-1 px-3 py-1 md:px-4 md:py-2 text-sm md:text-base rounded', currentPage === page ? 'bg-blue-500 text-white' : 'bg-gray-200 hover:bg-gray-300']">
|
|
||||||
{{ page }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts" setup>
|
|
||||||
import { ref, computed, onMounted } from 'vue'
|
|
||||||
import { useI18n } from 'vue-i18n'
|
|
||||||
import $api from '@/service/webRequest'
|
|
||||||
|
|
||||||
// 分页相关变量
|
|
||||||
const currentPage = ref(1)
|
|
||||||
const itemsPerPage = 5
|
|
||||||
const totalItems = ref(0)
|
|
||||||
|
|
||||||
// 新闻数据
|
|
||||||
const mockNewsData = ref([])
|
|
||||||
const allNewsList = ref([])
|
|
||||||
const isMobile = ref(false)
|
|
||||||
onMounted(() => {
|
|
||||||
isMobile.value = window.innerWidth < 768
|
|
||||||
getNewsList()
|
|
||||||
getFeaturedNews()
|
|
||||||
})
|
|
||||||
|
|
||||||
const topImg = ref('')
|
|
||||||
// 获取轮播展示的新闻(前5条)
|
|
||||||
const getFeaturedNews = () => {
|
|
||||||
$api.get("/api/article/list/8", { params: { page: 1, limit: 5 } })
|
|
||||||
.then((res: any) => {
|
|
||||||
mockNewsData.value = res.data.data.list
|
|
||||||
topImg.value = res.data.data.list[0].image_input[0]
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.error("获取轮播新闻失败:", err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取分页新闻列表
|
|
||||||
const getNewsList = () => {
|
|
||||||
$api.get("/api/article/list/8", { params: { page: currentPage.value, limit: itemsPerPage } })
|
|
||||||
.then((res: any) => {
|
|
||||||
allNewsList.value = res.data.data.list
|
|
||||||
// 获取总条数用于分页
|
|
||||||
totalItems.value = res.data.data.count
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.error("获取新闻列表失败:", err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const { locale } = useI18n()
|
|
||||||
const currentIndex = ref(0)
|
|
||||||
|
|
||||||
// 轮播新闻列表
|
|
||||||
const newsList = computed(() => mockNewsData.value)
|
|
||||||
|
|
||||||
// 计算总页数
|
|
||||||
const totalPages = computed(() => Math.ceil(totalItems.value / itemsPerPage))
|
|
||||||
|
|
||||||
// 当前轮播的新闻
|
|
||||||
const currentNews = computed(() => {
|
|
||||||
return newsList.value[currentIndex.value] || {
|
|
||||||
id: 0,
|
|
||||||
title: '',
|
|
||||||
description: '',
|
|
||||||
inputtime: ''
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// 轮播控制方法
|
|
||||||
const prevSlide = () => {
|
|
||||||
topImg.value = mockNewsData.value[currentIndex.value - 1].image_input[0]
|
|
||||||
currentIndex.value = (currentIndex.value - 1 + newsList.value.length) % newsList.value.length
|
|
||||||
}
|
|
||||||
|
|
||||||
const nextSlide = () => {
|
|
||||||
topImg.value = mockNewsData.value[currentIndex.value + 1].image_input[0]
|
|
||||||
currentIndex.value = (currentIndex.value + 1) % newsList.value.length
|
|
||||||
}
|
|
||||||
|
|
||||||
// 分页方法
|
|
||||||
const changePage = (page: number) => {
|
|
||||||
currentPage.value = page
|
|
||||||
getNewsList() // 切换页码时重新获取数据
|
|
||||||
}
|
|
||||||
|
|
||||||
// 格式化年份 - 处理字符串格式的日期 "2023-02-15 16:50"
|
|
||||||
const formatYear = (dateStr: string) => {
|
|
||||||
if (!dateStr) return ''
|
|
||||||
// 从日期字符串中提取年份
|
|
||||||
const year = dateStr.split(' ')[0].split('-')[0]
|
|
||||||
return year
|
|
||||||
}
|
|
||||||
|
|
||||||
// 格式化日期 - 处理字符串格式的日期 "2023-02-15 16:50"
|
|
||||||
const formatDate = (dateStr: string) => {
|
|
||||||
if (!dateStr) return ''
|
|
||||||
// 从日期字符串中提取月和日
|
|
||||||
const dateParts = dateStr.split(' ')[0].split('-')
|
|
||||||
if (dateParts.length < 3) return ''
|
|
||||||
|
|
||||||
const month = dateParts[1]
|
|
||||||
const day = dateParts[2]
|
|
||||||
return `${month}/${day}`
|
|
||||||
}
|
|
||||||
|
|
||||||
const getCurrentLanguage = () => {
|
|
||||||
return locale.value
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
|
||||||
@import "@/assets/animate/animate.min.css";
|
|
||||||
|
|
||||||
.container {
|
|
||||||
width: 100%;
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
max-width: 1310px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.aboutimgBg {
|
|
||||||
background-image: url(/images/newsgroup3.png);
|
|
||||||
background-size: cover;
|
|
||||||
height: 300px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: start;
|
|
||||||
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
height: 600px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsTit h2::after {
|
|
||||||
content: '';
|
|
||||||
width: 120px;
|
|
||||||
height: 20px;
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
width: 100%;
|
|
||||||
height: 28px;
|
|
||||||
margin: 0 auto;
|
|
||||||
margin-top: -15px;
|
|
||||||
}
|
|
||||||
background: #A8CBFF;
|
|
||||||
display: block;
|
|
||||||
margin-top: -20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ellipsis-3 {
|
|
||||||
display: -webkit-box;
|
|
||||||
-webkit-line-clamp: 3;
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsBox1 {
|
|
||||||
margin-top: 20px;
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
margin-top: 50px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsBox2 {
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsBox2:hover {
|
|
||||||
transform: translateY(-5px);
|
|
||||||
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsSpan1 {
|
|
||||||
color: #333;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsSpan2 {
|
|
||||||
color: #1C1C1C;
|
|
||||||
letter-spacing: 2px;
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
letter-spacing: 5px;
|
|
||||||
padding-left: 10px;
|
|
||||||
}
|
|
||||||
padding-left: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsbs2 {
|
|
||||||
position: absolute;
|
|
||||||
margin-left: 81px;
|
|
||||||
border-right: 2px solid #1C1C1C;
|
|
||||||
display: inline-block;
|
|
||||||
height: 300px;
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
height: 344px;
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.t6::after {
|
|
||||||
content: '';
|
|
||||||
width: 100px;
|
|
||||||
height: 15px;
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
width: 175px;
|
|
||||||
height: 20px;
|
|
||||||
margin-top: -18px;
|
|
||||||
}
|
|
||||||
background: #A3C8FF;
|
|
||||||
display: block;
|
|
||||||
margin-top: -14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.t7::after {
|
|
||||||
content: '';
|
|
||||||
width: 2px;
|
|
||||||
height: 16px;
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
width: 3px;
|
|
||||||
height: 21px;
|
|
||||||
top: 20px;
|
|
||||||
}
|
|
||||||
background: #000000;
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
top: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsTit2 h2::after {
|
|
||||||
content: '';
|
|
||||||
margin-top: -20px;
|
|
||||||
width: 120px;
|
|
||||||
height: 20px;
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
margin-top: -29px;
|
|
||||||
width: 200px;
|
|
||||||
height: 31px;
|
|
||||||
margin-left: 2px;
|
|
||||||
}
|
|
||||||
background: #A8CBFF;
|
|
||||||
display: block;
|
|
||||||
margin-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newsBox2di {
|
|
||||||
width: 100%;
|
|
||||||
border-top: 1px solid #1C1C1C;
|
|
||||||
@media (min-width: 768px) {
|
|
||||||
width: 473px;
|
|
||||||
border-top: 2px solid #1C1C1C;
|
|
||||||
margin-left: 0px;
|
|
||||||
margin-top: 0px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -1,17 +1,17 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="bg-white">
|
<div class="bg-white">
|
||||||
<!-- Banner section with background image -->
|
<!-- Banner section with background image -->
|
||||||
<div class="aboutimgBg">
|
<!-- <div class="aboutimgBg">
|
||||||
<div class="pl-4 md:pl-[200px]">
|
<div class="pl-4 md:pl-[200px]">
|
||||||
<div class="newsTit">
|
<div class="newsTit">
|
||||||
<h2 class="animated fadeInLeft text-2xl md:text-[40px] font-bold">{{ $t('list_p1') }}</h2>
|
<h2 class="animated fadeInLeft text-2xl md:text-[40px] font-bold">{{ $t('list_p1') }}</h2>
|
||||||
<h3 class="animated fadeInLeft text-lg md:text-[25px] font-medium mt-3 md:mt-[30px] text-[#606060]">{{ $t('list_p2') }}</h3>
|
<h3 class="animated fadeInLeft text-lg md:text-[25px] font-medium mt-3 md:mt-[30px] text-[#606060]">{{ $t('list_p2') }}</h3>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
|
|
||||||
<!-- Featured news section -->
|
<!-- Featured news section -->
|
||||||
<div class="newsBox1 container mx-auto px-4 py-8 flex flex-col md:flex-row flex-wrap" v-if="newsList.length > 0">
|
<!-- <div class="newsBox1 container mx-auto px-4 py-8 flex flex-col md:flex-row flex-wrap" v-if="newsList.length > 0">
|
||||||
<div class="newsBox1lider w-full md:w-[38%] mb-6 md:mb-0">
|
<div class="newsBox1lider w-full md:w-[38%] mb-6 md:mb-0">
|
||||||
<img id="featuredImage" :src="topImg" class="h-[200px] md:h-[300px] w-full object-cover rounded-[5px]" />
|
<img id="featuredImage" :src="topImg" class="h-[200px] md:h-[300px] w-full object-cover rounded-[5px]" />
|
||||||
</div>
|
</div>
|
||||||
@ -61,33 +61,23 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div> -->
|
||||||
|
|
||||||
<!-- News list section -->
|
<!-- News list section -->
|
||||||
<div class="container mx-auto px-4 py-8 md:py-12">
|
<div class="container mx-auto px-4 py-8 md:py-16 flex flex-wrap">
|
||||||
<div v-for="(news, index) in allNewsList" :key="'all-'+index" class="newsBox2 min-h-[200px] md:min-h-[300px] h-auto md:h-[300px] flex flex-col md:flex-row flex-wrap items-start md:items-center p-4 md:p-[20px] mb-8 md:mb-12 border-b border-gray-200">
|
<div v-for="(news, index) in allProsList" :key="'all-'+index" class="newsBox2 min-h-[200px] md:min-h-[300px] h-auto md:w-1/5 md:h-[330px] flex flex-col md:flex-row flex-wrap items-start md:items-center p-4 md:p-[20px] mb-8 md:mb-12 border-b border-gray-200">
|
||||||
<NuxtLink :to="'/info/' + news.id" target="_blank" class="text-[#0c1923] hover:text-blue-600 md:h-[300px] flex md:p-[20px]">
|
<NuxtLink :to="'/product/' + news.id" target="_blank" class="text-[#0c1923] md:h-[300px] flex flex-col ">
|
||||||
<div class="newsTit2 w-full md:w-2/3 pr-0 md:pr-6 mb-4 md:mb-0">
|
<img :src="news.image" class="news2g10 w-full md:h-full object-cover rounded-lg" alt="News thumbnail" />
|
||||||
<h2>
|
<div class="newsTit2 w-full pr-0 md:pr-6 mb-4 md:mb-0">
|
||||||
<span class="newsSpan1 text-2xl md:text-[40px]">{{ formatYear(news.add_time) }}/</span>
|
<h4 class="text-gray-600 text-base md:text-lg line-clamp-2 text-center">
|
||||||
<span class="newsSpan2 text-xl md:text-[28px]">{{ formatDate(news.add_time) }}</span>
|
|
||||||
</h2>
|
|
||||||
<div class="newsBox2di w-full md:w-[473px]"></div>
|
|
||||||
<h3 class="text-xl md:text-2xl font-bold mb-2 md:mb-4 pt-3 md:pt-[20px] line-clamp-1">
|
|
||||||
|
|
||||||
{{ getCurrentLanguage() == 'zh' ? news.title : (news.en_title || news.title) }}
|
{{ getCurrentLanguage() == 'zh' ? news.title : (news.en_title || news.title) }}
|
||||||
|
|
||||||
</h3>
|
|
||||||
<h4 class="text-gray-600 text-base md:text-lg line-clamp-2">
|
|
||||||
{{ getCurrentLanguage() == 'zh' ? news.synopsis : (news.en_synopsis || news.synopsis) }}
|
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<img :src="news.image_input[0]" class="news2g10 w-full md:w-1/3 h-[200px] md:h-full object-cover rounded-lg" alt="News thumbnail" />
|
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Pagination -->
|
<!-- Pagination -->
|
||||||
<div id="pages" class="text-center mt-6 md:mt-8">
|
<div id="pages" class="text-center mt-6 md:mt-8 md:w-full">
|
||||||
<button
|
<button
|
||||||
v-for="page in totalPages"
|
v-for="page in totalPages"
|
||||||
:key="page"
|
:key="page"
|
||||||
@ -107,37 +97,27 @@ import $api from '@/service/webRequest'
|
|||||||
|
|
||||||
// 分页相关变量
|
// 分页相关变量
|
||||||
const currentPage = ref(1)
|
const currentPage = ref(1)
|
||||||
const itemsPerPage = 5
|
const itemsPerPage = 10
|
||||||
const totalItems = ref(0)
|
const totalItems = ref(0)
|
||||||
|
|
||||||
// 新闻数据
|
// 新闻数据
|
||||||
const mockNewsData = ref([])
|
const mockNewsData = ref([])
|
||||||
const allNewsList = ref([])
|
const allProsList = ref([])
|
||||||
const isMobile = ref(false)
|
const isMobile = ref(false)
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
isMobile.value = window.innerWidth < 768
|
isMobile.value = window.innerWidth < 768
|
||||||
getNewsList()
|
getNewsList()
|
||||||
getFeaturedNews()
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const topImg = ref('')
|
const topImg = ref('')
|
||||||
// 获取轮播展示的新闻(前5条)
|
|
||||||
const getFeaturedNews = () => {
|
|
||||||
$api.get("/api/article/list/8", { params: { page: 1, limit: 5 } })
|
|
||||||
.then((res: any) => {
|
|
||||||
mockNewsData.value = res.data.data.list
|
|
||||||
topImg.value = res.data.data.list[0].image_input[0]
|
|
||||||
})
|
|
||||||
.catch((err) => {
|
|
||||||
console.error("获取轮播新闻失败:", err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取分页新闻列表
|
// 获取分页新闻列表
|
||||||
const getNewsList = () => {
|
const getNewsList = () => {
|
||||||
$api.get("/api/article/list/8", { params: { page: currentPage.value, limit: itemsPerPage } })
|
$api.get("/api/websiteproduct/list", { params: { page: currentPage.value, limit: itemsPerPage } })
|
||||||
|
|
||||||
.then((res: any) => {
|
.then((res: any) => {
|
||||||
allNewsList.value = res.data.data.list
|
allProsList.value = res.data.data.list
|
||||||
// 获取总条数用于分页
|
// 获取总条数用于分页
|
||||||
totalItems.value = res.data.data.count
|
totalItems.value = res.data.data.count
|
||||||
})
|
})
|
||||||
@ -212,8 +192,10 @@ const getCurrentLanguage = () => {
|
|||||||
|
|
||||||
.container {
|
.container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
padding-top:4rem;
|
||||||
@media (min-width: 768px) {
|
@media (min-width: 768px) {
|
||||||
max-width: 1310px;
|
max-width: 1310px;
|
||||||
|
padding-top: 90px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
301
pages/product/[id].vue
Normal file
301
pages/product/[id].vue
Normal file
@ -0,0 +1,301 @@
|
|||||||
|
<template>
|
||||||
|
<div class="bg-[#F2F2F2]">
|
||||||
|
<!-- Contact section -->
|
||||||
|
<div class="box2">
|
||||||
|
<div class="flex flex-wrap justify-center pb-[50px] md:pb-[50px] px-4 md:px-0">
|
||||||
|
<div class="md:w-[50%]" style="display: flex;align-items: self-start;flex-wrap: wrap;justify-content: right;height: 800px;margin-top: 119px;">
|
||||||
|
<img :src="images_top" class="w-[585px] h-[585px]" alt="Product Image">
|
||||||
|
<div class="flex justify-start w-[585px] ">
|
||||||
|
<img @click="imgsChange(item)" class="w-[102px] h-[102px] pr-[10px]" :src="item" v-for="(item,index) in info.images" :key="index">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="w-full md:w-[50%] px-4 md:px-[115px] pt-6 md:pt-[115px]">
|
||||||
|
<div class="contactTit">
|
||||||
|
<h3 class="text-[22px] md:text-[30px] font-bold mb-[20px]" style="color: #3D3D3D;">{{locale == 'zh' ? info.title : info.en_title }}</h3>
|
||||||
|
<div class="mb-[30px]"> {{locale == 'zh' ? info.profile : info.en_profile }}</div>
|
||||||
|
<a href="#contactpro">
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="contactBut flex justify-center items-center bg-[#0C4DA9]"
|
||||||
|
>
|
||||||
|
<img src="/images/zixun.png" class="w-[32px] " >
|
||||||
|
<span class="text-[#ffffff] text-[22px] ml-2" >{{ $t('contact_b5') }}</span>
|
||||||
|
</button>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="contactTit">
|
||||||
|
<h5 class="text-[22px] md:text-[24px] font-bold h5s" style="color: #0C4DA9;">{{ $t('products_details') }}</h5>
|
||||||
|
<div class="mt-[20px]">{{locale == 'zh' ? info.content : info.en_content }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="contactTit" id="contactpro">
|
||||||
|
<h5 class="text-[22px] md:text-[24px] font-bold h5s" style="color: #0C4DA9;">{{ $t('contact_b4') }}</h5>
|
||||||
|
<form class="contactForm mt-6 md:mt-12 w-full md:w-[700px]" @submit.prevent="submitForm">
|
||||||
|
<input
|
||||||
|
v-model="formData.name"
|
||||||
|
class="contactInput w-full md:w-[700px]"
|
||||||
|
type="text"
|
||||||
|
:placeholder="$t('message_b1')"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
v-model="formData.emil"
|
||||||
|
class="contactInput mt-[15px] md:mt-[30px] w-full md:w-[700px]"
|
||||||
|
type="text"
|
||||||
|
:placeholder="$t('message_b2')"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
v-model="formData.mobile"
|
||||||
|
class="contactInput mt-[15px] md:mt-[30px] w-full md:w-[700px]"
|
||||||
|
type="text"
|
||||||
|
:placeholder="$t('message_b3')"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
v-model="formData.company"
|
||||||
|
class="contactInput mt-[15px] md:mt-[30px] w-full md:w-[700px]"
|
||||||
|
type="text"
|
||||||
|
:placeholder="$t('message_b4')"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
v-model="formData.subject"
|
||||||
|
class="contactInput mt-[15px] md:mt-[30px] w-full md:w-[700px]"
|
||||||
|
type="text"
|
||||||
|
:placeholder="$t('message_b5')"
|
||||||
|
/>
|
||||||
|
<div class="relative mt-4 md:mt-8 w-full md:w-[700px]">
|
||||||
|
<textarea
|
||||||
|
v-model="formData.content"
|
||||||
|
id="myTextarea"
|
||||||
|
:placeholder="$t('message_b6')"
|
||||||
|
rows="6"
|
||||||
|
maxlength="100"
|
||||||
|
class="w-full md:w-[700px]"
|
||||||
|
></textarea>
|
||||||
|
<div class="char-count">{{ formData.content.length }}/100</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex justify-start mt-4 md:mt-6">
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
class="contactBut"
|
||||||
|
>
|
||||||
|
{{ $t('contact_b5') }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref, reactive ,onMounted} from 'vue'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
const { locale,t} = useI18n()
|
||||||
|
import { useStore } from '~/store'
|
||||||
|
import $api from '@/service/webRequest'
|
||||||
|
const store = useStore()
|
||||||
|
const route = useRoute()
|
||||||
|
const id = ref('')
|
||||||
|
const images_top = ref('')
|
||||||
|
const info = ref({})
|
||||||
|
// 表单数据
|
||||||
|
const formData = reactive({
|
||||||
|
name: '',
|
||||||
|
mobile: '',
|
||||||
|
content: '',
|
||||||
|
emil:'',
|
||||||
|
subject:'',
|
||||||
|
company:''
|
||||||
|
})
|
||||||
|
onMounted(() => {
|
||||||
|
id.value = route.params.id;
|
||||||
|
getInfo()
|
||||||
|
})
|
||||||
|
|
||||||
|
const getInfo=()=>{
|
||||||
|
$api.get("/api/websiteproduct/details/"+id.value)
|
||||||
|
.then((res: any) => {
|
||||||
|
console.log(res)
|
||||||
|
info.value = res.data.data
|
||||||
|
images_top.value = res.data.data.image
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.dir(err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// 社交分享功能
|
||||||
|
const shareToLink = (item) => {
|
||||||
|
// 实现Instagram分享
|
||||||
|
window.open(item.link, '_blank');
|
||||||
|
}
|
||||||
|
const imgsChange = (e) => {
|
||||||
|
images_top.value = e;
|
||||||
|
}
|
||||||
|
// 表单提交方法
|
||||||
|
const submitForm = () => {
|
||||||
|
console.log(formData);
|
||||||
|
|
||||||
|
// 这里可以添加表单验证逻辑
|
||||||
|
if (!formData.name) {
|
||||||
|
alert(t('message_name_required'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!formData.mobile) {
|
||||||
|
alert(t('message_phone_required'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (!formData.content) {
|
||||||
|
alert(t('message_message_required'))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
$api.post("/api/websiteproduct/leave_word",{
|
||||||
|
name:formData.name,
|
||||||
|
mobile:formData.mobile,
|
||||||
|
content:formData.content,
|
||||||
|
emil:formData.emil,
|
||||||
|
subject:formData.subject,
|
||||||
|
company:formData.company,
|
||||||
|
product_id:id.value
|
||||||
|
})
|
||||||
|
.then((res: any) => {
|
||||||
|
console.log(res)
|
||||||
|
if(res.data.status==200){
|
||||||
|
alert(t('contact_success'))
|
||||||
|
}else{
|
||||||
|
alert(t('contact_error'))
|
||||||
|
}
|
||||||
|
formData.name = '';
|
||||||
|
formData.mobile = '';
|
||||||
|
formData.content = '';
|
||||||
|
formData.subject = '';
|
||||||
|
formData.emil = '';
|
||||||
|
formData.company = '';
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.dir(err)
|
||||||
|
})
|
||||||
|
// 重置表单
|
||||||
|
// formData.name = ''
|
||||||
|
// formData.mobile = ''
|
||||||
|
// formData.content = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
/* 可以添加一些特定的样式,但大部分已经通过Tailwind实现 */
|
||||||
|
.animated {
|
||||||
|
animation-duration: 1s;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fadeInLeft {
|
||||||
|
animation-name: fadeInLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fadeInLeft {
|
||||||
|
from {
|
||||||
|
opacity: 0;
|
||||||
|
transform: translate3d(-100%, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
transform: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.contactTit {
|
||||||
|
background: #ffffff;
|
||||||
|
margin-bottom:30px;
|
||||||
|
padding: 30px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
.contactTit h5 span {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 22px;
|
||||||
|
color: #1C1C1C;
|
||||||
|
line-height: 26px;
|
||||||
|
text-align: left;
|
||||||
|
margin-left: 4px;
|
||||||
|
}
|
||||||
|
.h5s::before {
|
||||||
|
content:'1';
|
||||||
|
width: 3px;
|
||||||
|
height: 26px;
|
||||||
|
margin-right: 10px;
|
||||||
|
background: #0C4DA9;
|
||||||
|
}
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.contactTit h3 span {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.contactInput{border-radius:6px;
|
||||||
|
border: 1px solid #BBBBBB;font-size: 24px;color: #000;height: 50px;}
|
||||||
|
.contactInput::placeholder {color: #999999;}
|
||||||
|
.contactInput:focus {outline: none;}
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.contactInput {
|
||||||
|
font-size: 18px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#myTextarea {padding: 10px;border-radius: 6px;margin-top: 32px;border: 1px solid #BBBBBB;font-weight: 400;font-size: 24px;color: #000;line-height: 22px;resize: none; /* 禁止用户调整文本域大小 */}
|
||||||
|
#myTextarea::placeholder {color: #999999;}
|
||||||
|
#myTextarea:focus {outline: none;}
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
#myTextarea {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 18px;
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.char-count {position: absolute;bottom: 5px; /* 根据需要调整距离底部的位置 */right: 10px; /* 根据需要调整距离右侧的位置 */font-size: 12px; /* 根据需要调整字体大小 */color: #999999;}
|
||||||
|
.text-area-container {position: relative;width: 100%;}
|
||||||
|
.contactBut{ width: 232px;
|
||||||
|
height: 54px;
|
||||||
|
border-radius: 0px 0px 0px 0px;
|
||||||
|
border: 1px solid #0C4DA9;
|
||||||
|
color: #0C4DA9;
|
||||||
|
}
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.contactBut {
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 22px;
|
||||||
|
}
|
||||||
|
.contactBut::after {
|
||||||
|
width: 100px;
|
||||||
|
height: 10px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.contactForm{width: 100%;}
|
||||||
|
.contactTit h8 {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 24px;
|
||||||
|
color: #175FCB;
|
||||||
|
line-height: 28px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
@media (max-width: 768px) {
|
||||||
|
.contactTit h8 {
|
||||||
|
font-size: 20px;
|
||||||
|
line-height: 24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.contactdx8{
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 5px;
|
||||||
|
border-top: 2px solid #175FCB;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -10,7 +10,7 @@ export default {
|
|||||||
index_clients: 'CLIENTS',
|
index_clients: 'CLIENTS',
|
||||||
index_news: 'News',
|
index_news: 'News',
|
||||||
index_contact: 'Contact US',
|
index_contact: 'Contact US',
|
||||||
index_product:'Products',
|
index_products:'Products',
|
||||||
index_share: 'Share Wed',
|
index_share: 'Share Wed',
|
||||||
|
|
||||||
// Index section 2
|
// Index section 2
|
||||||
@ -98,4 +98,19 @@ export default {
|
|||||||
contact_success_title: 'Thank you for your submission',
|
contact_success_title: 'Thank you for your submission',
|
||||||
//提交失败
|
//提交失败
|
||||||
contact_fail_title: 'Submission failed',
|
contact_fail_title: 'Submission failed',
|
||||||
|
|
||||||
|
|
||||||
|
// 留言
|
||||||
|
message_b1: ' Your name',
|
||||||
|
message_b2: ' Your email address',
|
||||||
|
message_b3: ' Your contact information',
|
||||||
|
message_b4: ' Your company name',
|
||||||
|
message_b5: ' Your theme ',
|
||||||
|
message_b6: ' The content you have filled in',
|
||||||
|
|
||||||
|
message_name_required: ' Please enter your name',
|
||||||
|
message_phone_required: ' Please enter your contact information',
|
||||||
|
message_message_required: ' Please enter the message content',
|
||||||
|
|
||||||
|
products_details:'Products Details'
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ export default {
|
|||||||
index_clients: '我的客户',
|
index_clients: '我的客户',
|
||||||
index_news: '最新新闻',
|
index_news: '最新新闻',
|
||||||
index_contact: '联系我们',
|
index_contact: '联系我们',
|
||||||
index_product: '产品',
|
index_products: '产品列表',
|
||||||
index_share: '分享',
|
index_share: '分享',
|
||||||
|
|
||||||
// 首页2
|
// 首页2
|
||||||
@ -96,4 +96,18 @@ export default {
|
|||||||
contact_success: '提交成功',
|
contact_success: '提交成功',
|
||||||
//提交失败
|
//提交失败
|
||||||
contact_error:'提交失败',
|
contact_error:'提交失败',
|
||||||
|
|
||||||
|
// 留言
|
||||||
|
message_b1: '您的姓名',
|
||||||
|
message_b2: '您的电子邮箱',
|
||||||
|
message_b3: '您的联系方式',
|
||||||
|
message_b4: '您的公司名称',
|
||||||
|
message_b5: '您的主题',
|
||||||
|
message_b6: '您填写的内容',
|
||||||
|
|
||||||
|
message_name_required: '请输入您的姓名',
|
||||||
|
message_phone_required: '请输入您的联系方式',
|
||||||
|
message_message_required: '请输入留言内容',
|
||||||
|
|
||||||
|
products_details:'产品详情'
|
||||||
}
|
}
|
||||||
|
BIN
public/images/zixun.png
Normal file
BIN
public/images/zixun.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 769 B |
Loading…
x
Reference in New Issue
Block a user