uniapp-app/pages/index/index.vue
2025-09-05 10:19:10 +08:00

1679 lines
35 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="container">
<!-- 头部搜索栏 -->
<view class="header" :style="{ backgroundColor: headerBgColor }">
<view class="header-content">
<view class="header-left">
<view class="calendar-icon" @click="onSignClick">
<up-image :src="isSignedIn ? sign : nosign" width="60rpx" height="60rpx"></up-image>
</view>
</view>
<view class="search-container" @click="focus">
<view class="mask"></view>
<uni-search-bar
placeholder="搜索视频、精品课、课件、指南等"
radius="8"
cancelButton="none"
bgColor="#ffffff"
placeholderColor="#999999"
></uni-search-bar>
</view>
<view class="header-right">
<view class="message-icon">
<uni-icons type="email" size="32" color="#fff"></uni-icons>
<view v-if="hasUnread" class="red-dot"></view>
</view>
</view>
</view>
</view>
<!-- 轮播图 -->
<view class="banner-section">
<uni-swiper-dot
:info="bannerList"
:current="current"
field="content"
:mode="mode"
:dots-styles="dotsStyles"
>
<swiper class="swiper-box" @change="change" :current="current" :autoplay="true" :interval="4000" :duration="500" :circular="true">
<swiper-item v-for="(item, index) in bannerList" :key="index">
<view class="banner-item" @click="onBannerClick(item,index)">
<view class="doctorInfo" v-if="index==0">
<view class="name">{{expertDetail.realName}}专家工作室</view>
<view class="hospital">{{expertDetail.hospitalName}}</view>
</view>
<up-image :src="item.image" width="100%" height="400rpx"></up-image>
</view>
</swiper-item>
</swiper>
</uni-swiper-dot>
</view>
<!-- 功能网格 -->
<view class="grid-section">
<uni-grid :column="4" :highlight="true" >
<uni-grid-item v-for="(item, index) in gridList" :key="index">
<view class="grid-item" @click="onClick(index)">
<up-image :src="item.icon" width="75rpx" height="75rpx" ></up-image>
<text class="grid-text">{{ item.text }}</text>
</view>
</uni-grid-item>
</uni-grid>
</view>
<!-- 消息通知滚动播放 -->
<view class="notice-section" v-if="noticeList.length > 0">
<view class="notice-container">
<view class="notice-icon">
</view>
<view class="notice-content">
<swiper class="notice-swiper"
:vertical="true"
:autoplay="true"
:interval="3000"
:duration="1000"
:circular="true"
@change="onNoticeChange"
>
<swiper-item v-for="(item, index) in noticeList" :key="index">
<view class="notice-cell">
<view class="timebox">
<view class="top">
<up-image :src="livebg" width="59rpx" height="27rpx" ></up-image>
<up-image :src="jing_sign" width="28rpx" height="28rpx" ></up-image>
</view>
<view class="date">
{{ formatToMonthDay(item.date || item.time) }}
</view>
</view>
<view class="bar"></view>
<view class="notice-text oneline" @click="onNoticeClick(item)">
{{ item.content }}
</view>
</view>
</swiper-item>
</swiper>
</view>
</view>
</view>
<!-- 专题E站 -->
<view class="special-section">
<view class="section-title">
<text class="title-text">专题E站</text>
</view>
<view class="special-content">
<view class="special-item" v-for="(item, index) in specialList" :key="index" @click="onEsiteClick(item)">
<up-image class="special-img" :src="item.image" width="100%" height="auto" mode="widthFix"></up-image>
</view>
</view>
</view>
<!-- 精品课 -->
<view class="course-section">
<view class="section-header">
<text class="section-title-text">精品课</text>
<view class="more-link" @click="goToCourseHome">
<text class="more-text">更多</text>
<uni-icons type="right" size="32rpx" color="#999"></uni-icons>
</view>
</view>
<scroll-view class="course-scroll" scroll-x="true" scroll-with-animation="true" show-scrollbar="false">
<view class="course-list">
<view class="course-item" v-for="(item, index) in courseList" :key="index">
<view class="course-card">
<up-image :src="item.avatar" width="464rpx" height="262rpx" ></up-image>
<view class="course-content">
<view class="course-title twoline">{{ item.title }}</view>
<view class="course-subtitle" v-if="item.upload_num==item.video_num">已完结</view>
<view class="course-subtitle" v-else>已更新{{item.upload_num}}课时</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
<!-- 精彩回放 -->
<view class="replay-section">
<view class="section-header">
<text class="section-title-text">精彩回放</text>
<view class="more-link">
<text class="more-text">更多<uni-icons type="right" size="32rpx" color="#999"></uni-icons></text>
</view>
</view>
<view class="replay-grid">
<view class="replay-item" v-for="(item, index) in replayList" :key="index" @click="onReplayClick(item)">
<view class="replay-card">
<up-image class="replay-img" :src="item.avatar" width="100%" height="auto" mode="widthFix"></up-image>
<view class="replay-content">
<text class="replay-text">{{ item.content }}</text>
</view>
</view>
</view>
</view>
</view>
<!-- 实用指南 -->
<view class="guide-section">
<!-- 顶部导航标签 -->
<view class="bg">
<up-image :src="bg" width="481rpx" height="112rpx" ></up-image>
</view>
<view class="guide-tabs">
<view class="tab-item"
v-for="(tab, index) in guideTabs"
:key="index"
:class="{ active: currentGuideTab === index }"
@click="switchGuideTab(index)"
>
<text class="tab-text">{{ tab.name }}</text>
<view class="tab-underline" v-if="currentGuideTab === index"></view>
</view>
<view class="tab-more" @click="onGuideMore">
<text class="more-text">更多</text>
<uni-icons type="right" size="32rpx" color="#999"></uni-icons>
</view>
</view>
<!-- 内容区域 -->
<view class="guide-content">
<view class="guide-list">
<view class="guide-item" v-for="(item, index) in guideList" :key="index" @click="onGuideClick(item)">
<view class="guide-info">
<text class="guide-item-title twoline">{{ item.title }}</text>
</view>
<view class="guide-action">
<text v-if="item.actionType === 'view'" class="action-view">查看</text>
<up-icon name="download" color="#8D2316" size="28" v-else></up-icon>
</view>
</view>
</view>
</view>
</view>
<!-- 自定义Tabbar -->
<custom-tabbar
ref="tabbarRef"
@tabChange="onTabChange"
></custom-tabbar>
</view>
<unidialog :visible="visible" :content="'有福利待领取'" @close="visible=false" ></unidialog>
<unidialog :visible="hasSign" content="今日已签到,每天只能签到一次。<br>请明日继续哦~" @close="hasSign=false" :showCancel="true" cancelText="关闭"></unidialog>
<up-overlay :show="showSign" >
<view class="signwrap">
<view class="signbox">
<view class="close" @click="showSign=false"></view>
<view class="signbg">
<up-image :src="signImg" width="604rpx" height="964rpx" ></up-image>
</view>
<view class="signcontent">
<view class="day">今天是我们相识的第{{signInfo.gdxzday}}</view>
<view class="signtotal">本周共签到{{signInfo.totalDay}}</view>
<view class="signcontinue">已经连续签到{{signInfo.continuous_day}}</view>
<view class="tip">连续签到获取更多积分</view>
<view class="news" @click.stop="goNews">
{{signInfo.news.summary}}
</view>
</view>
</view>
</view>
</up-overlay>
</template>
<script setup>
import { ref, reactive, onMounted, nextTick, computed } from 'vue';
import { onShow, onLoad, onPageScroll } from "@dcloudio/uni-app";
import CustomTabbar from '@/components/tabBar/tabBar.vue';
import unidialog from "@/components/dialog/dialog.vue"
import api from '@/api/api.js'
import navTo from "@/utils/navTo.js";
import docUrl from "@/utils/docUrl.js";
import bg from "@/static/more_bg.png"
import patient from "@/static/icon_home_my_patient.png"
import video from "@/static/icon_home_video.png"
import consult from "@/static/icon_home_my_public.png"
import library from "@/static/icon_home_my_library.png"
import course from "@/static/jingpingke.png"
import more from "@/static/home_more.png"
import livebg from "@/static/livebg.png"
import jing_sign from "@/static/jing_sign.png"
import bo_bg from "@/static/bo_bg.png"
import nosign from "@/static/home_no_qiandao_icon.png"
import sign from "@/static/home_qiandao_icon.png"
import signImg from "@/static/sign_in_bng_big.png"
import dayjs from 'dayjs'
const expertDetail=reactive({})
const showSign=ref(false)
const signInfo=reactive({
news:{
summary:''
}
})
// 定义refs
const tabbarRef = ref(null);
const visible=ref(false)
const hasUnread = ref(false)
const isSignedIn = ref(false) // 签到状态false-未签到true-已签到
const hasSign=ref(false)
// 滚动相关状态
const scrollTop = ref(0);
const bannerHeight = 400; // 轮播图高度单位rpx
// 获取设备像素比
const getPixelRatio = () => {
const systemInfo = uni.getSystemInfoSync();
return systemInfo.pixelRatio || 1;
};
const focus=()=>{
navTo({
url:'/pages_app/search/search'
})
}
// 计算头部背景色
const headerBgColor = computed(() => {
// 获取屏幕宽度来计算rpx到px的转换比例
const systemInfo = uni.getSystemInfoSync();
const screenWidth = systemInfo.screenWidth;
const rpxToPx = screenWidth / 750; // 750rpx = 屏幕宽度
const maxScroll = bannerHeight * rpxToPx; // 400rpx转换为px
const currentScroll = scrollTop.value;
const progress = Math.min(currentScroll / maxScroll, 1);
// 从透明渐变到绿色 (#8B2316)
const alpha = progress;
return `rgba(139, 34, 22, ${alpha})`;
});
// 轮播图相关
const current = ref(0);
const mode = ref('dot');
const dotsStyles = reactive({
backgroundColor: '#ddd',
border: '1px solid #ddd',
color: '#fff',
selectedBackgroundColor: '#8B2316',
selectedBorder: '1px solid #8B2316'
});
// 轮播图数据(仅图片)
const bannerList = reactive([]);
// 功能网格数据
const gridList = reactive([
{
icon: patient,
text: '我的患者'
},
{
icon: video,
text: '肝胆视频'
},
{
icon: consult,
text: '公益咨询'
},
{
icon: consult,
text: '指南杂志'
},
{
icon: '',
text: '肝胆新闻'
},
{
icon: '',
text: '肝胆课件'
},
{
icon: course,
text: '精品课'
},
{
icon: '',
text: '开具发票'
},
{
icon: more,
text: '更多'
}
]);
// 专题E站数据
const specialList = reactive([]);
// 消息通知数据
const noticeList = reactive([]);
// 精品课数据
const courseList = reactive([]);
// 精彩回放数据
const replayList = reactive([]);
// 实用指南标签页
const guideTabs = reactive([
{ name: '实用指南', type: 'guide' },
{ name: '课件分享', type: 'courseware' }
]);
// 当前选中的标签页
const currentGuideTab = ref(0);
// 实用指南展示数据(随标签切换填充)
const guideList = reactive([]);
// 存储两类原始数据:指南 与 课件分享
const guidesData = reactive([]);
const coursewareData = reactive([]);
// 轮播图切换事件
const change = (e) => {
current.value = e.detail.current;
};
// 消息通知切换事件
const onNoticeChange = (e) => {
console.log('消息通知切换:', e.detail.current);
};
// 使用 dayjs 格式化为 月日(如 8月6日
const formatToMonthDay = (val) => {
if (!val) return '';
const d = dayjs(val);
if (!d.isValid()) return '';
return d.format('M月D日');
};
// 消息通知点击事件
const onNoticeClick = (item) => {
console.log('点击消息通知:', item);
uni.showToast({
title: `查看${item.content}`,
icon: 'none'
});
// 根据消息类型跳转到不同页面
switch(item.type) {
case 'patient':
uni.navigateTo({
url: '/pages/patient/consultation'
});
break;
case 'meeting':
uni.navigateTo({
url: '/pages/meeting/live'
});
break;
case 'guide':
uni.navigateTo({
url: '/pages/guide/list'
});
break;
default:
uni.navigateTo({
url: '/pages/notice/detail?id=' + item.id
});
}
};
// 查看更多消息
const onNoticeMore = () => {
console.log('查看更多消息');
uni.navigateTo({
url: '/pages/notice/list'
});
};
// 精彩回放点击事件
const onReplayClick = (item) => {
console.log('点击精彩回放:', item);
uni.showToast({
title: `查看${item.content}`,
icon: 'none'
});
// 根据类型跳转到不同页面
switch(item.type) {
case 'case_discussion':
uni.navigateTo({
url: '/pages/discussion/detail?id=' + item.id
});
break;
case 'new_topic':
uni.navigateTo({
url: '/pages/topic/detail?id=' + item.id
});
break;
default:
uni.navigateTo({
url: '/pages/replay/detail?id=' + item.id
});
}
};
// 网格点击事件
const onClick = (index) => {
console.log('点击了第' + index + '个');
let url=''
if(index==0){
url='/pages_app/patientMsg/patientMsg'
}else if(index==1){
url='/pages_app/video/video'
}else if(index==2){
url='/pages_app/consult/consult'
}else if(index==3){
url='/pages_app/zhinan/zhinan'
}else if(index==4){
url='/pages_app/news/news'
}else if(index==5){
url='/pages_app/ppt/ppt'
}else if(index==6){
url='/pages_course/index/index'
}else{
url='/pages_app/search/search'
}
navTo({
url:url
})
};
// Tab切换事件
const onTabChange = (data) => {
console.log('Tab切换:', data);
uni.showToast({
title: `切换到${data.item.text}`,
icon: 'none'
});
};
// 切换实用指南标签页
const switchGuideTab = (index) => {
currentGuideTab.value = index;
// 0: 实用指南 -> guidesData1: 课件分享 -> coursewareData
guideList.length = 0;
if (index === 0) {
guideList.push(...guidesData);
} else {
guideList.push(...coursewareData);
}
};
// 查看更多实用指南
const onGuideMore = () => {
console.log('查看更多实用指南');
uni.navigateTo({
url: '/pages/guide/list'
});
};
const goNews=()=>{
let url=docUrl+signInfo.news.path;
// #ifdef H5
window.open(url, '_blank');
// #endif
// #ifdef APP-PLUS
plus.runtime.openURL(url);
// #endif
// #ifdef MP
const encoded = encodeURIComponent(url);
uni.navigateTo({
url: `/pages_app/webview/webview?url=${encoded}`
});
// #endif
}
// 点击顶部轮播图
const onBannerClick = (item,index) => {
if (!item) return;
if(index==0){
}else{
// 如果存在外链path优先按平台打开
if (item.path) {
// #ifdef H5
window.open(item.path, '_blank');
// #endif
// #ifdef APP-PLUS
plus.runtime.openURL(item.path);
// #endif
// #ifdef MP
const encoded = encodeURIComponent(item.path);
uni.navigateTo({
url: `/pages_app/webview/webview?url=${encoded}`
});
// #endif
return;
}
// 如果是新闻类型且有uuid可跳转新闻详情H5
if (item.uuid) {
const url = `https://dev-doc.igandan.com/app/html/news/${item.uuid}.html`;
// #ifdef H5
window.open(url, '_blank');
// #endif
// #ifdef APP-PLUS
plus.runtime.openURL(url);
// #endif
// #ifdef MP
const encoded = encodeURIComponent(url);
uni.navigateTo({ url: `/pages_app/webview/webview?url=${encoded}` });
// #endif
}
}
};
// 点击专题E站图片
const onEsiteClick = (item) => {
if (!item || !item.url) {
return;
}
// H5 端
// #ifdef H5
window.open(item.url, '_blank');
// #endif
// App 端
// #ifdef APP-PLUS
plus.runtime.openURL(item.url);
// #endif
// 小程序端:使用内嵌 webview 页面打开
// #ifdef MP
const encoded = encodeURIComponent(item.url)
uni.navigateTo({
url: `/pages_app/webview/webview?url=${encoded}`
})
// #endif
};
// 实用指南点击事件
const onGuideClick = (item) => {
// 如果有PDF链接直接打开
if (item.path) {
const pdfUrl = docUrl+item.path;
console.log(pdfUrl)
if (pdfUrl) {
// H5 端
// #ifdef H5
window.open(pdfUrl, '_blank');
// #endif
// App 端
// #ifdef APP-PLUS
plus.runtime.openURL(pdfUrl);
// #endif
// 小程序端:使用内嵌 webview 页面打开
// #ifdef MP-WEIXIN
const encoded = encodeURIComponent(pdfUrl);
uni.navigateTo({
url: `/pages_app/webview/webview?url=${encoded}`
});
// #endif
return;
}
}
// 没有PDF链接时根据类型跳转到不同页面
// if (item.type === 'guide') {
// uni.navigateTo({
// url: '/pages/guide/detail?id=' + item.id
// });
// } else if (item.type === 'courseware') {
// uni.navigateTo({
// url: '/pages/courseware/list'
// });
// }
};
// 测试tabbar功能的方法
const testTabbar = () => {
nextTick(() => {
if (tabbarRef.value) {
// 设置徽章数量
tabbarRef.value.setBadge(1, 10);
// 显示红点
tabbarRef.value.showRedDot(2);
// 3秒后隐藏红点
setTimeout(() => {
tabbarRef.value.hideRedDot(2);
}, 3000);
}
});
};
// 获取tabbar状态
const getTabbarStatus = () => {
if (tabbarRef.value) {
const currentTab = tabbarRef.value.getCurrentTab();
console.log('当前tab状态:', currentTab);
}
};
// 获取首页数据
const getHomeData = async () => {
try {
uni.showLoading({ title: '加载中...' });
const res = await api.getHomeData();
console.log('首页数据:', res);
if (res && res.data) {
const data = res.data;
Object.assign(expertDetail,data.expertDetail)
// 未读消息红点
hasUnread.value = !!data.has_unread;
// 签到状态
isSignedIn.value = data.sign_in === 1;
// 福利待领取弹窗
if (data.welfare_notice && data.welfare_notice.receive_notice) {
visible.value = true;
}
// 顶部轮播图news_list图片+可跳转)
bannerList.length = 0;
if (Array.isArray(data.news_list) && data.news_list.length > 0) {
bannerList.push(
...data.news_list.map(item => ({
image: item.headImg || '',
type: item.type, // 0: H5链接, 1: 图片无跳转 等
path: item.path || '',
uuid: item.uuid || ''
}))
);
} else if (Array.isArray(data.esite_list) && data.esite_list.length > 0) {
bannerList.push({ image: data.esite_list[0].img_path || '' });
}
// 功能网格icons_list -> gridList
if (Array.isArray(data.icons_list) && data.icons_list.length > 0) {
gridList.length = 0;
gridList.push(
...data.icons_list.map(item => ({
icon: item.img || '',
text: item.name || ''
}))
);
gridList.push({
icon:more,
text:'更多'
})
}
// 消息通知meeting_list -> noticeList含日期
if (Array.isArray(data.meeting_list) && data.meeting_list.length > 0) {
noticeList.length = 0;
noticeList.push(
...data.meeting_list.map((item, idx) => ({
id: item.id || item.uuid || idx + 1,
content: item.title || item.name || '',
time: item.begin_date || item.start_time || item.time || item.create_date || '',
type: 'meeting',
path: item.path || ''
}))
);
}
// 专题E站esite_list -> specialList仅图片最多展示3个
if (Array.isArray(data.esite_list) && data.esite_list.length > 0) {
specialList.length = 0;
specialList.push(
...data.esite_list.slice(0, 3).map(item => ({
image: item.img_path || '',
url: item.url || ''
}))
);
}
// 精品课excellencourse_list -> courseList
if (Array.isArray(data.excellencourse_list) && data.excellencourse_list.length > 0) {
courseList.length = 0;
courseList.push(
...data.excellencourse_list.map(item => ({
title: item.title || '',
status: item.video_num != null ? `${item.video_num}` : '',
avatar: item.index_img || ''
}))
);
}
// 精彩回放video_list -> replayList
if (Array.isArray(data.video_list) && data.video_list.length > 0) {
replayList.length = 0;
replayList.push(
...data.video_list.map(item => ({
id: item.uuid || item.polyv_uuid || Math.random().toString(36).slice(2),
avatar: item.imgpath || '',
content: item.name || '',
type: 'case_discussion'
}))
);
}
// 实用指南guide_ist存 guidesData
guidesData.length = 0;
if (Array.isArray(data.guide_ist) && data.guide_ist.length > 0) {
guidesData.push(
...data.guide_ist.map(item => ({
id: item.article_uuid || '',
title: item.title || '',
description: '',
actionType: 'download',
type: 'courseware',
path: item.path || ''
}))
);
}
// 课件分享gandanfile_list存 coursewareData
coursewareData.length = 0;
if (Array.isArray(data.gandanfile_list) && data.gandanfile_list.length > 0) {
coursewareData.push(
...data.gandanfile_list.map(item => ({
id: item.article_uuid || '',
title: item.title || '',
description: '',
actionType: 'download',
type: 'courseware',
path: item.path || ''
}))
);
}
// 默认展示当前选中标签的数据
guideList.length = 0;
if (currentGuideTab.value === 0) {
guideList.push(...guidesData);
} else {
guideList.push(...coursewareData);
}
}
} catch (error) {
console.error('获取首页数据失败:', error);
uni.showToast({
title: '数据加载失败',
icon: 'none'
});
} finally {
uni.hideLoading();
}
};
// 页面滚动监听
onPageScroll((e) => {
scrollTop.value = e.scrollTop;
// 调试信息
if (scrollTop.value % 50 === 0) { // 每滚动50px打印一次
console.log('滚动位置:', scrollTop.value, '背景色:', headerBgColor.value);
}
});
// 页面加载
onLoad(() => {
console.log('首页加载完成');
});
// 页面显示
onShow(() => {
console.log('首页显示');
// 获取首页数据
getHomeData();
// 页面加载完成后测试tabbar功能
testTabbar();
// 5秒后获取tabbar状态
setTimeout(() => {
getTabbarStatus();
}, 5000);
});
// 跳转到精品课首页
const goToCourseHome = () => {
uni.navigateTo({
url: '/pages_course/course/course'
});
};
// 签到点击事件
const onSignClick = async () => {
// 如果已经签到,显示提示
if (isSignedIn.value) {
hasSign.value=true;
return;
}
try {
// 调用添加积分接口
const res = await api.addBonusPointsN({
score_type:1
});
if (res && res.code ==1) {
// 签到成功
isSignedIn.value = true;
uni.showToast({
title: '签到成功,获得'+res.bonuspoints+'积分',
icon: 'none'
});
Object.assign(signInfo,res);
// 显示签到弹窗
showSign.value = true;
} else {
uni.showToast({
title: res?.msg || '签到失败',
icon: 'none'
});
}
} catch (error) {
console.error('签到失败:', error);
uni.showToast({
title: '签到失败,请重试',
icon: 'none'
});
}
};
// 暴露方法给父组件(如果需要)
defineExpose({
testTabbar,
getTabbarStatus,
goToCourseHome,
onSignClick
});
</script>
<style>
.signwrap{
display: flex;
align-items: center;
justify-content: center;
height:100%;
}
.signbox{
display: flex;
flex-direction: column;
align-items: center;
position: relative;
z-index:0;
}
.signbox .close{
position:absolute;
right:0;
height:60rpx;
width:60rpx;
opacity: 0;
background:#fff;
z-index:2;
border-radius: 50%;;
}
.signcontent{
width:100%;
top:0;
position: absolute;
z-index:1;
}
.signcontent .day{
margin-top: 384rpx;
text-align: center;
}
.signtotal{
margin-top: 30rpx;
text-align: center;
font-size: 30rpx;
}
.signcontinue{
font-size: 30rpx;
text-align: center;
}
.signcontent .tip{
margin-top: 40rpx;
color:red;
font-size: 28rpx;
text-align: center;
}
.signcontent .news{
margin: 196rpx 60rpx 0;
height: 116rpx;
font-size: 30rpx;
}
.signbg{
width:604rpx;
height:964rpx;
}
.container {
background-color: #f5f5f5;
min-height: 100vh;
padding-bottom: 120rpx; /* 为tabbar留出空间 */
}
/* 状态栏 */
.status-bar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10rpx 30rpx;
background-color: #ffffff;
font-size: 24rpx;
color: #333;
}
.status-center {
display: flex;
align-items: center;
gap: 10rpx;
}
/* 头部搜索栏 */
.header {
top:0rpx;
position: fixed;
left:0rpx;
right:0rpx;
height: 210rpx;
z-index: 99;
transition: background-color 0.3s ease;
}
.header-content {
padding: 0 20rpx;
display: flex;
align-items: center;
margin-top: 80rpx;
}
.header-left, .header-right {
position: relative;
}
.calendar-icon, .message-icon {
position: relative;
}
.red-dot {
position: absolute;
top: -4rpx;
right: -4rpx;
width: 16rpx;
height: 16rpx;
background-color: #ff0000;
border-radius: 50%;
}
.search-container {
flex: 1;
position: relative;
}
.search-container .mask{
position: absolute;
width:100%;
height:100%;
z-index:1;
}
/* 轮播图 */
.banner-section {
position: relative;
}
/* 消息通知 */
.notice-section {
margin: 20rpx 0rpx;
background: url('@/static/lunbo_bg.png') no-repeat 0 0;
background-size: cover;
overflow: hidden;
}
.notice-container {
display: flex;
align-items: center;
padding: 0rpx 30rpx;
}
.notice-icon {
margin-right: 20rpx;
display: flex;
align-items: center;
}
.notice-content {
flex: 1;
height: 94rpx;
overflow: hidden;
}
.notice-swiper {
height: 100%;
}
.notice-item {
height: 94rpx;
display: flex;
align-items: center;
justify-content: space-between;
cursor: pointer;
}
.notice-text {
flex: 1;
font-size: 26rpx;
color: #333;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
margin-right: 20rpx;
}
.notice-time {
font-size: 22rpx;
color: #999;
flex-shrink: 0;
}
.notice-more {
margin-left: 20rpx;
display: flex;
align-items: center;
padding: 10rpx;
}
.swiper-box {
height: 400rpx;
}
.banner-item {
height: 100%;
overflow: hidden;
position: relative;
}
.doctorInfo{
position: absolute;
top:200rpx;
z-index:9;
left:30rpx;
right:30rpx;
color:#fff;
font-size: 40rpx;
}
.doctorInfo .hospital{
margin-top: 20rpx;
font-size: 32rpx;
}
.banner-content {
height: 100%;
display: flex;
flex-direction: column;
justify-content: space-between;
padding: 40rpx;
color: white;
}
.banner-text {
z-index: 2;
}
.banner-title {
display: block;
font-size: 36rpx;
font-weight: bold;
margin-bottom: 10rpx;
}
.banner-subtitle {
display: block;
font-size: 28rpx;
opacity: 0.9;
}
.banner-scene {
display: flex;
justify-content: space-between;
align-items: flex-end;
font-size: 48rpx;
}
/* 功能网格 */
.grid-section {
padding: 30rpx;
background-color: #fff;
overflow: hidden;
}
.grid-item {
display: flex;
flex-direction: column;
align-items: center;
padding: 40rpx 20rpx;
}
.grid-icon {
font-size: 64rpx;
margin-bottom: 16rpx;
}
.grid-text {
font-size: 24rpx;
color: #333;
text-align: center;
}
/* 专题E站 */
.special-section {
margin: 30rpx;
}
.section-title {
margin-bottom: 30rpx;
}
.title-text {
font-size: 36rpx;
font-weight: bold;
color: #333;
}
.special-content {
display: flex;
flex-direction: column;
gap: 20rpx;
background-color: #fff;
padding: 20rpx;
border-radius: 10rpx;
}
/* 专题E站图片项宽度铺满高度自适应 */
.special-item {
position: relative;
width: 100%;
overflow: hidden;
}
.special-img {
width: 100%;
display: block;
}
.special-card {
display: flex;
justify-content: space-between;
align-items: center;
padding: 30rpx;
border-radius: 16rpx;
color: white;
}
.special-left {
flex: 1;
}
.special-title {
display: block;
font-size: 28rpx;
font-weight: bold;
margin-bottom: 10rpx;
}
.special-desc {
display: block;
font-size: 24rpx;
opacity: 0.9;
}
.special-right {
display: flex;
align-items: center;
gap: 20rpx;
}
.special-icon {
font-size: 40rpx;
}
.special-arrow {
font-size: 36rpx;
font-weight: bold;
}
/* 精品课 */
.course-section {
background-color: #fff;
padding-bottom: 40rpx;
}
.section-header {
padding: 35rpx 30rpx 0;
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
}
.section-title-text {
font-weight: bold;
font-size: 34rpx;
color: #000000;
}
.more-link {
display: flex;
align-items: center;
gap: 10rpx;
}
.more-text {
font-size: 30rpx;
color: #999;
}
.course-scroll {
white-space: nowrap;
margin-left: 30rpx;
margin-right: 30rpx;
overflow: hidden;
}
.course-list {
display: inline-flex;
gap: 30rpx;
width: auto;
padding-right: 60rpx; /* 让最后一项与右边留出更大间距 */
}
.course-item {
display: inline-block;
background-color: #f4f4f4;
width: 464rpx;
box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.1);
border-radius: 24rpx;
overflow: hidden;
}
.course-header {
display: flex;
justify-content: space-between;
align-items: flex-start;
margin-bottom: 20rpx;
}
.course-icon {
font-size: 48rpx;
}
.course-ribbon {
background-color: #007aff;
color: white;
padding: 4rpx 16rpx;
border-radius: 8rpx;
font-size: 20rpx;
}
.course-title {
white-space: normal;
font-size: 30rpx;
color: #333333;
margin: 20rpx;
/* 固定两行高度并省略 */
line-height: 40rpx;
height: 80rpx;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
text-overflow: ellipsis;
}
.course-subtitle {
display: block;
font-size: 24rpx;
color: #8B2316;
margin: 20rpx;
text-align: right;
padding-bottom: 25rpx;
}
.course-teacher {
display: block;
font-size: 24rpx;
color: #666;
line-height: 1.4;
}
.course-footer {
display: flex;
justify-content: flex-start;
}
.course-tags {
display: flex;
gap: 10rpx;
}
.tag {
font-size: 32rpx;
}
/* 精彩回放 */
.replay-section {
margin: 30rpx;
}
.replay-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 20rpx;
}
.replay-item {
cursor: pointer;
}
.replay-card {
background-color: white;
border-radius: 16rpx;
overflow: hidden;
box-shadow: 0 2rpx 8rpx rgba(0,0,0,0.1);
transition: transform 0.2s ease;
}
.replay-card:active {
transform: scale(0.98);
}
.replay-image { /* 不再使用固定高容器,保留占位以防其它样式引用 */
width: 100%;
overflow: hidden;
}
.doctor-avatar {
width: 100%;
height: 100%;
object-fit: cover;
}
/* 新增:精彩回放图片自适应 */
.replay-img{
width: 100%;
height: auto;
display: block;
}
.replay-content {
padding: 20rpx;
}
.replay-text {
font-size: 26rpx;
height: 72rpx;
color: #333;
line-height: 1.4;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
/* 实用指南 */
.guide-section {
background: white;
position: relative;
overflow: hidden;
}
.guide-section .bg{
position: absolute;
right:0;
top:5rpx;
z-index:0;
}
.guide-tabs {
position: relative;
z-index:1;
display: flex;
justify-content: space-between;
padding: 35rpx 30rpx;
}
.tab-item {
display: flex;
flex-direction: column;
align-items: center;
padding: 0 20rpx;
cursor: pointer;
}
.guide-tabs .tab-item:nth-child(2){
margin-left: -170rpx;
}
.tab-text {
font-size: 28rpx;
color: #666666;
}
.tab-item.active .tab-text {
color: #000;
font-size: 34rpx;
font-weight: bold;
}
.tab-underline {
width: 64rpx;
height: 4rpx;
background-color: #8B2316;
border-radius: 2rpx;
margin-top: 4rpx;
}
.tab-more {
display: flex;
align-items: center;
/* padding: 10rpx 20rpx; */
color: #999;
font-size: 28rpx;
}
.guide-content {
padding: 20rpx 30rpx;
}
.guide-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
}
.guide-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.guide-more {
display: flex;
align-items: center;
gap: 10rpx;
color: #999;
font-size: 28rpx;
}
.guide-list {
display: flex;
flex-direction: column;
gap: 20rpx;
}
.guide-item {
display: flex;
background: #F4F4F4;
border-radius: 10rpx;
justify-content: space-between;
align-items: center;
padding: 20rpx;
cursor: pointer;
}
.guide-item:last-child {
border-bottom: none;
}
.guide-item:active {
background-color: #f5f5f5;
}
.guide-info {
flex: 1;
margin-right: 20rpx;
}
.guide-item-title {
font-size: 28rpx;
color: #333333;
}
.guide-item-desc {
font-size: 24rpx;
color: #666;
line-height: 1.4;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
text-overflow: ellipsis;
}
.guide-action {
display: flex;
align-items: center;
gap: 10rpx;
color: #007aff;
font-size: 28rpx;
flex-shrink: 0;
}
.action-view {
font-size: 24rpx;
color: #8D2316;
}
/* 响应式调整 */
@media (max-width: 750rpx) {
.course-item {
width: 500rpx;
}
.grid-item {
padding: 30rpx 10rpx;
}
.grid-icon {
font-size: 56rpx;
}
.replay-grid {
grid-template-columns: 1fr;
gap: 15rpx;
}
.replay-image {
height: 180rpx;
}
.replay-text {
font-size: 24rpx;
}
.guide-tabs {
padding: 15rpx 0;
}
.tab-text {
font-size: 26rpx;
}
.guide-content {
padding: 15rpx 20rpx;
}
.guide-item-title {
font-size: 28rpx;
color:#333;
}
.guide-item-desc {
font-size: 22rpx;
}
.action-view {
font-size: 26rpx;
}
}
:deep(.uni-grid-item__box){
border: none !important;
}
:deep(.uni-grid){
border: none !important;
}
.notice-cell{
display: flex;
height:94rpx;
align-items: center;
}
.timebox{
margin-top: -5rpx;
}
.timebox .top{
display: flex;
}
.timebox .date{
width: 129rpx;
height: 31rpx;
font-size: 24rpx;
color:#fff;
text-align: center;
background-size:cover;
background: url('@/static/bo_bg.png') no-repeat 0 0;
}
.bar{
width: 2rpx;
height: 58rpx;
margin:0 14rpx;
background: #C5C5C5;
border-radius: 1rpx;
}
:deep(.uni-searchbar__box ){
height: 60rpx!important;
}
</style>