404 lines
9.8 KiB
Vue
404 lines
9.8 KiB
Vue
<template>
|
||
<Panel :title="'就诊队列'" style="height: 100%">
|
||
<template #tools>
|
||
<div @click="setDate" class="date-btn">
|
||
<span>{{ selectedDateStr }}</span>
|
||
<el-icon style="margin-left: 21px">
|
||
<Calendar/>
|
||
</el-icon>
|
||
</div>
|
||
<el-date-picker
|
||
v-model="selectedDate"
|
||
type="date"
|
||
placeholder="选择日期"
|
||
ref="datePickerRef"
|
||
format="YYYY-MM-DD"
|
||
value-format="YYYY-MM-DD"
|
||
/>
|
||
</template>
|
||
<div class="panel-content" style="display: flex;flex-direction: column;height: 100%">
|
||
<div class="tabs">
|
||
<span v-for="(item,index) in statusList" :class="curStatus == item.status ? 'tabs-item' : ''"
|
||
@click="clickTab(item)">{{ item.label }} ({{ item.num }})</span>
|
||
</div>
|
||
<div class="search">
|
||
<img src="/static/images/outpatient/search.png" class="search-icon" alt="搜索图标">
|
||
<input class="search-input" v-model="search" placeholder="搜索门诊单">
|
||
</div>
|
||
<div class="list">
|
||
<ul style="height: 100%">
|
||
<el-scrollbar style="height: 100%">
|
||
<li class="list-item" :class="curItem?.id == item.id ? 'active' : ''" v-for="(item, index) in list"
|
||
:key="index" @click="clickLi(item)">
|
||
<span class="item-avatar">
|
||
<img v-if="item.gender==1" class="avatar" src="/static/images/outpatient/man.png"
|
||
alt="头像"/>
|
||
<img v-if="item.gender==2" class="avatar" src="/static/images/outpatient/women.png"
|
||
alt="头像"/>
|
||
</span>
|
||
<span class="item-name">{{ item.name }}</span>
|
||
<span class="item-time">
|
||
{{ formatListTime(item.createDatetime) }}
|
||
</span>
|
||
<span class="item-type">{{ item.type == 2 ? '医保' : '自费' }}</span>
|
||
</li>
|
||
</el-scrollbar>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</Panel>
|
||
</template>
|
||
<script setup lang="ts">
|
||
|
||
import {onMounted, ref, watch, onUnmounted} from "vue";
|
||
import Panel from "@/components/common/Panel.vue";
|
||
import {post} from "@/utils/request.ts";
|
||
import {formatListTime, getToday, getThisMonth, getCurrentDate, getEndOfDay} from "@/utils/dateUtils.ts";
|
||
import {apiConfig} from "@/assets/config/apiConfig.ts";
|
||
import {ElMessageBox} from "element-plus";
|
||
import {Calendar} from '@element-plus/icons-vue'
|
||
|
||
const curStatus = ref(1)
|
||
const search = ref('')
|
||
const curItem = ref<any>('')
|
||
const selectedDate: any = ref('')
|
||
const selectedDateStr: any = ref('')
|
||
const emit = defineEmits(['clickItem', 'changeTab'])
|
||
const datePickerRef = ref()
|
||
const clickTab = (item: any) => {
|
||
curStatus.value = item.status
|
||
emit('changeTab', item.status)
|
||
curItem.value = {}
|
||
}
|
||
const setDate = function () {
|
||
if (datePickerRef.value) {
|
||
datePickerRef.value.handleOpen()
|
||
}
|
||
}
|
||
const list = ref<any>([])
|
||
const statusList = ref<any>([
|
||
{
|
||
status: 1,
|
||
label: '候诊',
|
||
num: 0
|
||
},
|
||
{
|
||
status: 2,
|
||
label: '在诊',
|
||
num: 0
|
||
},
|
||
{
|
||
status: 3,
|
||
label: '已诊',
|
||
num: 0
|
||
}
|
||
])
|
||
const itemId = defineModel()
|
||
let refreshInterval: number | null = null; // 定义定时器变量
|
||
onMounted(() => {
|
||
selectedDate.value = getCurrentDate()
|
||
initStatusList()
|
||
if (curStatus.value == 1) {
|
||
init()
|
||
}
|
||
// 启动定时器,每秒更新一次
|
||
refreshInterval = setInterval(() => {
|
||
initList()
|
||
}, 60 * 1000); // 每1000毫秒(即1秒)执行一次
|
||
})
|
||
onUnmounted(() => {
|
||
// 组件卸载时清除定时器
|
||
if (refreshInterval !== null) {
|
||
clearInterval(refreshInterval);
|
||
refreshInterval = null;
|
||
}
|
||
});
|
||
const initList = async () => {
|
||
selectedDateStr.value = setDateTip()
|
||
try {
|
||
let data: any = await post(apiConfig.RegistrationList, {
|
||
query: {
|
||
status: curStatus.value,
|
||
beginTime: selectedDate.value,
|
||
endTime: getEndOfDay(new Date(selectedDate.value))
|
||
}
|
||
}, {catch_error: true});
|
||
list.value = data.list
|
||
if (itemId.value != null) {
|
||
list.value.forEach((item: any, index: any) => {
|
||
if (item.id == itemId.value && curStatus.value == 2) {
|
||
clickLi(item, false)
|
||
}
|
||
})
|
||
}
|
||
} catch (e) {
|
||
|
||
} finally {
|
||
}
|
||
initStatusList()
|
||
}
|
||
const loading = ref(true)
|
||
const init = async () => {
|
||
selectedDateStr.value = setDateTip()
|
||
clickLi(null)
|
||
loading.value = true
|
||
try {
|
||
let data: any = await post(apiConfig.RegistrationList, {
|
||
query: {
|
||
status: curStatus.value,
|
||
beginTime: selectedDate.value,
|
||
endTime: getEndOfDay(new Date(selectedDate.value))
|
||
}
|
||
}, {catch_error: true});
|
||
list.value = data.list
|
||
if (itemId.value != null) {
|
||
list.value.forEach((item: any, index: any) => {
|
||
if (item.id == itemId.value && curStatus.value == 2) {
|
||
clickLi(item, false)
|
||
}
|
||
})
|
||
}
|
||
|
||
} catch (e) {
|
||
|
||
} finally {
|
||
loading.value = false
|
||
}
|
||
initStatusList()
|
||
}
|
||
const initStatusList = () => {
|
||
post('statistics/getTipCount', {
|
||
beginTime: selectedDate.value,
|
||
endTime: getEndOfDay(new Date(selectedDate.value))
|
||
}).then((res: any) => {
|
||
statusList.value[0].num = res.waitDiagnosisCount
|
||
statusList.value[1].num = res.diagnosingCount
|
||
statusList.value[2].num = res.completeDiaCount
|
||
})
|
||
}
|
||
const clickLi = (item: any, showBox: any = true) => {
|
||
if (!item) {
|
||
return
|
||
}
|
||
curItem.value = item
|
||
if (item.status == 1 && showBox) {
|
||
ElMessageBox.confirm(`您将要接诊:${item.name}`, "提示", {
|
||
confirmButtonText: '确定',
|
||
cancelButtonText: '取消',
|
||
callback: (action: any) => {
|
||
if (action == "cancel") {
|
||
curItem.value = null
|
||
return
|
||
}
|
||
if (action == "confirm") {
|
||
post('registration/changeStatus', {id: item.id, status: 2}).then((res: any) => {
|
||
curStatus.value = 2
|
||
curItem.value = res
|
||
initStatusList()
|
||
emit('clickItem', curItem.value)
|
||
})
|
||
}
|
||
},
|
||
})
|
||
} else {
|
||
emit('clickItem', curItem.value)
|
||
}
|
||
|
||
}
|
||
const changeCurItemOrStatus = (item: any, status: any) => {
|
||
curStatus.value = status
|
||
init()
|
||
}
|
||
defineExpose({changeCurItemOrStatus})
|
||
watch(() => curStatus.value, () => {
|
||
init() // 重新初始化数据
|
||
})
|
||
const setDateTip = () => {
|
||
const seletctedDateObj = new Date(selectedDate.value);
|
||
//如果选择的日期是今天
|
||
if (seletctedDateObj.getFullYear() == new Date().getFullYear() && seletctedDateObj.getMonth() == new Date().getMonth() && seletctedDateObj.getDate() == new Date().getDate()) {
|
||
return '今天'
|
||
}
|
||
if (seletctedDateObj.getFullYear() == new Date().getFullYear() && seletctedDateObj.getMonth() == new Date().getMonth() && seletctedDateObj.getDate() == new Date().getDate() - 1) {
|
||
return '昨天'
|
||
}
|
||
//如果为今年
|
||
if (seletctedDateObj.getFullYear() == new Date().getFullYear()) {
|
||
return `${seletctedDateObj.getMonth() + 1}-${seletctedDateObj.getDate()}`
|
||
}
|
||
return seletctedDateObj.getFullYear();
|
||
|
||
|
||
}
|
||
watch(() => selectedDate.value, (newValue, oldValue) => {
|
||
curItem.value = null
|
||
emit('clickItem', curItem.value)
|
||
if (newValue == oldValue) {
|
||
init()
|
||
return;
|
||
}
|
||
if (newValue == null) {
|
||
return;
|
||
}
|
||
init()
|
||
})
|
||
</script>
|
||
<style scoped lang="scss">
|
||
|
||
.tabs {
|
||
height: 27px;
|
||
border-bottom: 1px solid #EAEAEC;
|
||
font-weight: 500;
|
||
color: #999999;
|
||
font-style: normal;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
padding: 0 18px;
|
||
|
||
span {
|
||
cursor: pointer;
|
||
}
|
||
|
||
.tabs-item {
|
||
border-bottom: 2px solid #4D6DE4;
|
||
color: #4D6DE4;
|
||
padding-bottom: 10px;
|
||
}
|
||
}
|
||
|
||
.search {
|
||
position: relative;
|
||
margin: 16px 0;
|
||
padding: 0 16px;
|
||
|
||
.search-icon {
|
||
position: absolute;
|
||
left: 32px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
width: 16px; // 调整图标大小
|
||
height: 16px; // 调整图标大小
|
||
z-index: 1;
|
||
}
|
||
|
||
.search-input {
|
||
width: 100%;
|
||
height: 42px;
|
||
background: #FFFFFF;
|
||
border-radius: 6px;
|
||
border: 1px solid #EAEAEC;
|
||
padding-left: 42px;
|
||
|
||
&:focus {
|
||
outline: none; // 移除默认的焦点轮廓
|
||
border-color: #5078c8; // 修改边框颜色
|
||
box-shadow: 0 0 5px rgba(#5078c8, 0.5); // 添加阴影效果
|
||
}
|
||
}
|
||
}
|
||
|
||
.list {
|
||
flex: 1;
|
||
display: flex;
|
||
min-height: 0;
|
||
flex-direction: column;
|
||
|
||
ul {
|
||
flex: 1;
|
||
min-height: 0;
|
||
|
||
.list-item {
|
||
height: 48px;
|
||
display: flex;
|
||
font-weight: 400;
|
||
padding: 0 16px;
|
||
font-size: 14px;
|
||
color: rgba(34, 42, 57, 0.7);
|
||
font-style: normal;
|
||
cursor: pointer;
|
||
|
||
span {
|
||
display: block;
|
||
line-height: 48px;
|
||
text-align: center;
|
||
}
|
||
|
||
.item-avatar {
|
||
width: 26px;
|
||
margin-right: 10px;
|
||
|
||
.avatar {
|
||
margin-top: 11px;
|
||
width: 26px;
|
||
height: 26px;
|
||
}
|
||
}
|
||
|
||
.item-name {
|
||
flex: 1;
|
||
min-width: 0;
|
||
text-align: left;
|
||
white-space: nowrap; // 防止文本换行
|
||
overflow: hidden; // 隐藏溢出的文本
|
||
text-overflow: ellipsis; // 显示省略号
|
||
}
|
||
|
||
.item-time {
|
||
width: 40px;
|
||
font-size: 12px;
|
||
}
|
||
|
||
.item-type {
|
||
width: 40px;
|
||
font-size: 12px;
|
||
}
|
||
|
||
&:hover {
|
||
background: rgba(#4D6DE4, 0.5);
|
||
}
|
||
|
||
|
||
.item_time {
|
||
white-space: nowrap; // 防止文本换行
|
||
overflow: hidden; // 隐藏溢出的文本
|
||
text-overflow: ellipsis; // 显示省略号
|
||
text-align: center;
|
||
}
|
||
|
||
}
|
||
|
||
.active {
|
||
color: #fff;
|
||
background: #4D6DE4;
|
||
|
||
&:hover {
|
||
background: #4D6DE4;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
}
|
||
|
||
.date-btn {
|
||
width: 98px;
|
||
height: 32px;
|
||
background: #FFFFFF;
|
||
border-radius: 6px;
|
||
border: 1px solid #EAEAEC;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
cursor: pointer;
|
||
}
|
||
|
||
:deep(.el-input) {
|
||
visibility: hidden;
|
||
width: 0;
|
||
height: 0;
|
||
position: absolute;
|
||
right: 0;
|
||
top: 50px;
|
||
}
|
||
|
||
</style> |