tuanshiwei-web/pages/phone_index.vue
zhangkai 81ca4297d8 1,手机端内容新列表 轮播图 详情 留言板
2、手机端文章详情,百科详情,公开信息详情
2025-06-11 18:23:32 +08:00

814 lines
18 KiB
Vue

<template>
<div style="width: 100%;">
<!-- Swiper 容器 -->
<div class="group_666" style="position: relative;height: 219px;">
<swiper class="swiper-container h-full" @swiper="onSwiperNews" v-bind="swiperOptionsNews">
<swiper-slide>
<img :src="`/img/index/homebg.png`" style="width: 100%;height: 100%;object-fit: cover;">
<!-- <div style="position: absolute;bottom: 30px;right:30px;">
<img :src="`/img/index/hmouse.png`" alt="">
</div> -->
</swiper-slide>
</swiper>
</div>
<div class="group_2 flex-col">
<div class="box_2 flex-col">
<div class="group_3" >
<div class="group_4 flex-col">
<div class="fly" >
<div class="re_box">
<span class="w-[100%] text_14" style="margin-top: 0;">文章精选</span>
<div class="swiper">
<swiper class="w-[100%] h-[228px]" @swiper="onSwiperImgs" v-bind="swiperOptionsimgs">
<swiper-slide v-for="(item,index) in xsImg" :key="index">
<div class="img_tits">{{ item.title }}</div>
<img :src="item.image" style="width: 100%;height: 100%;object-fit: cover;">
</swiper-slide>
</swiper>
<div class="swiper-pagination"></div>
</div>
<div style="width: 100%;">
<div class="re_box_item" v-for="(item,index) in xsList" :key="index" @click="gotoDetail(item.id)">
<div class="re_title">
<div class="dian"></div>
<span class="one-line-ellipsis" style="width:100%;">{{ item.title }}</span>
</div>
<div class="slices_rol"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div style="background-color: #ffffff;">
<div class="box_7 flex-col">
<span class="text_24">国务院百事通</span>
<div class="dswper">
<swiper ref="swiper_exp"
:slidesPerView="isMobile ? 1 : 2"
loop
:autoplay="false"
:modules="modules"
:watchSlidesProgress="true"
@swiper="onSwiperExp">
<swiper-slide v-for="(item, index) in bstList" :key="index" @click="openUrl(item.id)">
<div style="padding: 20px;">
<!-- <img class="hy_my_home" :src="`${$cdnUrl}/img/home_al/op${item}.png`"> -->
<div class="hy_my_home">
<div class="bst_con">
<img :src="`/img/index/bst${index+1}.png`" alt="" style="width: 34px;height: 34px;margin-top: 25px;margin-bottom: 15px;">
<div class="bsttitle">
{{ item.title }}
</div>
</div>
</div>
</div>
</swiper-slide>
</swiper>
<div class="flex-row justify-center align-center w-full" style="gap: 10px;height:40px;">
<div v-for="(_, index) in 3" :key="index" style="width: 20px; height: 5px;"
:style="{ backgroundColor: activeSlideIndex === index ? '#fc7428' : '#C1C1C1' }">
</div>
</div>
</div>
</div>
</div>
<div class="box_11 flex-col">
<div class="text-wrapper_10">
<span class="text_41">新闻动态</span>
</div>
<div v-for="item in newsList">
<div class="box_12 flex-row justify-center">
<!-- <img @click="openUrl(item.id)" class="image_7 leftBoxTop" referrerpolicy="no-referrer"
:src="item.image" style="cursor: pointer;;object-fit: cover;" /> -->
<div class="box_13 flex-col" @click="openUrl(item.id)">
<div class="text-group_6">
<div class="one-line-ellipsis news_title_home">
{{ item.title }}
</div>
<div class="two-line-ellipsis"
style="color: #768597;font-size: 14px;font-weight: 400;margin-top: 20px;">
{{ item.subtitle }}
</div>
</div>
<div class="group_22 flex-row">
<div class="section_6 flex-col"></div>
<span class="text_44">{{ item.cate.name }}</span>
<span class="text_45">{{ retTime(item.release_time_text) }}</span>
</div>
</div>
</div>
</div>
<!-- <div class="box_16 flex-row">
<div class="text-wrapper_12 flex-col">
<nuxt-link to="/phone_societyDutyNew/" class="text_52">
<span>查看更多</span>
</nuxt-link>
</div>
</div> -->
</div>
<div class="box_18 flex-col" style="overflow: hidden;">
<span class="text_53" >团团留言版</span>
<div class="numberTopBox" style="margin:0 auto;padding-bottom: 30px;">
<form class="contactForm mt-6 w-full" @submit.prevent="submitForm">
<div class="inputform">
<input v-model="formData.name" class="contactInput mt-[15px] md:mt-[30px] w-full md:w-[700px]"
type="text" placeholder="输入您的姓名" />
<input v-model="formData.mobile"
class="contactInput mt-[15px] md:ml-[30px] md:mt-[30px] w-full md:w-[700px]" type="text"
placeholder="请输入您的联系电话" />
<input v-model="formData.emil"
class="contactInput mt-[15px] md:ml-[30px] md:mt-[30px] w-full md:w-[700px]" type="text"
placeholder="请输入您的邮箱" />
</div>
<div class="relative w-full" style="padding:0px 20px;">
<textarea v-model="formData.message" id="myTextarea" placeholder="为了更好地帮助您,请尽量提供详细的信息" rows="5"
maxlength="100" class="w-full"></textarea>
<button type="submit" class="contactBut">
{{ '提交' }}
</button>
</div>
</form>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { Swiper, SwiperSlide } from 'swiper/vue'
import { nextTick, ref, onMounted, onUnmounted } from 'vue'
import 'swiper/css'
import { Autoplay, Navigation, Pagination, Scrollbar, A11y, EffectCoverflow, EffectFade } from "swiper/modules";
import ScrollReveal from 'scrollreveal';
import { NNumberAnimation } from 'naive-ui'
let modules = [Autoplay, A11y, EffectCoverflow, EffectFade];
import "swiper/css";
import "swiper/css/navigation";
import "swiper/css/pagination";
import 'swiper/css/effect-coverflow';
import 'swiper/css/mousewheel'
import 'swiper/css/grid'
import 'swiper/css/effect-fade'
import 'swiper/css/autoplay'
import * as swiperAni from '@/assets/animate/animate.js'
import $api from '@/service/webRequest'
import { useI18n } from 'vue-i18n'
import { useStore } from '~/store'
const cdnUrl = useCdn()
const { locale } = useI18n()
const typeId = ref(1);
interface NewsItem {
id: number;
title: string;
subtitle: string;
image: string;
cate: {
name: string;
};
release_time_text: string;
}
const newsList = ref<NewsItem[]>([])
const openType = (type: number) => {
console.log(type);
typeId.value = type;
}
const bstList = ref([
{title:"中国共产主义青年团的性质是什么?",id:5969},
{title:"中国共产主义青年团的行动指南是什么?",id:5970},
{title:"为什么说共青团是中国共产党的助手和后备军?",id:5971},
{title:"中国共产主义青年团在新时代的基本任务是什么?",id:5972},
{title:"怎样加入中国共产主义青年团?",id:5973},
{title:"团员必须履行哪些义务?",id:5974},
{title:"团员享有哪些权利?",id:5975},
{title:"团旗、团徽和团歌分别是什么?",id:5976}
])
const videoShow = ref(false)
let newsSwiper: any = null
const onSwiperNews = (swiper: any) => {
newsSwiper = swiper
}
const swiperOptionsNews = {
autoplay: {
delay: 5000,
disableOnInteraction: false,
},
direction: 'horizontal' as const,
slidesPerView: 1,
speed: 500,
effect: 'fade',
loop: true,
modules: [EffectFade, Autoplay],
}
let vesSwiper: any = null
const onSwiperExp = (swiper: any) => {
vesSwiper = swiper
// 监听幻灯片变化事件
swiper.on('slideChange', () => {
// 更新当前活动幻灯片索引
activeSlideIndex.value = swiper.realIndex % 3
})
}
const swiper_exp = ref();
const activeSlideIndex = ref(0);
// 表单数据
const formData = reactive({
name: '',
mobile: '',
emil: '',
message: ''
})
const router = useRouter()
// 新闻数据
const isMobile = ref(false)
const checkMobile = () => {
isMobile.value = window.innerWidth <= 768
}
onMounted(() => {
checkMobile()
window.addEventListener('resize', checkMobile)
getIndexNews();
nextTick(() => {
// 初始化 ScrollReveal
setTimeout(() => {
animate()
}, 500)
})
getxsImg();
})
onUnmounted(() => {
window.removeEventListener('resize', checkMobile)
})
const animate = () => {
const sr = ScrollReveal();
sr.reveal('.leftBoxTop', {
origin: "left",
distance: "1000px",
duration: 1300,
delay: 100,
opacity: 0,
scale: 0.9,
reset: true,
mobile: true,
})
sr.reveal('.leftBox', {
origin: "left",
distance: "1000px",
duration: 1300,
delay: 100,
opacity: 0,
scale: 0.9,
reset: true,
mobile: true,
})
sr.reveal('.rightBox', {
origin: "right",
distance: "1000px",
duration: 1300,
delay: 100,
opacity: 0,
scale: 0.9,
reset: true,
mobile: true,
})
sr.reveal('.topBox', {
origin: "top",
distance: "1000px",
duration: 1300,
delay: 100,
opacity: 0,
scale: 0.9,
reset: true,
mobile: true,
})
sr.reveal('.bottomBox', {
origin: "bottom",
distance: "1000px",
duration: 1300,
delay: 100,
opacity: 0,
scale: 0.9,
reset: true,
mobile: true,
})
sr.reveal('.numberTopBox', {
origin: "top",
distance: "1000px",
duration: 1300,
delay: 100,
opacity: 0,
scale: 0.9,
reset: false,
mobile: true,
beforeReveal: function (el: any) {
// numberAnimationInstRef.value.play()
// numberAnimationInstRefKH.value.play()
// numberAnimationInstRefJS.value.play()
// numberAnimationInstRefHY.value.play()
},
})
sr.reveal('.group_29 ', {
origin: "bottom",
distance: "500px",
opacity: 0,
scale: 0.9,
reset: false,
mobile: true,
})
}
// 表单提交方法
const submitForm = () => {
console.log(formData);
// 这里可以添加表单验证逻辑
if (!formData.name) {
alert('请输入您的姓名')
return
}
if (!formData.mobile) {
alert('请输入您的手机号码')
return
}
if (!formData.message) {
alert('请输入您的留言内容')
return
}
$api.post("/api/home.leave_word/add", formData)
.then((res: any) => {
console.log(res)
if (res.status == 200) {
alert('留言成功')
} else {
alert('失败')
}
formData.name = '';
formData.mobile = '';
formData.emil = '';
formData.message = '';
})
.catch((err) => {
console.dir(err)
})
// 重置表单
// formData.name = ''
// formData.mobile = ''
// formData.content = ''
}
const getIndexNews = () => {
$api.get("/api/home.news/index?page=1&limit=3")
.then((res: any) => {
console.log(res)
newsList.value = res.data.data.list
})
.catch((err) => {
console.dir(err)
})
}
const retTime = (dateTimeStr: string) => {
return dateTimeStr.split(' ')[0]; // 分割后取日期部分
}
const openUrl = (id: number) => {
window.open(`/phone_info/${id}`)
}
const gotoDetail = (id: number) => {
window.open(`/phone_info/${id}`)
}
const xsImg = ref([]);
const xsList = ref([]);
//逐梦新声轮播图
const getxsImg = async () => {
const res = await $api.get('/api/index/images?page=1&limit=3')
xsImg.value = res.data.data.list;
const ress = await $api.get(`/api/home.news/index?cate_id=99&page=1&limit=4`)
xsList.value = ress.data.data.list;
}
let ImgsSwiper: any = null
const onSwiperImgs = (swiper: any) => {
ImgsSwiper = swiper
}
const swiperOptionsimgs = {
autoplay: {
delay: 5000,
disableOnInteraction: false,
},
direction: 'horizontal',
slidesPerView: 1,
speed: 500,
// effect: 'fade',
loop: true,
modules: [Autoplay,Pagination],
pagination: {
el:'.swiper-pagination'
},
}
</script>
<style lang="scss" scoped>
@import "@/assets/animate/animate.min.css";
@import "@/assets/index.scss";
.text_7, .text_8 {
text-align: center;
width: 100%;
}
.text_9, .text_11 {
font-size: 16px !important;
text-align: center;
padding-right:0px
}
.text_12 {
font-size: 14px !important;
line-height: 1.6;
padding: 0 15px;
width: 100%;
}
.text-wrapper_2{
margin: 0 auto;
}
.leftBox, .rightBox {
width: 100% !important;
margin: 10px 0 !important;
}
.content_box {
width: 100% !important;
height: 300px !important;
position: relative !important;
right: 0 !important;
bottom: 0 !important;
}
.hy_my_home {
width: 100% !important;
// height: auto !important;
height: 150px;
background-image: url('/img/index/bstbg.png');
background-size: 100% 100%;
background-repeat: no-repeat;
.bst_con{
width: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
.bsttitle{
width: 80%;
font-family: Microsoft YaHei UI;
font-weight: bold;
font-size: 18px;
color: #FFFFFF;
text-align: center;
}
&:hover{
.bsttitle{
color: #FFE7B8;
}
}
}
}
.section_1{
height: 323px;
width: 100%;
}
.image-wrapper_2{
border-radius: 10px;
}
.contactForm {
.inputform {
flex-direction: column !important;
width: 100% !important;
padding:20px 20px 10px 20px;
}
.contactInput {
width: 100% !important;
margin: 10px 0 !important;
height: 40px !important;
font-size: 14px !important;
border-radius: 6px!important;
background: #FFFFFF;
padding-left: 10px;
}
#myTextarea {
width: 100% !important;
height: 120px !important;
font-size: 14px !important;
border-radius: 6px!important;
padding: 10px;
}
}
.box_12, .box_14 {
flex-direction: column !important;
}
.box_3{
width: 100%;
}
.box_7,.box_13,.box_18{
height: 100%;
}
.image_7, .image_8, .image_9 {
width: 100% !important;
}
.text_24{
margin-top: 30px;
}
.group_22{
width: 100%;
margin: 27px 0 23px 15px;
}
.news_my_home {
width: 100% !important;
margin: 10px 0 !important;
padding: 15px !important;
}
.contactBut {
width: 108px;
border-radius: 4px 4px 4px 4px;
position: absolute;
bottom: 20px;
right: 30px;
height: 36px;
background-color: #3B90DF;
border: none;
font-weight: 400;
font-size: 16px;
line-height: 28px;
color: #FFFFFF;
}
.group_29 {
grid-template-columns: repeat(2, 1fr) !important;
gap: 10px !important;
padding: 0 15px !important;
}
.bottom_imgs {
width: 100% !important;
height: auto !important;
}
.pop {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, .8);
z-index: 200;
display: none;
}
.popCont {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.pop_video_close {
border-radius: 50%;
position: absolute;
top: -73px;
right: 0px;
width: 40px;
height: 40px;
background: var(--close) no-repeat 0 0;
background-size: 100% auto;
border: 6px solid #979797;
}
.pop_video_cont {
width: 600px;
border: 6px solid #979797;
background: #000;
}
.pop_video_cont video {
display: block;
width: 100%;
height: 100%;
}
.text_16 {
font-size: 14px;
line-height: 24px;
}
.group_10{
width: 91%;
margin-left:15px;
margin-top: 0px;
}
.text_18 {
font-size: 15px !important;
}
.text_19 {
font-size: 13px !important;
}
.group_7 {
padding: 10px !important;
margin: 0px 0 !important;
height: 100%!important;
}
.text-group_3{
height: auto;
}
.section_2sa{
height: 700px;
}
.image-wrapper_5 {
width: 40px !important;
height: 40px !important;
margin-top: 0px;
margin-right: 20px !important;
}
.text-group_3_3{
height: auto;
}
.text-group_3, .text-group_3_3 {
flex: 1 !important;
}
.contactBut {
width: 100% !important;
height: 40px !important;
font-size: 16px !important;
margin-top: 10px !important;
position: relative !important;
right: 0 !important;
bottom: 0 !important;
}
// 移除所有hover效果
.hy_my_home:hover,
.news_my_home:hover .news_title_home {
transform: none !important;
color: inherit !important;
}
.text-group_1,.group_7,.group_6s{
width: 100%;
}
.text_19{
width: 100%;
line-height: 25px;
height: auto;
}
.box_12{
height: 100%;
margin-top: 0px;
}
.group_6 {
width: 100%;
}
.box_13{
width: 100%;
margin:0px;
}
.section_2s{
height: 710px;
}
.box_5{
height: auto;
}
.text-group_2{
width: 55%;
height: auto;
}
.text_17,.text_16{
width: auto;
}
.box_6{
padding:0px 15px 15px 15px;
height: 100%;
}
.image-wrapper_5{
width: 30%;
}
.text-group_3{
width: 70%;
}
.group_10s {
width: 100%;
margin: 0px;
}
.dswper{
margin-top: 10px;
}
.text-wrapper_10{
margin-top: 30px;
}
@media (max-width: 768px) {
.group_3 {
height: auto;
padding: 20px;
background-size:auto;
}
}
.fly{
.re_box{
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: flex-start;
align-content: flex-start;
// gap: 10px;
background: #FFFFFF;
position: relative;
border-radius: 12px;
.re_box_item{
width: 100%;
height: 40px;
padding-bottom: 5px;
border-bottom: 1px dashed #dedede;
box-sizing: border-box;
display: flex;
justify-content: space-between;
align-items: center;
.re_title{
width: 100%;
font-family: Microsoft YaHei;
font-weight: 400;
font-size: 16px;
color: #323232;
display: flex;
align-items: center;
.dian{
width: 5px;
height: 5px;
background: #3B90DF;
border-radius: 50%;
margin-right: 10px;
}
}
// &:hover{
// background-image: url('/img/index/listhmbg.png');
// background-size: 100% 100%;
// cursor: pointer;
// .slices_rol{
// width: 10px;
// height: 88px;
// background: #FAA828;
// position: absolute;
// right: 0;
// }
// }
}
.swiper{
width: 100%;
border-radius: 10px;
.swiper-pagination{
text-align: right;
padding-right: 10px;
bottom: 0;
height: 38px;
line-height: 38px;
--swiper-pagination-color: #bf1712;/* 两种都可以 */
}
.img_tits{
font-family: Microsoft YaHei UI;
font-weight: bold;
font-size: 18px;
color: #FFFEFE;
position: absolute;
bottom: 0;
left: 0;
background: rgba(0, 0, 0, .2);
width: 100%;
height: 38px;
line-height: 38px;
padding-left: 10px;
}
}
}
}
</style>