2025-09-23 19:00:32 +08:00

826 lines
17 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="outpatient-page">
<!-- 导航栏 -->
<uni-nav-bar
left-icon="left"
title="出/停诊公告"
@clickLeft="goBack"
fixed
color="#8B2316"
height="140rpx"
:border="false"
backgroundColor="#eee"
>
<template #right>
<view class="nav-right">
<up-icon name="share" color="#8B2316" size="24"></up-icon>
<up-icon name="map" color="#8B2316" size="24" @click="goSite"></up-icon>
</view>
</template>
</uni-nav-bar>
<!-- 标签页 -->
<view class="tab-container">
<view class="tab-item" :class="{ active: currentTab === 'suspension' }" @click="switchTab('suspension')">
<text class="tab-text">停诊公告</text>
</view>
<view class="tab-divider"></view>
<view class="tab-item" :class="{ active: currentTab === 'outpatient' }" @click="switchTab('outpatient')">
<text class="tab-text">门诊安排</text>
</view>
</view>
<!-- 主内容区域 -->
<view class="content-area">
<!-- 停诊公告卡片 -->
<view v-if="currentTab === 'suspension'">
<view class="announcement-card" v-for="announcement in stopOutPatientList" :key="announcement.uuid">
<view class="card-header">
<view class="date-tag">
<view class="tag-dot"></view>
<text class="tag-date">{{ formatDate(announcement.expire_date) }}</text>
</view>
<view class="delete-btn" @click="deleteAnnouncement(announcement.uuid)">
<text class="delete-icon"></text>
</view>
</view>
<view class="card-content">
<view class="info-row">
<text class="info-label">停诊原因:</text>
<text class="info-value">{{ getStopReason(announcement.type) }}</text>
</view>
<view class="info-row">
<text class="info-label">停诊时间:</text>
<text class="info-value">{{ announcement.date_list[0]?.param1 }} ~ {{ announcement.date_list[0]?.param2 }}</text>
</view>
<view class="info-row remarks-row">
<text class="info-label">备注:</text>
<view class="remarks-input" v-if="announcement.note">{{ announcement.note }}</view>
</view>
</view>
</view>
<!-- 空状态 -->
<view v-if="stopOutPatientList.length === 0" class="empty-state">
<text class="empty-text">暂无停诊公告</text>
</view>
</view>
<!-- 门诊安排内容 -->
<view v-if="currentTab === 'outpatient'">
<view v-if="outPatientList.length > 0" class="schedule-list">
<!-- 门诊安排列表 -->
<view class="schedule-card" v-for="schedule in outPatientList" :key="schedule.uuid">
<view class="cell-content">
<view class="schedule-left">
<view class="weekday">{{ getWeekdayByWeek(schedule.week) }}</view>
<view class="time-period">{{ getTimePeriod(schedule.day) }}</view>
</view>
<view class="schedule-right">
<view class="hospital-info">
<text class="hospital-name">{{ schedule.hospital_name || '首都医科大学附属北京佑安医院' }}</text>
<view class="office-info">
<text class="office-name">{{ schedule.office_name || '肝病科' }}</text>
</view>
<view class="location-info">
<text class="location">{{ schedule.location || '北京' }}</text>
<view class="type-tag" v-if="schedule.type">
{{ getTypeText(schedule.type) }}
</view>
</view>
</view>
</view>
</view>
<view class="schedule-actions">
<view class="action-btn edit-btn" @click="editSchedule(schedule)">
<text class="action-icon"></text>
<text class="action-text">编辑</text>
</view>
<view class="action-btn delete-btn" @click="deleteSchedule(schedule.uuid)">
<text class="action-icon">🗑</text>
<text class="action-text">删除</text>
</view>
</view>
</view>
</view>
<view v-else class="empty-state">
<text class="empty-text">暂无门诊安排</text>
</view>
</view>
</view>
<!-- 底部操作按钮 -->
<view class="bottom-actions">
<view class="publish-btn" @click="currentTab === 'suspension' ? publishNew() : addSchedule()">
<text class="btn-text">{{ currentTab === 'suspension' ? '发布新的停诊' : '增加门诊安排' }}</text>
</view>
</view>
<!-- 浮动编辑按钮 -->
<view class="floating-edit-btn" @click="editAnnouncement">
<text class="edit-icon"></text>
</view>
</view>
</template>
<script setup>
import { ref, reactive } from 'vue'
import api from '@/api/api'
import {onShow,onUnload,onLoad} from '@dcloudio/uni-app'
import navTo from '@/utils/navTo'
const page=ref(1);
// 响应式数据
const currentTab = ref('suspension')
const remarks = ref('')
const note = ref('')
const outpatientSchedules = ref([])
const outPatientList = ref([]);
const getListOutPatient = async () => {
const res = await api.listOutPatient({
page:page.value,
});
if(res.code == 200){
outPatientList.value = res.data.list.list;
console.log(res.data.note)
note.value = res.data.note.note;
}
}
const stopOutPatientList = ref([]);
const getStopOutPatientList = async () => {
const res = await api.stopOutPatientList();
if(res.code == 200){
stopOutPatientList.value = res.data;
}
}
// 数据转换函数
const formatDate = (timestamp) => {
if (!timestamp) return '';
const date = new Date(timestamp * 1000);
const year = date.getFullYear();
const month = String(date.getMonth() + 1).padStart(2, '0');
const day = String(date.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
const goSite = () => {
navTo({
url: '/pages_chat/addAddress/addAddress'
})
}
const getStopReason = (type) => {
const reasonMap = {
1: '出差',
2: '休假',
3: '临时安排',
4: '其他'
};
return reasonMap[type] || '其他';
}
// 获取星期几
const getWeekday = (date) => {
if (!date) return '周一';
const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
const d = new Date(date);
return weekdays[d.getDay()];
}
// 根据week字段获取星期几
const getWeekdayByWeek = (week) => {
const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
return weekdays[week] || '周一';
}
// 根据day字段获取时间段
const getTimePeriod = (day) => {
const timeMap = {
'a': '上午',
'p': '下午',
'd': '晚上'
};
return timeMap[day] || '晚上';
}
// 根据type字段获取类型文本
const getTypeText = (type) => {
const typeMap = {
1: '普通门诊',
2: '专家门诊',
3: '特需门诊',
4: '专科/专病门诊'
};
return typeMap[type] || '普通门诊';
}
// 方法
const goBack = () => {
uni.navigateBack({
delta: 1,
fail() {
uni.redirectTo({
url: '/pages/index/index'
})
}
})
}
const share = () => {
uni.showToast({
title: '分享功能',
icon: 'none'
})
}
const addNew = () => {
uni.showToast({
title: '添加新内容',
icon: 'none'
})
}
onLoad((options) => {
})
onShow(() => {
getStopOutPatientList();
getListOutPatient();
})
const switchTab = (tab) => {
currentTab.value = tab;
if(tab=='suspension'){
getStopOutPatientList();
}else{
getListOutPatient();
}
}
const deleteAnnouncement = async (uuid) => {
uni.showModal({
title: '确认删除',
content: '确定要删除这条停诊公告吗?',
success: async (res) => {
if (res.confirm) {
try {
const deleteRes = await api.deleteStopPatient({ uuid });
if (deleteRes.code === 200) {
uni.showToast({
title: '删除成功',
icon: 'none'
});
getStopOutPatientList();
} else {
uni.showToast({
title: deleteRes.msg || '删除失败',
icon: 'none'
});
}
} catch (error) {
uni.showToast({
title: '删除失败',
icon: 'none'
});
}
}
}
})
}
const publishNew = () => {
if(stopOutPatientList.value.length>=2){
uni.showToast({
title: '最多发布2条停诊公告',
icon: 'none'
})
return
}
// 跳转到发布新停诊页面
navTo({
url: '/pages_chat/stopPatient/stopPatient'
})
}
const editAnnouncement = () => {
navTo({
url: '/pages_chat/note/note?note='+note.value
})
}
// 刷新数据
const refreshData = () => {
getListOutPatient();
getStopOutPatientList();
}
// 门诊安排相关方法
const addSchedule = () => {
navTo({
url: '/pages_chat/outManage/outManage'
})
}
const editSchedule = (schedule) => {
uni.navigateTo({
url: `/pages_chat/outManage/outManage?uuid=${schedule.uuid}&workplace_uuid=${schedule.workplace_uuid}&week=${schedule.week}&type=${schedule.type}`
})
}
const deleteSchedule = async (uuid) => {
uni.showModal({
title: '确认删除',
content: '确定要删除这条门诊安排吗?',
success: async (res) => {
if (res.confirm) {
try {
const deleteRes = await api.deleteOutPatient({ uuid });
if (deleteRes.code === 200) {
outPatientList.value = outPatientList.value.filter(item => item.uuid !== uuid);
uni.showToast({
title: '删除成功',
icon: 'none'
});
getListOutPatient();
} else {
uni.showToast({
title: deleteRes.msg || '删除失败',
icon: 'none'
});
}
} catch (error) {
uni.showToast({
title: '删除失败',
icon: 'none'
});
}
}
}
})
}
</script>
<style lang="scss" scoped>
.outpatient-page {
min-height: 100vh;
background-color: #f5f5f5;
position: relative;
}
/* 状态栏样式 */
.status-bar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 20rpx 30rpx;
background-color: #fff;
font-size: 28rpx;
color: #333;
}
.status-right {
display: flex;
align-items: center;
gap: 10rpx;
}
.network-type {
font-size: 24rpx;
color: #666;
}
.signal-bars {
display: flex;
align-items: end;
gap: 2rpx;
margin: 0 10rpx;
}
.bar {
width: 4rpx;
background-color: #333;
border-radius: 1rpx;
}
.bar:nth-child(1) { height: 8rpx; }
.bar:nth-child(2) { height: 12rpx; }
.bar:nth-child(3) { height: 16rpx; }
.bar:nth-child(4) { height: 20rpx; }
.battery {
display: flex;
align-items: center;
}
.battery-text {
font-size: 24rpx;
color: #333;
}
/* 导航栏样式 */
.nav-bar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 20rpx 30rpx;
background-color: #fff;
border-bottom: 1rpx solid #eee;
}
.nav-left {
width: 60rpx;
}
.back-arrow {
font-size: 50rpx;
color: #8B2316;
}
.nav-center {
flex: 1;
text-align: center;
}
.nav-title {
font-size: 34rpx;
color: #8B2316;
}
.nav-right {
display: flex;
align-items: center;
gap: 20rpx;
width: 60rpx;
justify-content: flex-end;
}
.nav-icon {
width: 40rpx;
height: 40rpx;
display: flex;
align-items: center;
justify-content: center;
}
.icon-share {
font-size: 32rpx;
color: #666;
}
.add-icon {
background-color: #8B2316;
border-radius: 50%;
}
.icon-add {
font-size: 28rpx;
color: #fff;
}
/* 标签页样式 */
.tab-container {
display: flex;
align-items: center;
background-color: #fff;
padding: 0 30rpx;
border-bottom: 1rpx solid #eee;
}
.tab-item {
flex: 1;
text-align: center;
padding: 30rpx 0;
position: relative;
}
.tab-item.active .tab-text {
color: #8B2316;
}
.tab-text {
font-size: 30rpx;
color: #666;
}
.tab-divider {
width: 2rpx;
height: 40rpx;
background-color: #ddd;
}
/* 主内容区域 */
.content-area {
padding: 30rpx;
min-height: calc(100vh - 400rpx);
}
/* 停诊公告卡片 */
.announcement-card {
background-color: #fff;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 20rpx;
}
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
}
.date-tag {
display: flex;
align-items: center;
background-color: #20c997;
padding: 10rpx 20rpx;
border-radius: 20rpx;
gap: 10rpx;
}
.tag-dot {
width: 12rpx;
height: 12rpx;
background-color: #fff;
border-radius: 50%;
}
.tag-date {
color: #fff;
font-size: 24rpx;
}
.announcement-card .delete-btn {
width: 40rpx;
height: 40rpx;
background-color: #8B2316;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
}
.delete-icon {
color: #fff;
font-size: 24rpx;
}
.card-content {
/* 卡片内容样式 */
display: flex;
flex-direction: column;
}
.info-row {
display: flex;
align-items: center;
margin-bottom: 20rpx;
}
.info-label {
font-size: 28rpx;
color: #333;
margin-right: 20rpx;
min-width: 120rpx;
}
.info-value {
font-size: 28rpx;
color: #666;
flex: 1;
}
.remarks-row {
align-items: flex-start;
}
.remarks-input {
flex: 1;
background-color: #fff;
border-radius: 8rpx;
font-size: 28rpx;
color: #333;
}
/* 空状态样式 */
.empty-state {
display: flex;
align-items: center;
justify-content: center;
height: 400rpx;
}
.empty-text {
font-size: 28rpx;
color: #999;
}
/* 门诊安排样式 */
.schedule-list {
display: flex;
flex-direction: column;
gap: 20rpx;
}
.schedule-card {
background-color: #fff;
border-radius: 12rpx;
box-shadow: 0 2rpx 8rpx rgba(0, 0, 0, 0.1);
gap: 30rpx;
}
.cell-content {
padding: 0 30rpx;
display: flex;
align-items: flex-start;
}
.schedule-left {
height: 200rpx;
border-right: 2rpx solid #f0f0f0;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-width: 120rpx;
}
.weekday {
font-size: 36rpx;
color: #333;
margin-bottom: 10rpx;
}
.time-period {
font-size: 24rpx;
color: #666;
}
.schedule-right {
flex: 1;
height: 200rpx;
margin-left: 30prx;
display: flex;
flex-direction: column;
justify-content: center;
}
.hospital-name {
font-size: 28rpx;
color: #333;
line-height: 1.4;
margin-bottom: 15rpx;
display: block;
}
.office-info {
margin-bottom: 15rpx;
}
.office-name {
font-size: 32rpx;
color: #333;
}
.location-info {
display: flex;
align-items: center;
gap: 15rpx;
}
.location {
font-size: 28rpx;
color: #666;
}
.price-info {
display: flex;
align-items: center;
gap: 15rpx;
}
.hospital-info {
padding-left: 30rpx;
}
.price {
font-size: 32rpx;
color: #333;
}
.type-tag {
background-color: transparent;
border: 2rpx solid #8B2316;
border-radius: 20rpx;
padding:2rpx 16rpx;
font-size: 20rpx;
color: #8B2316;
display: flex;
align-items: center;
justify-content: center;
}
.schedule-actions {
padding: 30rpx;
border-top: 2rpx solid #f0f0f0;
display: flex;
gap: 30rpx;
justify-content: flex-end;
}
.action-btn {
display: flex;
align-items: center;
gap: 8rpx;
padding: 10rpx 20rpx;
border-radius: 8rpx;
cursor: pointer;
}
.edit-btn {
white-space: nowrap;
background-color: #f8f9fa;
border: 1rpx solid #dee2e6;
}
.schedule-actions .delete-btn {
background-color: #fff5f5;
border: 1rpx solid #fed7d7;
}
.action-icon {
font-size: 24rpx;
}
.action-text {
white-space: nowrap;
font-size: 24rpx;
color: #666;
}
.edit-btn .action-text {
color: #495057;
}
.delete-btn .action-text {
color: #e74c3c;
}
/* 底部操作按钮 */
.bottom-actions {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 30rpx;
background-color: #fff;
border-top: 1rpx solid #eee;
}
.publish-btn {
background-color: #8B2316;
border-radius: 12rpx;
padding: 25rpx;
text-align: center;
}
.btn-text {
color: #fff;
font-size: 32rpx;
}
/* 浮动编辑按钮 */
.floating-edit-btn {
position: fixed;
bottom: 120rpx;
right: 30rpx;
width: 80rpx;
height: 80rpx;
background-color: #20c997;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
box-shadow: 0 4rpx 12rpx rgba(32, 201, 151, 0.3);
}
.edit-icon {
color: #fff;
font-size: 32rpx;
}
</style>