2025-10-14 17:46:23 +08:00

1156 lines
27 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="content">
<!-- 顶部导航栏 -->
<uni-nav-bar
left-icon="left"
:title="title"
@clickLeft="goBack"
fixed
color="#8B2316"
height="180rpx"
:border="false"
backgroundColor="#eee"
>
<template #right>
<view class="nav-right" v-if="activeTab === 'message'">
<uni-icons type="search" size="24" color="#8B2316" @click="searchPatients"></uni-icons>
<uni-icons type="staff" size="24" color="#8B2316" @click="managePatients" style="margin-left: 30rpx;"></uni-icons>
</view>
<view class="nav-right" v-else-if="activeTab === 'list'">
<uni-icons type="search" size="24" color="#8B2316" @click="searchPatients"></uni-icons>
<uni-icons type="plusempty" size="24" color="#8B2316" @click="goCode" style="margin-left: 30rpx;" ></uni-icons>
</view>
<view class="nav-right" v-else-if="activeTab === 'plan'" @click="showAddMenu">
<view class="save-btn">保存</view>
</view>
</template>
</uni-nav-bar>
<!-- 消息列表区域 -->
<scroll-view
class="message-list"
v-if="activeTab === 'message'"
scroll-y="true"
refresher-enabled="true"
:refresher-triggered="isRefreshing"
@refresherrefresh="onRefresh"
>
<ConversationList />
<!-- 消息项 -->
<!-- <view class="message-item" v-for="(item, index) in messageList" :key="item.id || index" @click="openMessage(item)">
<view class="message-avatar">
<view class="avatar-placeholder" v-if="!item.avatar">
<uni-icons type="person" size="32" color="#ffffff"></uni-icons>
</view>
<image v-else :src="item.avatar" class="patient-avatar" mode="aspectFill"></image>
</view>
<view class="message-content">
<view class="message-header">
<text class="patient-name">{{ item.patientName }}</text>
<text class="message-time">{{ item.time }}</text>
</view>
<view class="message-preview">
<text class="preview-text">{{ item.messagePreview }}</text>
</view>
</view>
</view>
<!-- 空状态提示 -->
<!-- <view class="empty-state" v-if="messageList.length === 0 && !isRefreshing">
<uni-icons type="chat" size="80" color="#cccccc"></uni-icons>
<text class="empty-text">暂无患者消息</text>
<text class="empty-subtext">下拉刷新获取最新申请</text>
<view class="debug-actions">
<button class="debug-btn" @click="getApplyList">测试API调用</button>
</view>
</view> -->
</scroll-view>
<!-- 患者列表区域 -->
<view class="patient-list" v-if="activeTab === 'list'">
<!-- 特殊操作项 -->
<view class="special-actions">
<view class="action-item" @click="addNewPatient">
<view class="action-icon new-patient">
<uni-icons type="person" size="24" color="#ffffff"></uni-icons>
<uni-icons type="plus" size="16" color="#ffffff" style="position: absolute; right: 8rpx; bottom: 8rpx;"></uni-icons>
</view>
<text class="action-text">新的患者<text class="new-patient-count" v-if="applyList.length > 0">(待审核{{ applyList.length }})</text></text>
<uni-icons type="right" size="20" color="#999"></uni-icons>
</view>
<view class="action-item" @click="managePatientGroups">
<view class="action-icon group-icon">
<view class="grid-icon">
<view class="grid-item"></view>
<view class="grid-item"></view>
<view class="grid-item"></view>
<view class="grid-item"></view>
</view>
</view>
<text class="action-text">患者分组 <text class="new-patient-count" v-if="patientList.length > 0">(随访{{ patientList.length }})</text></text>
<uni-icons type="right" size="20" color="#999"></uni-icons>
</view>
</view>
<view class="listbox">
<!-- 使用 up-index-list 索引组件数据动态渲染 -->
<up-index-list :index-list="indexList" custom-nav-height="180rpx" v-if="patientList.length > 0">
<template v-for="group in patientGroups" :key="group.letter">
<up-index-item >
<up-index-anchor :text="group.letter" />
<view class="group-section">
<view class="patient-item" v-for="item in group.items" :key="item.uuid || item.id" >
<template v-if="item.placeholder">
<view class="patient-avatar-placeholder">
<uni-icons type="person" size="32" color="#ffffff"></uni-icons>
</view>
</template>
<template v-else>
<image class="patient-avatar" :src="docUrl+item.photo" mode="aspectFill"></image>
</template>
<view class="patient-info" @click="goPatientDetail(item.uuid)">
<text class="patient-name">{{ item.realName }}</text>
<view class="patient-badge" v-if="item.badge">
<text class="badge-text">{{ item.badge }}</text>
</view>
</view>
<view class="patient-status">
<uni-icons type="compose" size="20" color="#8B2316" @click.stop="editPatient(item.uuid)"></uni-icons>
<text class="follow-date">随访于{{ formatYMD(item.join_date) }}</text>
</view>
</view>
</view>
</up-index-item>
</template>
</up-index-list>
<empty v-else></empty>
</view>
</view>
<view class="plan" v-if="activeTab === 'plan'">
<scroll-view
class="plan-scroll"
scroll-y="true"
refresher-enabled="true"
:refresher-triggered="followUpRefreshing"
@refresherrefresh="onFollowUpRefresh"
@scrolltolower="onFollowUpLoadMore"
:lower-threshold="100"
>
<view class="plan-list" v-if="groupedFollowUpList.length > 0">
<view class="plan-group" v-for="group in groupedFollowUpList" :key="group.yearMonth">
<view class="group-header">{{ group.yearMonth }}</view>
<view class="plan-card" v-for="item in group.items" :key="item.uuid" @click="goFollowDetail(item)">
<view class="left-rail">
<text class="day">{{ formatDay(item.datetime) }}</text>
</view>
<view class="linebox">
<up-image :src="lineImg" width="14rpx" height="180rpx" ></up-image>
</view>
<view class="right-content">
<view class="leftcontent">
<view class="note">{{ item.note }}</view>
<view class="name">{{ item.patientname }}</view>
</view>
<uni-icons type="forward" size="20" color="#999"></uni-icons>
</view>
</view>
</view>
<!-- 加载更多状态 -->
<view class="load-more" v-if="followUpLoading">
<uni-icons type="spinner-cycle" size="20" color="#999"></uni-icons>
<text class="load-text">加载中...</text>
</view>
<!-- 没有更多数据 -->
<view class="no-more" v-if="!followUpHasMore && followUpList.length > 0">
<text class="no-more-text">没有更多数据了</text>
</view>
</view>
<empty v-else></empty>
</scroll-view>
<!-- 悬浮添加按钮 -->
<!-- <view class="floating-add-btn" @click="showAddMenu">
<uni-icons type="plus" size="24" color="#ffffff"></uni-icons>
<text class="btn-text">添加</text>
</view> -->
<!-- 添加菜单弹窗 -->
<view class="add-menu-popup" v-if="showAddMenuFlag" @click="hideAddMenu">
<view class="menu-content" @click.stop>
<!-- 添加日程 -->
<view class="menu-item" @click="addSchedule">
<up-image :src="dayImg" width="34rpx" height="34rpx" ></up-image>
<text class="menu-text">添加日程</text>
</view>
<!-- 分割线 -->
<view class="menu-divider"></view>
<!-- 添加随访计划 -->
<view class="menu-item" @click="addFollowUpPlan">
<up-image :src="planImg" width="34rpx" height="34rpx" ></up-image>
<text class="menu-text">添加随访计划</text>
</view>
</view>
</view>
</view
<!-- 底部标签栏 -->
<view class="tab-bar">
<view class="tab-item" :class="{active: activeTab === 'message'}" @click="switchTab('message')">
<text class="tab-text">患者消息</text>
</view>
<view class="tab-item" :class="{active: activeTab === 'list'}" @click="switchTab('list')">
<text class="tab-text">患者列表</text>
</view>
<view class="tab-item" :class="{active: activeTab === 'plan'}" @click="switchTab('plan')">
<text class="tab-text">随访计划</text>
</view>
</view>
</view>
</template>
<script setup>
import { ref, getCurrentInstance, computed } from 'vue';
import { onShow,onLoad} from "@dcloudio/uni-app";
import dayImg from "@/static/visit_data11.png"
import planImg from "@/static/visitplan.png"
import api from '@/api/api.js';
import navTo from '@/utils/navTo.js';
import docUrl from '@/utils/docUrl.js';
const patientList = ref([]);
import pinyin from 'pinyin';
import dayjs from 'dayjs'
import lineImg from "@/static/item_visitplan_fg.png"
import ConversationList from './conversation-list/index.vue'
const title = ref('患者消息');
const goPatientDetail = (uuid) => {
navTo({
url: `/pages_app/patientDetail/patientDetail?uuid=${uuid}`
})
}
const editPatient = (uuid) => {
console.log(uuid)
navTo({
url: `/pages_app/patientSetting/patientSetting?uuid=${uuid}`
})
}
const goCode = () => {
navTo({
url: `/pages_app/myCode/myCode`
})
}
// 仅保留年月日
const formatYMD = (input) => {
if (!input) return '';
const d = dayjs(input);
return d.isValid() ? d.format('YYYY-MM-DD') : '';
}
const formatYearMonth = (input) => {
if (!input) return '';
const d = dayjs(input);
return d.isValid() ? d.format('YYYY年MM月') : '';
}
// 格式化显示日03
const formatDay = (input) => {
if (!input) return '';
const d = dayjs(input);
return d.isValid() ? d.format('DD日') : '';
}
// 申请列表数据
const messageList = ref([
{
id: 1,
patientName: '测试',
messagePreview: '[图片]',
time: '2025-08-11',
avatar: ''
}
]);
// 当前激活的标签
const activeTab = ref('message');
const letters = ref(['A','C','E','L']);
const activeLetter = ref('A');
const scrollIntoViewId = ref('');
let scrollingByClick = false;
// 控制添加菜单弹窗显示
const showAddMenuFlag = ref(false);
// 组件实例(用于 selectorQuery 作用域)
const { proxy } = getCurrentInstance();
// up-index-list 索引固定为 26 个大写字母
// 索引固定为 A-Z
const indexList = ref('ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split(''));
// 列表高度(像素):窗口高度 - 顶部导航(rpx转px) - 底部tab(约100rpx->px) - 操作区(约200rpx->px)
const groupsListHeight = ref(0);
const rpxToPx = (rpx) => {
const { screenWidth } = uni.getSystemInfoSync();
return Math.round((screenWidth / 750) * rpx);
};
const computeListHeight = () => {
const { windowHeight } = uni.getSystemInfoSync();
const reserved = rpxToPx(240); // 140rpx(nav) + 100rpx(tab) 近似
groupsListHeight.value = Math.max(0, windowHeight - reserved);
};
// 分组数据(可从接口返回后赋值)
const patientGroups = ref([]);
// 重建索引时保持固定 A-Z
const rebuildIndexList = () => {
// 固定 A-Z不随分组变化
indexList.value = patientGroups.value.map(g => g.letter);
};
// 生成模拟数据
// 工具:获取首字母
const generateMockDate = () => '';
const getFirstLetter = (chineseName) => {
// 假设名字由一个或多个汉字组成,我们取第一个汉字的首字母
const firstChar = chineseName.charAt(0); // 获取第一个汉字
const pinyinArray = pinyin(firstChar, { style: pinyin.STYLE_NORMAL }); // 获取拼音数组
return pinyinArray[0][0].charAt(0); // 返回拼音的第一个字母
}
// 根据 patientList 构建按拼音首字母的分组
const buildGroupsFromPatients = () => {
const map = new Map();
patientList.value.forEach((p) => {
const name = p.realName;
const first = getFirstLetter(name).toUpperCase();
const letter = /^[A-Z]$/.test(first) ? first : '#';
if (!map.has(letter)) map.set(letter, []);
map.get(letter).push(p);
});
const letters = Array.from(map.keys()).sort((a,b) => a.localeCompare(b));
patientGroups.value = letters.map(l => ({ letter: l, items: map.get(l) }));
rebuildIndexList();
};
// 申请列表数据
const applyList = ref([]);
// 刷新状态
const isRefreshing = ref(false);
const getFollowUpList = async (isRefresh = false) => {
if (followUpLoading.value) return;
followUpLoading.value = true;
try {
const currentPage = isRefresh ? 1 : page.value;
const res = await api.followUpList({
page: currentPage,
pageSize: followUpPageSize.value
});
if(res.code === 200) {
const newData = res.data.list || [];
if (isRefresh) {
// 下拉刷新:替换数据
followUpList.value = newData;
page.value = 1;
} else {
// 上拉加载:追加数据
followUpList.value = [...followUpList.value, ...newData];
}
// 判断是否还有更多数据
followUpHasMore.value = newData.length >= followUpPageSize.value;
if (!isRefresh) {
page.value++;
}
console.log('随访计划数据:', followUpList.value);
}
} catch (error) {
console.error('获取随访计划失败:', error);
uni.showToast({
title: '获取数据失败',
icon: 'error',
duration: 2000
});
} finally {
followUpLoading.value = false;
followUpRefreshing.value = false;
}
};
const getApplyList = async () => { // 申请列表
try {
let userInfo=uni.getStorageSync('userInfo')
const res = await api.applyList();
if (res && res.code === 200) {
applyList.value = res.data;
} else {
uni.showToast({
title: res.message || '获取申请列表失败',
icon: 'error',
duration: 2000
});
}
} catch (error) {
console.error('获取申请列表失败:', error);
uni.showToast({
title: '网络请求失败',
icon: 'error',
duration: 2000
});
}
};
const goBack = () => {
uni.reLaunch({
url: "/pages/index/index?from=push"
})
};
const patientListByGBK = async () => {
const res = await api.patientListByGBK();
if(res.code == 1){
patientList.value = res.data;
buildGroupsFromPatients()
}
};
const page=ref(1)
const followUpList = ref([]);
// 随访计划相关状态
const followUpLoading = ref(false);
const followUpRefreshing = ref(false);
const followUpHasMore = ref(true);
const followUpPageSize = ref(10);
// 按年月分组的随访计划数据
const groupedFollowUpList = computed(() => {
if (!followUpList.value || followUpList.value.length === 0) {
return [];
}
const groups = new Map();
followUpList.value.forEach(item => {
const yearMonth = formatYearMonth(item.datetime);
if (!groups.has(yearMonth)) {
groups.set(yearMonth, []);
}
groups.get(yearMonth).push(item);
});
// 转换为数组格式,按时间正序排列
return Array.from(groups.entries()).map(([yearMonth, items]) => ({
yearMonth,
items: items.sort((a, b) => new Date(a.datetime) - new Date(b.datetime))
})).sort((a, b) => new Date(a.items[0].datetime) - new Date(b.items[0].datetime));
});
// 下拉刷新
const onRefresh = async () => {
isRefreshing.value = true;
try {
await getApplyList();
uni.showToast({
title: '刷新成功',
icon: 'none',
duration: 1500
});
} catch (error) {
console.error('刷新失败:', error);
uni.showToast({
title: '刷新失败',
icon: 'error',
duration: 1500
});
} finally {
isRefreshing.value = false;
}
};
// 随访计划下拉刷新
const onFollowUpRefresh = async () => {
followUpRefreshing.value = true;
await getFollowUpList(true);
uni.showToast({
title: '刷新成功',
icon: 'none',
duration: 1500
});
};
// 随访计划上拉加载
const onFollowUpLoadMore = async () => {
if (!followUpHasMore.value || followUpLoading.value) return;
await getFollowUpList(false);
};
// 搜索患者
const searchPatients = () => {
navTo({
url: `/pages_app/searchPatient/searchPatient`
})
};
// 管理患者
const managePatients = () => {
uni.showToast({
title: '患者管理',
icon: 'none'
});
};
// 打开消息
const openMessage = (item) => {
uni.showToast({
title: `打开患者 ${item?.patientName || '未知'} 的消息`,
icon: 'none'
});
// 这里可以跳转到消息详情页面
// uni.navigateTo({
// url: `/pages_app/messageDetail/messageDetail?id=${item?.id}`
// });
};
// 切换标签
const switchTab = (tab) => {
activeTab.value = tab;
switch(tab) {
case 'message':
// 患者消息页面逻辑 - 刷新申请列表
getApplyList();
title.value = '患者消息';
break;
case 'list':
title.value = '患者列表';
// 显示患者列表
break;
case 'plan':
title.value = '随访计划';
// 随访计划页面 - 加载随访计划数据
if (followUpList.value.length === 0) {
getFollowUpList(true);
}
break;
}
};
// 添加新患者
const addNewPatient = () => {
navTo({
url: '/pages_app/myPatient/myPatient'
})
};
// 管理患者分组
const managePatientGroups = () => {
navTo({
url: '/pages_app/patientGroup/patientGroup'
})
};
// 打开患者详情
const openPatient = (patientName) => {
uni.showToast({
title: `打开患者: ${patientName}`,
icon: 'none'
});
};
// 添加随访计划
const addFollowUpPlan = () => {
showAddMenuFlag.value = false;
uni.navigateTo({
url: '/pages_app/visit/visit?from=patientMsg'
});
};
// 添加日程
const addSchedule = () => {
showAddMenuFlag.value = false;
uni.navigateTo({
url: '/pages_app/schedule/schedule'
});
};
const fromType=ref('');
// 显示添加菜单
const showAddMenu = () => {
showAddMenuFlag.value = true;
};
// 隐藏添加菜单
const hideAddMenu = () => {
showAddMenuFlag.value = false;
};
// 使用 up-index-list 后不再需要手动滚动联动逻辑
// 页面显示时加载数据
onLoad((options) => {
if(options.from == 'push'){
fromType.value='push';
}
loadMessageList();
computeListHeight();
getApplyList();
patientListByGBK();
});
onShow(() => {
followUpList.value = [];
page.value = 1;
followUpHasMore.value = true;
followUpLoading.value = false;
followUpRefreshing.value = false;
getFollowUpList(true);
});
// 加载消息列表
const loadMessageList = () => {
// 这里可以调用API获取消息列表
};
const goFollowDetail = (raw) => {
if(!raw) return;
navTo({
url: `/pages_app/followDetail/followDetail?followUpUuid=${encodeURIComponent(raw.uuid || '')}&patient_name=${raw.patientname}`
});
};
</script>
<style lang="scss" scoped>
.save-btn {
font-size: 32rpx;
color: #8b2316;
font-weight: 500;
}
.content {
background-color: #f5f5f5;
height: 100vh;
overflow-y: hidden;
}
.linebox{
margin:0 20rpx;
}
// 导航栏右侧按钮样式
.nav-right {
display: flex;
align-items: center;
}
// 消息列表样式
.message-list {
background-color: #ffffff;
margin-top: 20rpx;
.message-item {
display: flex;
align-items: center;
padding: 30rpx;
border-bottom: 1rpx solid #f0f0f0;
background-color: #ffffff;
&:last-child {
border-bottom: none;
}
.message-avatar {
margin-right: 20rpx;
.avatar-placeholder {
width: 80rpx;
height: 80rpx;
background-color: #ff6b6b;
border-radius: 10rpx;
display: flex;
align-items: center;
justify-content: center;
}
}
.message-content {
flex: 1;
.message-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10rpx;
}
.patient-name {
font-size: 32rpx;
color: #333333;
font-weight: 500;
}
.message-time {
font-size: 24rpx;
color: #999999;
}
.message-preview {
margin-top: 5rpx;
.preview-text {
font-size: 28rpx;
color: #666666;
}
}
}
}
// 空状态样式
.empty-state {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 100rpx 30rpx;
.empty-text {
margin-top: 20rpx;
font-size: 28rpx;
color: #999999;
}
.empty-subtext {
font-size: 26rpx;
color: #999999;
margin-top: 16rpx;
}
.debug-actions {
margin-top: 30rpx;
.debug-btn {
background-color: #8B2316;
color: #ffffff;
border: none;
padding: 16rpx 32rpx;
border-radius: 8rpx;
font-size: 26rpx;
}
}
}
}
// 底部标签栏样式
.tab-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
height: 100rpx;
background-color: #f8f8f8;
display: flex;
align-items: center;
border-top: 1rpx solid #e0e0e0;
z-index: 999;
.tab-item {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
height: 100%;
&:nth-child(2) {
border: 2rpx solid #ccc;
border-top: none;
border-bottom: none;
}
.tab-text {
font-size: 28rpx;
color: #999999;
transition: color 0.3s;
}
&.active {
.tab-text {
color: #8B2316;
font-weight: 500;
}
.tab-line {
position: absolute;
bottom: 0;
width: 60rpx;
height: 4rpx;
background-color: #8B2316;
border-radius: 2rpx;
}
}
}
}
// 患者列表样式
.patient-list {
height:calc(100vh - 265rpx);
overflow-y: scroll;
display: flex;
flex-direction:column;
background-color: #ffffff;
margin-top: 20rpx;
padding-bottom: 500rpx;
position: relative;
.listbox{
flex:1;
padding-bottom: 100rpx;
}
.groups-scroll {
display: none;
}
.special-actions {
background-color: #ffffff;
border-bottom: 1rpx solid #f0f0f0;
.action-item {
display: flex;
align-items: center;
padding: 30rpx;
border-bottom: 1rpx solid #f0f0f0;
&:last-child {
border-bottom: none;
}
.action-icon {
width: 60rpx;
height: 60rpx;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
margin-right: 20rpx;
position: relative;
&.new-patient {
background-color: #8B2316;
}
&.group-icon {
background-color: #8B2316;
.grid-icon {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
gap: 2rpx;
width: 32rpx;
height: 32rpx;
.grid-item {
background-color: #ffffff;
border-radius: 2rpx;
}
}
}
}
.action-text {
flex: 1;
font-size: 32rpx;
color: #333333;
.new-patient-count {
color: red;
font-size: 32rpx;
margin-left: 10rpx;
}
}
}
}
.letter-index {
position: fixed;
right: 10rpx;
top: 50%;
transform: translateY(-50%);
background-color: rgba(255, 255, 255, 0.9);
border-radius: 20rpx;
padding: 10rpx 5rpx;
z-index: 999;
.letter-item {
padding: 8rpx 12rpx;
font-size: 24rpx;
color: #666666;
text-align: center;
border-radius: 10rpx;
&.active {
color: #8B2316;
font-weight: 600;
}
&:active {
background-color: #f0f0f0;
}
}
}
}
.group-section {
.group-header {
padding: 20rpx 30rpx;
background-color: #e4e4e4;
font-size: 36rpx;
color: #666666;
font-weight: bold;
}
.patient-item {
display: flex;
align-items: center;
padding: 30rpx 80rpx 20rpx 30rpx;
border-bottom: 1rpx solid #f0f0f0;
background-color: #ffffff;
&:last-child {
border-bottom: none;
}
.patient-avatar,
.patient-avatar-placeholder {
width: 80rpx;
height: 80rpx;
border-radius: 10rpx;
margin-right: 20rpx;
display: flex;
align-items: center;
justify-content: center;
}
.patient-avatar-placeholder {
background-color: #ff6b6b;
}
.patient-info {
flex: 1;
.patient-name {
font-size: 32rpx;
color: #333333;
font-weight: 500;
margin-bottom: 8rpx;
}
.patient-badge {
background-color: #d4a574;
border-radius: 20rpx;
padding: 4rpx 12rpx;
display: inline-block;
.badge-text {
font-size: 20rpx;
color: #ffffff;
font-weight: 500;
}
}
}
.patient-status {
display: flex;
align-items: flex-end;
flex-direction: column;
.follow-date {
font-size: 24rpx;
color: #666666;
margin-left: 10rpx;
}
}
}
}
.floating-add-btn {
position: fixed;
bottom: 140rpx; /* Adjust based on nav-bar height */
right: 30rpx;
background-color: #8B2316;
border-radius: 50%;
width: 100rpx;
height: 100rpx;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
z-index: 999;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
.btn-text {
font-size: 20rpx;
color: #ffffff;
margin-top: 4rpx;
}
}
.add-menu-popup {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
}
.menu-content {
background-color: #ffffff;
border-radius: 20rpx;
box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.2);
width: 80%;
max-width: 400rpx;
overflow: hidden;
}
.menu-item {
display: flex;
align-items: center;
padding: 30rpx 40rpx;
border-bottom: 1rpx solid #f0f0f0;
&:last-child {
border-bottom: none;
}
.menu-text {
font-size: 32rpx;
color: #333333;
margin-left: 20rpx;
}
}
.menu-divider {
height: 1rpx;
background-color: #f0f0f0;
margin: 0 40rpx;
}
/* 随访计划样式 */
.plan{
position: fixed;
top: 180rpx;
left: 0;
right: 0;
bottom:110rpx;
}
.plan-scroll {
height: 100%;
}
.plan-list{
padding-bottom: 20rpx;
}
.plan-group{
background:#f5f5f5;
}
.group-header{
text-align: center;
background:#eee;
color:#333;
font-size: 30rpx;
padding: 20rpx 30rpx;
}
.plan-card{
display:flex;
align-items:center;
background:#fff;
padding: 26rpx 30rpx;
border-bottom:1rpx solid #f0f0f0;
}
.left-rail{
display:flex;
align-items:center;
color:#8B2316;
}
.left-rail .day{
font-size: 36rpx;
margin-right: 12rpx;
}
.left-rail .rail-dot{
width: 4rpx;
height: 60rpx;
background:#8B2316;
border-radius: 2rpx;
}
.right-content{
flex:1;
display:flex;
align-items:center;
justify-content:space-between;
}
.right-content .note{
font-size: 30rpx;
color:#333;
}
.right-content .name{
margin-top: 30rpx;
font-size: 28rpx;
color:#8B2316;
}
/* 加载状态样式 */
.load-more {
display: flex;
align-items: center;
justify-content: center;
padding: 30rpx;
color: #999;
.load-text {
margin-left: 10rpx;
font-size: 28rpx;
}
}
.no-more {
display: flex;
align-items: center;
justify-content: center;
padding: 30rpx;
.no-more-text {
font-size: 28rpx;
color: #999;
}
}
</style>