You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

887 lines
24 KiB
Vue

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<div class="YuYue202506">
<div class="patientInfo" v-if="patientInfo">
<div class="item"><span class="name">{{patientInfo.user_name}}</span>{{patientInfo.user_sex_label}} {{patientInfo.age}}岁)</div>
<div class="item">登记号:<span class="value">{{patientInfo.reg_num}} </span></div>
<div class="item">电话:<span class="value">{{patientInfo.user_phone}}</span></div>
<div class="item" v-if="patientInfo.warddesc">病区:<span class="value">{{patientInfo.warddesc}}</span></div>
<div class="item" v-if="patientInfo.bedname">床号:<span class="value">{{patientInfo.bedname}}</span></div>
<div class="item">诊断:<span class="value">{{patientInfo.diagnosisName}}</span></div>
</div>
<div v-else>
获取患者信息失败
</div>
<div class="entrustList">
<el-table :data="entrustTableDate" style="width: 100%;" height="300" row-key="id" v-loading="loading"
ref="entrustTableRef" :row-class-name="setRowClassName" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="50" :selectable="selectable" />
<el-table-column prop="tishi_msg" label="">
<template #default="scope">
<span v-if="scope.row.tishi_msg!=''" class="errMsg">{{scope.row.tishi_msg}}</span>
<span v-else>正常</span>
</template>
</el-table-column>
<el-table-column prop="list_status" label="医嘱状态" width="80">
<template #default="scope">
<el-tag v-if="scope.row.list_status===0" class="ml-2" type="info">申请中</el-tag>
<el-tag v-if="scope.row.list_status===1" class="ml-2" type="success">已预约</el-tag>
<el-tag v-if="scope.row.list_status===2" class="ml-2">登记</el-tag>
<el-tag v-if="scope.row.list_status===3" class="ml-2" type="warning">完成</el-tag>
</template>
</el-table-column>
<el-table-column prop="entrust" label="项目" width="250" />
<el-table-column prop="is_pay" label="是否交费" width="80">
<template #default="scope">
<span v-if="scope.row.is_pay==1">是</span>
<span v-if="scope.row.is_pay==0">否</span>
</template>
</el-table-column>
<el-table-column prop="department_resources.department_resources_name" label="预约资源" width="120" />
<el-table-column prop="reservation_date" label="预约日期" width="120" />
<el-table-column prop="check_begin_time" label="预约时间" width="120">
<template #default="scope">
<span
v-if="scope.row.period_begin_time && scope.row.period_end_time ">{{scope.row.period_begin_time.substring(0, 5)}}~{{scope.row.period_end_time.substring(0, 5)}}</span>
</template>
</el-table-column>
<el-table-column prop="limosis" label="是否空腹">
<template #default="scope">
<span v-if="scope.row.limosis==0">否</span>
<span v-else>是</span>
</template>
</el-table-column>
<el-table-column prop="reservation_department" label="申请科室" width="120" />
<el-table-column prop="" label="医嘱时间" width="160">
<template #default="scope">
{{scope.row.entrust_date}} {{scope.row.entrust_time}}
</template>
</el-table-column>
<el-table-column prop="docotr" label="申请医生" />
</el-table>
</div>
<div class="planInfo">
<div style="display: flex;justify-content: space-between; margin-top: 8px;margin-bottom: 8px;">
<div style="display: flex;">
<div v-for="(item ,index) in zhenShiList" :key="index"
:class="{'ZhenShiButton zhenshiButton_active': activeZhenShi === item,'ZhenShiButton': activeZhenShi !== item}"
@click="zhenshiClick(item)">{{item}}</div>
<div class="shuxian"></div>
<el-button class="do_button" type="success" @click="YuYueButtonClick(1)">预约</el-button>
<el-button class="do_button" type="warning" @click="YuYueButtonClick(2)">更改预约时间</el-button>
<el-button class="do_button" type="danger" @click="CancelYuYueFunc()">取消预约</el-button>
<el-button style="display: none;" ref="print_shenqingdan_button"
v-print="'#shenqingdan'">打印申请单隐藏按钮</el-button>
<el-button @click="print_shenqingdan()">打印申请单</el-button>
<el-checkbox-group v-model="auto_print" style="margin-left: 12px;">
<el-checkbox label="1">预约完成后打印申请单</el-checkbox>
</el-checkbox-group>
</div>
<div>
<el-date-picker v-model="startDate" type="date" placeholder="跳转日期" @change="DatePickerChange()" />
</div>
</div>
<div v-loading="planLoading" style="border: 1px solid #efefef;">
<table class="planTable">
<tr style="background-color: #f1f1f1;" v-if="selectedRows.length>0">
<td style="width: 120px;"></td>
<td style="font-weight: 700;" v-for="(item,index) in date_list">{{item.substring(5, 10)}}
{{getWeekday(item)}}
</td>
</tr>
<tr v-for="(item,index) in planTableData" :key="index" class="table_plan_row" v-if="date_list.length>0 && planTableData.length>0">
<td v-for="(item2,index2) in item" :key="index2" :class="{
'planActive': (selectedPlanId === item2.id && selectedPlanId !==0 && selectedPlanId),
'plandisable': !item2.enable && index2 !=='time_range'
}" @click="PlanClick(item2.id)"><span
v-if="index2=='time_range'">{{item2}}</span><span>{{item2.use_count}}</span></td>
</tr>
</table>
<div v-if="selectedRows.length==0">
<el-empty description="请选择项目" />
</div>
<div v-if="selectedRows.length>0 && planTableData.length==0" style="background-color: #fff;">
<el-empty description="暂无号源" />
</div>
</div>
</div>
<div id="shenqingdan" v-if="shenqingdan_show" style="position: relative;">
<div v-for="(item,index) in shenqingdan_list" :key="index">
<ShenQingDan :printInfo="item.maininfo"></ShenQingDan>
</div>
</div>
</div>
</template>
<script setup>
import {
ref,
onMounted,
watch
} from 'vue'
import {
getMainDetail,
GetEnablePlan,
CheckIsDaiJian,
PlanYuYue,
CheckEntrstItemGroup2,
DoctorCancelYuYue,GetConfigInfo2,CreateJianChaShenQingDanPdf
} from '@/api/api.js'
import {
ElMessage,
ElMessageBox
} from 'element-plus'
import ShenQingDan from '@/components/Yewu/PrintShenQingDan.vue'
const props = defineProps({
reg_num: {
type: String
},
entrust_ids: {
type: String
},
episode_id: {
type: String
},
appointment_type: {
type: [String, Number]
},
dotype: {
type: Number
},
do_user: {
default:'',
type: [String, Number]
}
})
let entrustTableRef = ref(null)
let patientInfo = ref(null)
let entrustTableDate = ref([]);
let planTableData = ref([]);
let loading = ref(false);
let planLoading = ref(false);
let zhenShiList = ref([]);
let activeZhenShi = ref('');
let selectedPlanId = ref(0)
let selectedMianListId = ref([]) //勾选选中的医嘱对应的数据库id
let selectedEntrustId = ref([]) //勾选选中的医嘱对应的entrust_id
let selectedRows = ref([])
let isHandlingSelection = ref(true) //防止冒泡 死循环
let lastSelection = ref([]) //上一次操作勾选的记录 用了比对 是取消还是 勾选
let print_shenqingdan_button = ref(null)
let auto_print = ref(['1']);
let shenqingdan_show = ref(false);
let handleType = ref('add');
let startDate = ref('');
let systemConfigs=ref([]);//系统参数
const getWeekday = (date1) => {
let days = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
const date = new Date(date1); // 注意:格式可能因浏览器而异
const dayOfWeek = date.getDay();
return days[dayOfWeek]
}
const handleSelectionChange = (selection) => {
selectedMianListId.value = []
selectedEntrustId.value = []
zhenShiList.value = []
planTableData.value = []
activeZhenShi.value = ''
selectedRows.value = selection;
console.log('11111',selectedRows.value)
selectedRows.value.forEach((v, i) => {
selectedMianListId.value.push(v.id)
selectedEntrustId.value.push(v.entrust_id)
})
//遍历已经勾选的项目 如果号源id都相同则 获取可以选定的号源id.------------vvvv
const allPlanIdsSame = selectedRows.value.every(
(v) => v.roster_id === selectedRows.value[0]?.roster_id
);
if (allPlanIdsSame) {
selectedPlanId.value = selectedRows.value[0]?.roster_id;
if(selectedPlanId.value!==0 && selectedPlanId.value){
startDate.value=selectedRows.value[0]?.reservation_date
if(checkDateDifference15Day(getTodayDate(),selectedRows.value[0]?.reservation_date) && !!selectedRows.value[0]?.reservation_date){
date_list.value=getDatesAfter(selectedRows.value[0]?.reservation_date)
}else{
date_list.value=getDatesAfter(getTodayDate())
}
activeZhenShi.value=selectedRows.value[0]?.department_resources?.department_resources_name
}
} else {
selectedPlanId.value = 0;
}
//--------------------------------------------------------------^^^^^
lastSelection.value.forEach(lastRow => {
if (!selectedRows.value.find(s => s === lastRow)) {
handleType.value = 'cancel'
}
});
if(selectedRows.value.length==0){//如果全部取消了,则恢复状态
handleType.value = 'add'
lastSelection.value=[]
}
console.log(handleType.value)
if (selectedEntrustId.value.length > 0 && isHandlingSelection.value) {
if (handleType.value === 'add' && selectedRows.value[0].list_status==0) {
FindAllMatchItem();
} else {
GetEnablePlanFunc();
}
}
}
const isSelected = (row) => {
return selectedRows.value.findIndex(item => item.id === row.id) > -1;
}
const setRowClassName = ({
row,
rowIndex
}) => {
if (row.tishi_msg != "") {
return 'disabled-row';
}
if (isSelected(row)) {
return 'selected-row';
}
}
const selectable = (row, index) => {
if (row.tishi_msg != "") {
return false;
} else {
return true;
}
}
const GetMainInfo = () => {
let tempSelected = selectedMianListId.value
entrustTableDate.value = []
loading.value = true
getMainDetail({
regnum: props.reg_num,
entrustid: props.entrust_ids,
episodeid: props.episode_id,
appointment_type: props.appointment_type
}).then(res => {
loading.value = false
if (res.status) {
if (res.data.info.length > 0) {
let info = res.data.info
patientInfo.value = info[0].maininfo
info.forEach((v, i) => {
let item_entrust_info = v.maininfo
item_entrust_info.tishi_msg = v.msg
item_entrust_info.limosis = v.iteminfo[0]?.limosis
entrustTableDate.value.push(item_entrust_info)
})
if (tempSelected.length > 0) {
tempSelected.forEach((v, i) => {
entrustTableDate.value.forEach((v2, i2) => {
if (v == v2.id) {
entrustTableRef.value.toggleRowSelection(entrustTableDate
.value[i2], true)
}
})
})
} else { //进来后默认选中第一个可以勾选的
for (let i = 0; i < entrustTableDate.value.length; i++) {
if (entrustTableDate.value[i].tishi_msg == '') {
entrustTableRef.value.toggleRowSelection(entrustTableDate.value[i], true)
if(entrustTableDate.value[i].roster_id!=null){
selectedPlanId.value=entrustTableDate.value[i].roster_id
// startDate.value=entrustTableDate.value[i].reservation_date
//date_list.value = getDatesAfter(entrustTableDate.value[i].reservation_date)
activeZhenShi.value=entrustTableDate.value[i].department_resources?.department_resources_name
}
break;
}
}
}
}
} else {
ElMessage.error(res.msg)
}
})
}
const FindAllMatchItem = () => {
let list = []
//selectedRows.value.reverse();
let length=selectedRows.value.length
if (selectedRows.value[length-1].list_status != 0) return false //如果勾选的不是申请中的医嘱则不进行匹配
entrustTableDate.value.forEach((v, i) => {
if (v.list_status == 0 && v.tishi_msg == "") {
if (v.id == selectedRows.value[length-1].id) {
list.push({
name: v.entrust,
rowid: i,
first: 1
})
} else {
list.push({
name: v.entrust,
rowid: i,
first: 0
})
}
}
})
if (list.length >= 2) {
loading.value = true
CheckEntrstItemGroup2({
items: list
}).then(res => {
loading.value = false
if (res.status) {
list.forEach((v, i) => {
isHandlingSelection.value = false
entrustTableRef.value.toggleRowSelection(entrustTableDate.value[v.rowid],
false)
})
let rowids = res.data.rowids
// autoSeleted(d)
rowids.forEach((v, i) => {
isHandlingSelection.value = false
entrustTableRef.value.toggleRowSelection(entrustTableDate.value[v], true)
})
lastSelection.value = selectedRows.value
GetEnablePlanFunc()
} else {
ElMessage.error(res.msg)
}
isHandlingSelection.value = true
})
} else {
lastSelection.value = selectedRows.value
GetEnablePlanFunc()
}
}
let date_list = ref([]);
const GetEnablePlanFunc = () => {
if( selectedEntrustId.value.length==0){
ElMessage.error("请选择检查项目")
return false;
}
planLoading.value = true
GetEnablePlan({
regnum: props.reg_num,
entrustid: selectedEntrustId.value,
episodeid: props.episode_id,
appointment_type: props.appointment_type,
date: date_list.value
}).then(res => {
planLoading.value = false
planTableData.value = []
zhenShiList.value=[]
if (res.status) {
let plans = res.data.plan_list
let zhanWeiCount=res.data.zhanWeiCount
if (plans.length > 0) {
if (activeZhenShi.value == '') activeZhenShi.value = plans[0].department_resources_name
const timeSlotsSet = new Set();
const zhenshiSet = new Set();
plans.forEach(v => {
if (v.department_resources_name == activeZhenShi.value) {
const timeRange =
`${v.begin_time.substring(0,5)}-${v.end_time.substring(0,5)}`;
timeSlotsSet.add(timeRange);
}
zhenshiSet.add(v.department_resources_name)
});
zhenShiList.value = zhenshiSet
const timeSlots = Array.from(timeSlotsSet).sort(); // 排序可选
// Step 2: 构建表格数据
timeSlots.forEach(timeRange => {
const row = {
time_range: timeRange
};
date_list.value.forEach(date => {
const matchingPlan = plans.find(
v =>
`${v.begin_time.substring(0,5)}-${v.end_time.substring(0,5)}` ===
timeRange && v.date === date && v
.department_resources_name == activeZhenShi.value
);
let plan_enable = false
if (matchingPlan) {
if (matchingPlan.count - matchingPlan.used_count >= zhanWeiCount && matchingPlan.plan_enable===true) {
plan_enable = true
if(selectedPlanId.value == 0 || selectedPlanId.value == '' || selectedPlanId.value==null && matchingPlan.id==res.data.earliestPlan){
selectedPlanId.value=matchingPlan.id
}
}
row[date] = {
use_count: `${matchingPlan.used_count}/${matchingPlan.count}`,
id: matchingPlan.id,
enable: plan_enable
};
} else {
row[date] = {
use_count: "0/0",
id: null,
enable: plan_enable
};
}
});
planTableData.value.push(row);
});
}
} else {
ElMessage.error(res.msg)
}
})
}
const processData = (data) => {
const result = {};
data.forEach(record => {
const deptName = record.department_resources_name;
if (!result[deptName]) {
result[deptName] = {};
}
const date = record.date;
if (!result[deptName][date]) {
result[deptName][date] = [];
}
// 计算剩余号数
record.remaining_count = record.count - record.used_count;
// 添加到对应日期的列表中
result[deptName][date].push({
id: record.id,
roster_id: record.roster_id,
weekname: record.weekname,
begin_time: record.begin_time,
end_time: record.end_time,
remaining_count: record.remaining_count,
status: record.status
// 如果需要,可以在这里添加其他字段
});
});
return result;
}
const zhenshiClick = (zhenshi) => {
activeZhenShi.value = zhenshi
GetEnablePlanFunc()
}
const PlanClick = (planid) => {
console.log(planid)
if (planid != undefined) {
selectedPlanId.value = planid
checkDaijianFuc()
}
}
const checkDaijianFuc = () => {
planLoading.value = true
CheckIsDaiJian({
reg_num: props.reg_num,
planid: selectedPlanId.value
}).then(res => {
planLoading.value = false
if (res.status) {
} else {
ElMessageBox.confirm(
res.msg,
'提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
})
.catch(() => {
})
}
})
}
const YuYueButtonClick = (type) => {
if (selectedEntrustId.length == 0) {
ElMessage.error("请选择检查项目")
return false;
}
if (selectedPlanId.value == 0 || selectedPlanId.value == '' || selectedPlanId.value==null) {
ElMessage.error("请选择号源")
return false;
}
let msg='确定预约此时间吗?'
if(type==2){
msg='确定改约至此时间吗?'
}
ElMessageBox.confirm(
msg,
'提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(() => {
startYuYue(type)
})
.catch(() => {
})
}
const startYuYue = (type) => {
planLoading.value = true
PlanYuYue({
mainlistid: selectedMianListId.value,
planid: selectedPlanId.value,
appointment_type: props.appointment_type,
dotype: type, //1预约2改约,
do_user:props.do_user,
}).then(res => {
planLoading.value = false
if (res.status) {
systemConfigs.value.forEach((v,i)=>{
if(v.label=='开启申请单pdf' && v.value==="1"){
CreateJianChaShenQingDanPdfFunc()
}
})
GetMainInfo()
if (auto_print.value.length > 0) {
print_shenqingdan()
}
} else {
ElMessageBox.confirm(
res.msg,
'提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'error',
showCancelButton: false
}
)
.then(() => {
})
.catch(() => {
})
}
})
}
//取消预约(此界面取消预约,不验证密码)
const CancelYuYueFunc = () => {
ElMessageBox.confirm(
'确定取消预约吗?',
'提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning',
}
)
.then(async () => {
loading.value = true
const promises = selectedRows.value.map((v) => {
return DoctorCancelYuYue({
MainListId: v.id,
reg_num: v.reg_num,
do_user:props.do_user,
}).then(res => {
if (res.status) {
ElMessage.success('取消成功')
} else {
ElMessage.error(res.msg)
}
}).catch(err => {
ElMessage.error('取消失败')
console.error(err)
})
})
// 等待所有请求完成
await Promise.all(promises)
loading.value = false
GetMainInfo()
})
}
const GetConfigInfoFunc=()=>{
GetConfigInfo2({
config_arrs: ['开启申请单pdf','医生端打印'],
}).then(res => {
if(res.status){
systemConfigs.value=res.data.list
systemConfigs.value.forEach((v,i)=>{
console.log(props.appointment_type)
if(v.label=='医生端打印' && v.value==="0" && props.appointment_type==1){
auto_print.value=[]
}
})
}
})
}
//生成pdf文件
const CreateJianChaShenQingDanPdfFunc=()=>{
CreateJianChaShenQingDanPdf({
OrderNoList: selectedEntrustId.value,
}).then(res => {
if(res.status){
}
})
}
//打印申请单
let shenqingdan_list = ref([])
const print_shenqingdan = () => {
getMainDetail({
regnum: props.reg_num,
entrustid: selectedEntrustId.value.join(','),
episodeid: props.episode_id,
appointment_type: props.appointment_type
}).then(res => {
if (res.status) {
let enable = true
shenqingdan_list.value = res.data.info
shenqingdan_list.value.forEach((v, i) => {
if (v.maininfo.list_status != 1) {
ElMessage.error(v.maininfo.entrust + " 不可打印,请重新选择")
enable = false
}
})
if (enable) {
shenqingdan_show.value = true
setTimeout(function() {
print_shenqingdan_button.value.$el.click();
shenqingdan_show.value = false
}, 500)
}
} else {
ElMessage.error(res.msg)
}
})
}
const DatePickerChange = () => {
activeZhenShi.value=''
date_list.value = getDatesAfter(startDate.value)
console.log(date_list.value)
GetEnablePlanFunc()
}
function formatDateLocal(date) {
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}`;
}
function getDatesAfter(startDate = new Date(), days = 15) {
const date = new Date(startDate); // 转换为 Date 对象
const dates = [];
if (isNaN(date.getTime())) {
throw new Error("无效的日期格式");
}
for (let i = 0; i < days; i++) {
const nextDate = new Date(date);
nextDate.setDate(date.getDate() + i);
const formattedDate = formatDateLocal(nextDate);
dates.push(formattedDate);
}
return dates;
}
function isValidDate(dateString) {
// 简单的正则表达式来验证日期格式为 YYYY-MM-DD
const datePattern = /^\d{4}-\d{2}-\d{2}$/;
if (!datePattern.test(dateString)) {
return false;
}
// 创建 Date 对象并检查是否为有效日期
const date = new Date(dateString);
return date.toString() !== "Invalid Date" &&
!isNaN(date.getTime());
}
function checkDateDifference15Day(date1, date2) {
// 校验日期格式是否正确
if (!isValidDate(date1) || !isValidDate(date2)) {
console.error("日期格式不正确,请使用 YYYY-MM-DD");
return false; // 或者抛出异常、提示用户等
}
const startDate = new Date(date1);
const endDate = new Date(date2);
// 计算时间差(毫秒)
const diffInMs = endDate - startDate;
// 转换为天数
const diffInDays = diffInMs / (1000 * 60 * 60 * 24);
return diffInDays > 15;
}
function getTodayDate() {
const today = new Date();
const year = today.getFullYear(); // 年份,如 2025
const month = String(today.getMonth() + 1).padStart(2, '0'); // 月份从 0 开始,所以要 +1
const day = String(today.getDate()).padStart(2, '0'); // 日期
return `${year}-${month}-${day}`;
}
onMounted(() => {
GetConfigInfoFunc()
date_list.value = getDatesAfter()
GetMainInfo()
})
</script>
<style lang="scss" scoped>
.patientInfo {
display: flex;
.item{
margin-right: 18px;
}
.name {
font-size: 20px;
font-weight: 700;
}
.value {
font-size: 18px;
font-weight: 700;
}
}
.entrustList {
.errMsg {
color: #f27d7d;
font-weight: 700;
opacity: 1 !important;
}
}
.planInfo {
.planTable {
width: 100%;
background-color: #fff;
text-align: center;
border: 1px solid #f1f1f1;
border-collapse: collapse;
/* 合并边框 */
color: #333;
td {
border: 1px solid #f1f1f1;
padding: 6px;
}
}
.table_plan_row td:first-child {
background-color: #f1f1f1;
border-bottom: 1px solid #e8e8e8;
}
.table_plan_row> :not(:first-child):hover {
background-color: #aeebf0;
cursor: pointer;
color: #fff;
}
.planActive {
background-color: #5bc0de;
color: #fff;
}
.plandisable {
pointer-events: none;
opacity: 0.4;
}
.shuxian {
border-left: 1px solid #dfdfdf;
margin-left: 40px;
margin-right: 40px;
}
.do_button {
width: 100px;
}
}
.ZhenShiButton {
text-align: center;
font-size: 14px;
background-color: #fff;
border: 1px solid #e8e8e8;
width: 120px;
cursor: default;
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
padding: 4px;
}
.zhenshiButton_active {
background-color: #5bc0de;
color: #fff;
}
::v-deep .el-table .disabled-row {
background-color: #f2e3e2;
//pointer-events: none;
/* 禁用鼠标事件 */
opacity: 0.6;
/* 降低透明度 */
}
::v-deep .el-table .selected-row {
background-color: #9cd0de;
}
</style>