web/src/components/outpatient/MedicalQueue.vue

332 lines
8.3 KiB
Vue

<template>
<Panel :title="'就诊队列'" style="height: 100%">
<template #tools>
<el-button type="primary" plain @click="setDate">
{{ selectedDateStr }}
<el-icon class="el-icon--right">
<CaretBottom/>
</el-icon>
</el-button>
<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 }}&nbsp;({{ 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="搜索门诊单" style="font-size: 16px">
</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>
<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>{{ item.name }}</span>
<span>{{ item.age || 0 }}岁</span>
<span class="item_time">
{{ formatListTime(item.createDatetime) || '-' }}
</span>
<span>{{ item.type == 2 ? '医保' : '自费' }}</span>
</li>
</el-scrollbar>
</ul>
</div>
</div>
</Panel>
</template>
<script setup lang="ts">
import {nextTick, onMounted, ref, watch} 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 {CaretBottom} 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')
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()
onMounted(() => {
selectedDate.value = getCurrentDate()
initStatusList()
if (curStatus.value == 1) {
init()
}
})
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) {
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) => {
curItem.value = item
if (item != null && 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) => {
clickLi(item, false)
if (curStatus != null) {
curStatus.value = status
}
}
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) => {
if (newValue == oldValue) {
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;
justify-content: space-between;
align-items: center;
padding: 0 26px 0 28px;
font-weight: 400;
font-size: 14px;
color: rgba(34, 42, 57, 0.7);
font-style: normal;
cursor: pointer;
span {
display: flex;
align-items: center;
.avatar {
width: 26px;
height: 26px;
}
}
&:hover {
background: rgba(#4D6DE4, 0.5);
}
.item_name {
white-space: nowrap; // 防止文本换行
overflow: hidden; // 隐藏溢出的文本
text-overflow: ellipsis; // 显示省略号
}
.item_time {
white-space: nowrap; // 防止文本换行
overflow: hidden; // 隐藏溢出的文本
text-overflow: ellipsis; // 显示省略号
text-align: center;
}
}
.active {
color: #fff;
background: #4D6DE4;
&:hover {
background: #4D6DE4;
}
}
}
}
:deep(.el-input) {
visibility: hidden;
width: 0;
height: 0;
position: absolute;
right: 0;
top: 50px;
}
</style>