Browse Source

医生出诊设置-冲突弹出框展示、提取为组件形式、去除无用代码

pull/15/head
zq 4 weeks ago
parent
commit
a7685401cb
  1. 39
      src/views/DoctorInformation.vue
  2. 533
      src/views/HosInformation.vue
  3. 588
      src/views/conflictDialog.vue

39
src/views/DoctorInformation.vue

@ -60,7 +60,7 @@
<el-form :model="siteForm" :rules="siteFormrules3" ref="siteForm3">
<div class="flex-wrap">
<div class="flex-left">
<p class="coincideTip mb12">您有多个出诊医院时允许不同医院排班时段重合吗</p>
<p class="coincideTip mb24">您有多个出诊医院时允许不同医院排班时段重合吗</p>
<div class="flex">
<div class="coincideWrap">
<el-radio v-model="siteForm.is_allow_coincide" :label="1">允许时段重合</el-radio>
@ -68,7 +68,7 @@
</div>
<div class="coincideWrap">
<el-radio v-model="siteForm.is_allow_coincide" :label="0">禁止时段重合</el-radio>
<p>适用于可由助理代为坐诊</p>
<p>避免时段冲突造成患者错误预约</p>
</div>
</div>
</div>
@ -84,7 +84,7 @@
<GuipRadio v-model="siteForm.first_visit_audit" class="mb12" column="column"
:options="groupOptions" label="初诊是否审批" required prop="first_visit_audit"
@change="radioChange" />
<GuipInput ref="GuipInput" column="column" label="审批人电话" desc="审批人电话、微信,至少填写一项"
<GuipInput ref="GuipInput" column="column" label="审批人电话" desc="审批人电话、微信,至少填写一项"
v-model="siteForm.approver_phone" prop="approver_phone" placeholder="请输入" />
</div>
<div class="flex-line"></div>
@ -140,6 +140,9 @@
</el-form>
<GroupFormBtns @cancel="cancelClick('siteForm1')" @confirm="setDoctorDesc" />
</div>
<ConflictDialog :isDoctorSet="true" ref="conflictDialog" :cancelBtnShow="'0'" :doctor_id="doctorId"
title="已有出诊安排冲突,请先修改!" :confirmText="'我知道了'"/>
</div>
</template>
<script>
@ -150,6 +153,8 @@ import GuipInput from '@/components/GuipInput.vue';
import GuipTextarea from '@/components/GuipTextarea.vue';
import GroupFormBtns from '@/components/GroupFormBtns.vue';
import GuipRadio from '@/components/GuipRadio.vue';
import ConflictDialog from './conflictDialog.vue';
export default {
//
name: '',
@ -160,11 +165,14 @@ export default {
GuipRadio,
GuipInput,
GuipTextarea,
GroupFormBtns
GroupFormBtns,
ConflictDialog
},
data() {
return {
doctorId: '',
is_allow_coincide: true,//
hasConflictresult:[],
fileList: [
// { name: 'image.jpeg', url: 'http://jasonyizherenxin.checkcopy.com/user_avatar/1.png?v=93940df0b596961c42de23ef1f2d3257' }
],
@ -191,7 +199,7 @@ export default {
approver_phone: '',
approver_wechat: '',
first_visit_audit: '',
is_allow_coincide:''//
is_allow_coincide: ''//
},
oldForm: {},
siteFormrules2: {
@ -386,6 +394,12 @@ export default {
this.$message.error('请先设置医生基础信息')
return;
}
//
if (this.siteForm.is_allow_coincide == 0) {
this.$refs.conflictDialog.open()
return
}
//
// this.$http('POST', '/api/admin/set_doctor_approver', {
// is_allow_coincide:this.siteForm.is_allow_coincide
@ -397,12 +411,12 @@ export default {
// this.$message.success(response.msg)
// if (this.doctorId) return;
// }).catch(error => {
// console.error(error, 'error')
// this.$message.error('')
// })
},
handleApproverWechatChange(file, fileList) {
console.log(file, fileList)
@ -424,10 +438,11 @@ export default {
}
</script>
<style lang="scss" scoped>
.coincideWrap{
.coincideWrap {
margin-right: 24px;
text-align: left;
p{
p {
font-family: Microsoft YaHei UI;
font-size: 12px;
font-weight: normal;
@ -437,7 +452,8 @@ export default {
padding-left: 22px;
}
}
.coincideTip{
.coincideTip {
font-family: Microsoft YaHei UI;
font-size: 14px;
font-weight: normal;
@ -445,8 +461,9 @@ export default {
letter-spacing: 0.08em;
color: #1E2226;
text-align: left;
}
.info-upload-wrapper ::v-deep .el-upload-list.el-upload-list--picture-card {
display: none;
}

533
src/views/HosInformation.vue

@ -634,7 +634,7 @@
<el-option v-for="item in hosList" :key="item.hid" :label="item.name" disabled
:value="item.hid">
<div class="flex-between option-content">
<span style="color:#333">{{ item.name }}{{ item.morning_plan }}</span>
<span style="color:#333">{{ item.name }}</span>
<div class="checkbox-wrapper" @click.stop>
<el-checkbox :key="forceTime"
@change="handleWorkCheckDirect(item, $event, 'morningSelectedHospitals')"
@ -696,28 +696,9 @@
</p>
</el-form>
</GuipDialog>
<ConflictDialog :is_allow_coincide="is_allow_coincide" :h_realname="form.h_realname" :houseCallSettingForm="houseCallSettingForm"
ref="conflictDialog" :doctor_id="doctor_id" :rawScheduleDataProp="rawScheduleData" :depart_id="depart_id" :oldWorktimes="form.worktimes"/>
<GuipDialog :dialogVisible="visitDialogVisible" :title="visitDialogTitle" :show-close-button="true" width="699px"
:show-cancel-button="visitShowCancelBtn" @confirm="handleVisitConfirm" :confirmText="visitConfirmText"
@cancel="handleVisitCancel" @close="handleVisitClose">
<div class="flex conflictTitle mb24" v-if="is_allow_coincide">
您设置的 <b>{{ form.h_realname }} </b>每周排班与以下现有出诊安排重叠请确定是否正确
</div>
<div class="flex conflictTitle mb24" v-else>
您设置的 <b>{{ form.h_realname }} </b>每周排班与以下现有出诊安排冲突请调整后再保存
</div>
<div class="visitContent">
<div class="hosPlanItem mb24" v-for="(conflict, index) in hasConflictresult" :key="index">
<p>{{ conflict.date }} {{ conflict.dayOfWeek ? `${conflict.dayOfWeek}` : '' }}{{ conflict.conflictShift }}</p>
<div class="flex">
<span class="conflictTip">{{!is_allow_coincide ?'冲突':'重叠' }}</span>
<div>{{ conflict.hospital }}({{ conflict.type === 'fixed' ?
'固定排班' :
'临时出诊' }})</div>
</div>
</div>
</div>
</GuipDialog>
<GuipDialog :dialogVisible="dialogVisible" :title="dialogTitle" :show-close-button="true" width="762px"
:show-cancel-button="true" @confirm="handleConfirm" @cancel="handleCancel" @close="handleClose"
@dialogVisibleChange="dialogVisibleChange">
@ -756,9 +737,9 @@ import GuipTable from '@/components/GuipTable.vue';
import GuipDialog from '@/components/GuipDialog.vue';
import CustomDropdown from '@/components/CustomDropdown.vue';
import SetAliPay from '@/components/SetAliPay.vue';
import { mapState } from 'vuex';
import { Object } from 'core-js';
import ConflictDialog from './conflictDialog.vue';
const PAY_TYPE_WEIXIN = 2; //
const PAY_TYPE_ALIPAY = 3; //
@ -780,6 +761,7 @@ export default {
GroupFormBtns,
SetAliPay,
PromptText,
ConflictDialog
},
data() {
return {
@ -983,12 +965,13 @@ export default {
calendarList1: [],
calendarList: {}, //
rawScheduleData: null, //
is_allow_coincide: false,//
is_allow_coincide: 0,//
conflictDates: [], //
conflictCount: 0, //
tempAdjustments: {}, // {: {ID: {, , }}}
currentEditingHospital: null, //
currentEditingDate: null, //
currentClickDate: null, //
isShowDialogDate: false,//
morning_value: ['双皮奶', '鸡蛋'],
options: [{
@ -1022,7 +1005,6 @@ export default {
originalMorningSelected: [], //
originalAfternoonSelected: [], //
forceTime: Date.now(),
isRangeConflict: false, //
}
},
created() {
@ -1154,39 +1136,7 @@ export default {
...mapState(['hosMenuData']) // VuexshowSidebar
},
methods: {
// -
handleVisitConfirm() {
if (!this.is_allow_coincide) {
this.saveWorkTimeDirect();
}
this.visitDialogVisible = false;
},
async saveWorkTimeDirect() {
const { display_work_days, planDays, worktime_no_fixed, worktimes } = this.houseCallSettingForm;
var worktimesArray = this.formatWorktimesArray(worktimes)
const params = {
doctor_id: this.doctor_id,
depart_id: this.depart_id,
worktime_no_fixed: worktime_no_fixed,
week_visit_plan: JSON.stringify(worktimesArray)
}
if (display_work_days == 1 && planDays > 0) {
params.display_work_days = planDays
}
await this.$http('POST', '/api/admin/set_depart_worktime', {
...params
}).then(response => {
if (response.code == 0) {
this.$Message.success(response.msg || '设置成功')
this.getDoctorHosPreview();
}
}).catch(error => {
console.error(error, 'error')
})
},
// -
handleVisitCancel() {
this.handleVisitClose()
@ -1444,6 +1394,7 @@ export default {
},
handleDateClick(dateString, event) {
this.currentClickDate = dateString
event.stopPropagation();
// isConflictDate()
const clickedDate = new Date(dateString);
@ -1613,17 +1564,17 @@ export default {
});
});
// console.log(':', plans);
console.log('保存的排班数据:', plans);
// await this.saveTempAdjustment(this.currentEditingDate, plans);
await this.saveTempAdjustment(this.currentClickDate, plans);
this.moreHosVisiable = false;
//
this.$nextTick(() => {
this.morningSelectedHospitals = [];
this.afternoonSelectedHospitals = [];
this.hasConflict = false;
});
// //
// this.$nextTick(() => {
// this.morningSelectedHospitals = [];
// this.afternoonSelectedHospitals = [];
// this.hasConflict = false;
// });
} catch (error) {
console.error('保存多医院调诊失败:', error);
@ -1697,14 +1648,6 @@ export default {
// console.log(`:`, hospitals);
return hospitals;
},
// forceUpdateSelection() {
// this.$nextTick(() => {
// console.log('');
// this.morningSelectedHospitals = [...this.morningSelectedHospitals];
// this.afternoonSelectedHospitals = [...this.afternoonSelectedHospitals];
// });
// },
// tooltip
getWorkTimeDisplayText(hospital, dateStr, hospitalId) {
const hospitalData = this.rawScheduleData[hospitalId];
@ -1795,13 +1738,6 @@ export default {
return { class: 'color-tag', style: { backgroundColor: hospitalColor } };
}
},
//
// getColorTagConfig(dateStr, hospitalId, shiftType) {
// const key = `${dateStr}_${hospitalId}_${shiftType}`;
// return this.hospitalTagConfigs[dateStr]?.[key] || { class: 'color-tag', style: {} };
// },
getColorTagConfig(dateStr, hospitalId, shiftType) {
const schedule = this.getDateSchedule(dateStr);
if (!schedule || !schedule[shiftType]) return { class: 'color-tag', style: {} };
@ -1821,10 +1757,6 @@ export default {
//
const status = this.getTempAdjustmentStatus(dateStr, hospitalId, hospital.originalPlan);
// if (dateStr == '2025-11-12') {
// // console.log(status, 'getColorTagConfigstatus===');
// }
switch (status) {
case 'cancelled':
return { class: 'opacity-tag', style: { backgroundColor: hospitalColor } };
@ -1897,9 +1829,6 @@ export default {
const adjustment = this.tempAdjustments[dateStr][hospitalId];
const newPlan = adjustment.newPlan.toString();
const originalPlanStr = originalPlan.toString();
// if (dateStr == '2025-11-12' && hospitalId == 7) {
// console.log(`getTempAdjustmentStatus: ${dateStr}, =${hospitalId}, =${originalPlanStr}, =${newPlan}`);
// }
if (newPlan === "0" && originalPlanStr !== "0") {
// console.log(` - : cancelled ()`);
return 'cancelled';
@ -2011,8 +1940,6 @@ export default {
hasScheduleConflict(schedule) {
if (this.is_allow_coincide) return false; //
// console.log('=== ===', schedule._dateStr);
const timeSlots = {
morning: new Set(), //
afternoon: new Set() //
@ -2051,14 +1978,14 @@ export default {
const hasAfternoonConflict = timeSlots.afternoon.size > 1;
const hasConflict = hasMorningConflict || hasAfternoonConflict;
if (hasConflict) {
console.log(`冲突检测结果 ${schedule._dateStr}:`, {
上午时段医院: Array.from(timeSlots.morning),
下午时段医院: Array.from(timeSlots.afternoon),
上午冲突: hasMorningConflict,
下午冲突: hasAfternoonConflict
});
}
// if (hasConflict) {
// console.log(` ${schedule._dateStr}:`, {
// : Array.from(timeSlots.morning),
// : Array.from(timeSlots.afternoon),
// : hasMorningConflict,
// : hasAfternoonConflict
// });
// }
return hasConflict;
},
@ -2083,153 +2010,6 @@ export default {
doctor_id: this.doctor_id,
}).then(response => {
const list = response.msg;
console.log(list, '原始数据===');
// let list = this.rawScheduleData = {
// "4": {
// "h_depart_name": "8",
// "worktime_no_fixed": 0,
// "display_work_days": 0,
// "morning_worktime": "09:00-12:00",
// "afternoon_worktime": "12:00-23:00",
// "worktime_list": {
// "1": {
// "id": "92",
// "doctor_id": "3",
// "depart_id": "4",
// "week_day": "1",
// "plan": "2",
// "work_paln_desc": ""
// },
// "2": {
// "id": "93",
// "doctor_id": "3",
// "depart_id": "4",
// "week_day": "2",
// "plan": "3",
// "work_paln_desc": ""
// },
// "3": {
// "id": "94",
// "doctor_id": "3",
// "depart_id": "4",
// "week_day": "3",
// "plan": "2",
// "work_paln_desc": ""
// },
// "4": {
// "id": "95",
// "doctor_id": "3",
// "depart_id": "4",
// "week_day": "4",
// "plan": "1",
// "work_paln_desc": ""
// },
// "5": {
// "id": "96",
// "doctor_id": "3",
// "depart_id": "4",
// "week_day": "5",
// "plan": "3",
// "work_paln_desc": ""
// },
// "6": {
// "id": "97",
// "doctor_id": "3",
// "depart_id": "4",
// "week_day": "6",
// "plan": "3",
// "work_paln_desc": ""
// },
// "7": {
// "id": "98",
// "doctor_id": "3",
// "depart_id": "4",
// "week_day": "7",
// "plan": "0",
// "work_paln_desc": ""
// }
// },
// "temp_change_worktime": {
// "2025-11-13": {
// "id": "60",
// "doctor_id": "3",
// "depart_id": "4",
// "morning_plan": "0",
// "afternoon_plan": "0",
// "date": "2025-11-13",
// "plan": 0,
// "work_paln_desc": "",
// "date_paln_desc": "11.13"
// }
// }
// },
// "6": {
// "h_depart_name": "",
// "worktime_no_fixed": 1,
// "display_work_days": 3,
// "morning_worktime": "08:00-11:00",
// "afternoon_worktime": "13:00-16:00",
// "worktime_list": {
// "2025-11-13": {
// "id": "47",
// "doctor_id": "3",
// "depart_id": "6",
// "morning_plan": "1",
// "afternoon_plan": "0",
// "date": "2025-11-13",
// "plan": 1,
// "work_paln_desc": "",
// "date_paln_desc": "11.13"
// },
// "2025-11-14": {
// "id": "48",
// "doctor_id": "3",
// "depart_id": "6",
// "morning_plan": "1",
// "afternoon_plan": "0",
// "date": "2025-11-14",
// "plan": 1,
// "work_paln_desc": "",
// "date_paln_desc": "11.14"
// },
// "2025-11-15": {
// "id": "49",
// "doctor_id": "3",
// "depart_id": "6",
// "morning_plan": "1",
// "afternoon_plan": "0",
// "date": "2025-11-15",
// "plan": 1,
// "work_paln_desc": "",
// "date_paln_desc": "11.15"
// },
// "2025-11-16": {
// "id": "50",
// "doctor_id": "3",
// "depart_id": "6",
// "morning_plan": "1",
// "afternoon_plan": "0",
// "date": "2025-11-16",
// "plan": 1,
// "work_paln_desc": "",
// "date_paln_desc": "11.16"
// },
// "2025-11-17": {
// "id": "51",
// "doctor_id": "3",
// "depart_id": "6",
// "morning_plan": "1",
// "afternoon_plan": "0",
// "date": "2025-11-17",
// "plan": 1,
// "work_paln_desc": "",
// "date_paln_desc": "11.17"
// },
// }
// },
// }
if (response.code == 0) {
//
this.hosList = Object.keys(list).map(item => {
@ -2240,7 +2020,6 @@ export default {
});
//
this.hosListCopy = JSON.parse(JSON.stringify(this.hosList))
//
this.rawScheduleData = JSON.parse(JSON.stringify(list));
@ -2519,199 +2298,6 @@ export default {
},
// setDepartWorkTime
async setDepartWorkTime() {
const { display_work_days, planDays, worktime_no_fixed,worktimes } = this.houseCallSettingForm;
const params = {
doctor_id: this.doctor_id,
depart_id: this.depart_id,
worktime_no_fixed: worktime_no_fixed,
week_visit_plan: JSON.stringify(this.formatWorktimesArray(worktimes))
}
if (display_work_days == 1 && planDays > 0) {
params.display_work_days = planDays
}
// vs
const conflictResults = this.checkScheduleConflict(worktimes, worktime_no_fixed);
console.log('冲突检测结果:', conflictResults);
//
if (conflictResults.hasConflict && worktime_no_fixed == 0) {
this.visitDialogVisible = true;
this.hasConflictresult = conflictResults.conflicts;
this.visitDialogTitle = '出诊安排冲突,请确认';
this.visitConfirmText = '确定并保存';
return;
}
//
// await this.saveWorkTimeDirect(params);
},
// worktimes
formatWorktimesArray(worktimes) {
return Object.entries(worktimes).map(([key, value]) => ({
type: parseInt(key),
plan: value.plan
}));
},
//
checkScheduleConflict(newWorktimes, worktime_no_fixed) {
const conflicts = [];
let hasConflict = false;
if (!this.rawScheduleData) {
return { hasConflict: false, conflicts: [] };
}
console.log('开始冲突检测,当前设置医院:', this.depart_id);
console.log('新排班设置:', newWorktimes);
console.log('所有医院数据:', this.rawScheduleData);
//
Object.keys(this.rawScheduleData).forEach(hospitalId => {
// (depart_id=4)
if (hospitalId === this.depart_id.toString()) {
console.log('跳过当前医院:', hospitalId);
return;
}
const hospital = this.rawScheduleData[hospitalId];
console.log(`检查医院 ${hospitalId}: ${hospital.h_depart_name}`, hospital);
//
const hospitalConflicts = this.checkHospitalConflict(newWorktimes, hospital, worktime_no_fixed);
console.log(`医院 ${hospitalId} 的冲突:`, hospitalConflicts);
if (hospitalConflicts.length > 0) {
conflicts.push(...hospitalConflicts);
hasConflict = true;
}
});
console.log('最终冲突结果:', { hasConflict, conflicts });
return { hasConflict, conflicts };
},
//
checkHospitalConflict(newWorktimes, hospital) {
const conflicts = [];
if (hospital.worktime_no_fixed === 0) {
//
conflicts.push(...this.checkVsFixedHospital(newWorktimes, hospital));
} else {
//
conflicts.push(...this.checkVsNonFixedHospital(newWorktimes, hospital));
}
return conflicts;
},
//
checkVsNonFixedHospital(newWorktimes, hospital) {
const conflicts = [];
console.log('检查非固定排班医院冲突:', hospital.h_depart_name, hospital.worktime_list);
if (!hospital.worktime_list) return conflicts;
//
Object.keys(hospital.worktime_list).forEach(dateStr => {
const hospitalPlan = hospital.worktime_list[dateStr];
if (!hospitalPlan || hospitalPlan.plan === '0') return;
//
const date = new Date(dateStr);
const dayOfWeek = date.getDay() === 0 ? 7 : date.getDay();
const weekDayKey = dayOfWeek.toString();
//
const newSchedule = newWorktimes[weekDayKey];
if (!newSchedule || newSchedule.plan === '0') return;
console.log(`日期${dateStr}(周${dayOfWeek}): 新排班=${newSchedule.plan}, 医院排班=${hospitalPlan.plan}`);
//
const conflictShift = this.getConflictShift(newSchedule.plan, hospitalPlan.plan);
if (conflictShift) {
console.log(`发现冲突: ${dateStr}${newSchedule.plan} vs 医院${hospitalPlan.plan}, 冲突时段: ${conflictShift}`);
conflicts.push(this.createConflictInfo(
dateStr,
hospital.h_depart_name,
newSchedule.plan,
conflictShift, //
'非固定排班',
hospitalPlan.work_paln_desc,
this.weekPlan[dayOfWeek],//
));
}
});
return conflicts;
},
getConflictShift(newPlan, existingPlan) {
const planMap = {
'0': '休息',
'1': '上午',
'2': '下午',
'3': '全天班'
};
//
if (newPlan === '3') {
return planMap[existingPlan]; //
}
if (existingPlan === '3') {
return planMap[newPlan]; //
}
//
if (newPlan === existingPlan) {
return planMap[newPlan];
}
return null; //
},
//
checkVsFixedHospital(newWorktimes, hospital) {
const conflicts = [];
console.log('检查固定排班医院冲突:', hospital.h_depart_name, hospital.worktime_list);
//
Object.keys(newWorktimes).forEach(weekDay => {
const newPlan = newWorktimes[weekDay].plan;
if (newPlan === '0') {
return; //
}
//
const hospitalPlan = hospital.worktime_list && hospital.worktime_list[weekDay];
console.log(`${weekDay}: 新排班=${newPlan}, 医院排班=`, hospitalPlan);
if (hospitalPlan && hospitalPlan.plan !== '0') {
//
const conflictShift = this.getConflictShift(newPlan, hospitalPlan.plan);
if (conflictShift) {
console.log(`发现冲突: 周${weekDay}${newPlan} vs 医院${hospitalPlan.plan}, 冲突时段: ${conflictShift}`);
conflicts.push(this.createConflictInfo(
`${this.getWeekDayName(parseInt(weekDay))}`,
hospital.h_depart_name,
newPlan,
conflictShift, //
'固定排班',
hospitalPlan.work_paln_desc,
));
}
}
});
return conflicts;
},
//
getHospitalPlanForWeekDay(hospital, weekDay) {
if (hospital.worktime_no_fixed === 0 && hospital.worktime_list) {
@ -2724,36 +2310,9 @@ export default {
}
return null;
},
//
createConflictInfo(date, hospitalName, newPlan, conflictShift, scheduleType, workDesc, dayOfWeek) {
console.log(dayOfWeek,this.getWeekDayName(1),'createConflictInfo:dayOfWeek');
const planMap = {
'0': '休息',
'1': '上午班',
'2': '下午班',
'3': '全天班'
};
const conflict = {
date: date,
hospital: hospitalName,
newPlan: planMap[newPlan],
conflictShift: conflictShift, //
scheduleType: scheduleType,
workDesc: workDesc,
dayOfWeek
// displayText: `${date} ${planMap[newPlan]} ${hospitalName} ${conflictShift} `
};
console.log('创建冲突信息:', conflict);
return conflict;
},
getWeekDayName(weekDay) {
const weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
return weekDays[weekDay - 1] || `${weekDay}`;
},
//
restoreCancel() {
//
this.houseCallSettingForm.worktimes = JSON.parse(JSON.stringify(this.form.worktimes));
},
//
singleTempConfirm() {
@ -2824,6 +2383,9 @@ export default {
this.generateMonthSchedule(this.currentDay);
this.countMonthlyConflicts(); //
},
async setDepartWorkTime() {
this.$refs.conflictDialog.setDepartWorkTime()
},
formatMonth(date, dayFlag) {
const d = new Date(date);
const year = d.getFullYear();
@ -3181,7 +2743,7 @@ export default {
'morning_worktime': response.data.morning_worktime ? response.data.morning_worktime.split('-') : '',
'afternoon_worktime': response.data.afternoon_worktime ? response.data.afternoon_worktime.split('-') : ''
}
this.houseCallSettingForm.worktimes = this.form.worktimes;
this.houseCallSettingForm.worktimes = JSON.parse(JSON.stringify(this.form.worktimes));
this.departType = (response.data.type || response.data.type === 0 || response.data.type === "0") ? [Number(response.data.type)] : []
this.departIsFixed = response.data.is_fixed == "1" ? true : false
@ -3647,39 +3209,6 @@ export default {
</script>
<style lang="scss" scoped>
//
.visitContent {
max-height: 300px;
overflow-y: auto;
}
.conflictTitle {
display: flex;
margin-bottom: 24px;
font-size: 14px;
color: #333;
line-height: 1.5;
flex-wrap: wrap;
word-wrap: break-word;
word-break: break-word;
white-space: normal;
}
.conflictTitle b {
color: #1890ff;
font-weight: 600;
margin: 0 4px;
word-break: break-all;
}
.hosPlanItem {
p {
color: #1E2226;
margin-bottom: 14px;
}
div {
color: #8A9099;
}
}
.cancelled-item {
text-decoration: line-through;

588
src/views/conflictDialog.vue

@ -0,0 +1,588 @@
<template>
<GuipDialog :dialogVisible="visitDialogVisible" :title="visitDialogTitle" :show-close-button="true" width="699px"
:show-cancel-button="visitShowCancelBtn" @confirm="handleVisitConfirm" :confirmText="visitConfirmText"
@cancel="handleVisitCancel" @close="handleVisitClose">
<div class="flex conflictTitle" v-if="is_allow_coincide && !isDoctorSet">
您设置的 <b>{{ h_realname }} </b>每周排班与以下现有出诊安排重叠请确定是否正确
</div>
<div class="flex conflictTitle" v-if="!is_allow_coincide && !isDoctorSet">
您设置的 <b>{{ h_realname }} </b>每周排班与以下现有出诊安排冲突请调整后再保存
</div>
<div class="visitContent mt24">
<div class="hosPlanItem mb24" v-for="(conflict, index) in hasConflictresult" :key="index">
<p>{{ conflict.date }} {{ conflict.dayOfWeek ? `${conflict.dayOfWeek}` : '' }}{{ conflict.conflictShift }}</p>
<div class="flex">
<span class="conflictTip">{{!is_allow_coincide ?'冲突':'重叠' }}</span>
<div>{{ conflict.hospital }}({{ conflict.type === 'fixed' ?
'固定排班' :
'临时出诊' }})</div>
</div>
</div>
</div>
<p v-if="hasConflictresultLength > 3" style="color: #FF4D4F;">等共{{hasConflictresultLength}}条出诊安排冲突请修改后再进行设置</p>
</GuipDialog>
</template>
<script>
import GuipDialog from '@/components/GuipDialog.vue';
export default {
props: {
is_allow_coincide: [Boolean, Number],
oldWorktimes: Object,
h_realname: String,
doctor_id: [Number, String],
depart_id: [Number, String],
houseCallSettingForm: Object,
rawScheduleDataProp: Object,
isDoctorSet:Boolean,
cancelText: String,
confirmText: String,
cancelBtnShow: String,
title: String,
// houseCallSettingForm: Object,
// getDoctorHosPreview: Function,
// formatWorktimesArray: Function,
},
components: {
GuipDialog,
},
data(){
return {
visitDialogTitle: '出诊安排重叠,请确认',//
visitDialogVisible: false,//
visitShowCancelBtn: true,//
visitConfirmText: '确定并保存',//
hasConflictresult: [],
rawScheduleData1:null,
weekPlan: {
'1': '周一',
'2': '周二',
'3': '周三',
'4': '周四',
'5': '周五',
'6': '周六',
'7': '周日',
},
weekDaysDesc: ['周日', '周一', '周二', '周三', '周四', '周五', '周六'],
hasConflictresultLength:0
}
},
created() {
console.log(this.rawScheduleDataProp,'-----t111his.rawScheduleDataProp===');
this.rawScheduleData1 = this.rawScheduleDataProp;
},
watch: {
// props
rawScheduleDataProp(newVal) {
this.rawScheduleData1 = newVal
console.log(newVal,'===----00999');
},
} ,
mounted() {
if(this.cancelBtnShow == '0'){
this.visitShowCancelBtn = false;
}
// console.log(this.rawScheduleDataProp,'this.rawScheduleDataProp===');
// if(this.rawScheduleDataProp){
// this.rawScheduleData1 = this.rawScheduleDataProp;
// }
if(this.cancelText){
this.visitConfirmText = this.cancelText;
}
if(this.confirmText){
this.visitConfirmText = this.confirmText;
}
if(this.title){
this.visitDialogTitle = this.title;
}
},
methods: {
open(){
this.visitDialogVisible = true;
this.getDoctorHosPreview();
},
handleVisitClose() {
this.visitDialogVisible = false;
},
handleVisitCancel() {
this.visitDialogVisible = false;
},
handleVisitConfirm() {
if (this.is_allow_coincide) {
this.saveWorkTimeDirect();
}
this.visitDialogVisible = false;
},
// ...start
async getDoctorHosPreview() {
await this.$http('POST', '/api/admin/get_departs_worktimes', {
doctor_id: this.doctor_id,
}).then(response => {
const list = response.msg;
if (response.code == 0) {
//
this.rawScheduleData1 = JSON.parse(JSON.stringify(list));
const data = this.analyzeCurrentMonthConflicts();
this.hasConflictresultLength = data.length;
this.hasConflictresult = data.length > 3 ? data.slice(0, 3) : data;
console.log(this.hasConflictresult, 'this.hasConflictresult');
}
}).catch(error => {
console.error(error, 'error')
})
},
// YYYY-MM-DD
formatDate(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}`;
},
//
analyzeCurrentMonthConflicts() {
const conflicts = [];
const today = new Date();
const currentYear = today.getFullYear();
const currentMonth = today.getMonth();
//
const lastDay = new Date(currentYear, currentMonth + 1, 0).getDate();
//
for (let day = today.getDate(); day <= lastDay; day++) {
const date = new Date(currentYear, currentMonth, day);
const dateStr = this.formatDate(date);
const dayOfWeek = date.getDay() === 0 ? 7 : date.getDay();
const dayConflicts = this.checkDayConflictsWithType(dateStr, dayOfWeek, this.rawScheduleData1, Object.keys(this.rawScheduleData1));
if (dayConflicts.length > 0) {
conflicts.push(...dayConflicts);
}
}
return conflicts;
},
//
checkDayConflictsWithType(dateStr, dayOfWeek, hospitals, hospitalIds) {
const conflicts = [];
const timeSlots = {
morning: [],
afternoon: []
};
//
hospitalIds.forEach(hid => {
const hospital = hospitals[hid];
let plan = "0";
let isTempAdjust = false;
let originalPlan = "0";
//
if (hospital.worktime_no_fixed === 0) {
//
const weeklyPlan = hospital.worktime_list && hospital.worktime_list[dayOfWeek];
originalPlan = weeklyPlan ? weeklyPlan.plan.toString() : "0";
} else {
//
const datePlan = hospital.worktime_list && hospital.worktime_list[dateStr];
originalPlan = datePlan ? datePlan.plan.toString() : "0";
}
//
if (hospital.temp_change_worktime && hospital.temp_change_worktime[dateStr]) {
const tempPlan = hospital.temp_change_worktime[dateStr];
plan = tempPlan.plan.toString();
isTempAdjust = true;
} else {
plan = originalPlan;
}
if (plan !== "0") {
const hospitalInfo = {
hid,
name: hospital.h_depart_name,
plan,
originalPlan,
isTempAdjust,
scheduleType: isTempAdjust ? '临时出诊' : '固定排班'
};
if (plan === "1" || plan === "3") {
timeSlots.morning.push(hospitalInfo);
}
if (plan === "2" || plan === "3") {
timeSlots.afternoon.push(hospitalInfo);
}
}
});
//
if (timeSlots.morning.length > 1) {
conflicts.push(this.createConflictInfoWithType(
dateStr,
timeSlots.morning,
'上午'
));
}
if (timeSlots.afternoon.length > 1) {
conflicts.push(this.createConflictInfoWithType(
dateStr,
timeSlots.afternoon,
'下午'
));
}
return conflicts;
},
//
createConflictInfoWithType(date, hospitals, timeSlot) {
const dateObj = new Date(date);
const dayOfWeek = this.weekDaysDesc[dateObj.getDay()];
//
const hospitalGroups = {
fixed: hospitals.filter(h => !h.isTempAdjust).map(h => h.name),
temp: hospitals.filter(h => h.isTempAdjust).map(h => h.name)
};
let hospitalDisplay = '';
if (hospitalGroups.fixed.length > 0) {
hospitalDisplay += hospitalGroups.fixed.join('、') + '固定排班';
}
if (hospitalGroups.temp.length > 0) {
if (hospitalDisplay) hospitalDisplay += '、';
hospitalDisplay += hospitalGroups.temp.join('、') + '临时出诊';
}
return {
date: date,
hospital: hospitalDisplay,
conflictShift: timeSlot,
type: hospitalGroups.temp.length > 0 ? 'mixed' : 'fixed',
dayOfWeek: dayOfWeek,
hospitals: hospitals,
displayText: `${date}${dayOfWeek}${timeSlot}班:${hospitalDisplay}`
};
},
// ..end
async setDepartWorkTime() {
const { display_work_days, planDays, worktime_no_fixed,worktimes } = this.houseCallSettingForm;
const params = {
doctor_id: this.doctor_id,
depart_id: this.depart_id,
worktime_no_fixed: worktime_no_fixed,
week_visit_plan: JSON.stringify(this.formatWorktimesArray(worktimes))
}
if (display_work_days == 1 && planDays > 0) {
params.display_work_days = planDays
}
// vs
const conflictResults = this.checkScheduleConflict(worktimes, worktime_no_fixed);
console.log('冲突检测结果:', conflictResults);
//
if (conflictResults.hasConflict && worktime_no_fixed == 0) {
this.visitDialogVisible = true;
this.hasConflictresult = conflictResults.conflicts;
if(this.is_allow_coincide){
this.visitDialogTitle = '出诊安排重叠,请确认';
this.visitConfirmText = '确定并保存';
this.visitShowCancelBtn = true;
}else{
this.visitDialogTitle = '出诊安排冲突,请确认';
this.visitConfirmText = '知道了';
this.visitShowCancelBtn = false;
}
return;
}
},
async saveWorkTimeDirect() {
const { display_work_days, planDays, worktime_no_fixed, worktimes } = this.houseCallSettingForm;
var worktimesArray = this.formatWorktimesArray(worktimes)
console.log(worktimesArray,'worktimesArray===');
const params = {
doctor_id: this.doctor_id,
depart_id: this.depart_id,
worktime_no_fixed: worktime_no_fixed,
week_visit_plan: JSON.stringify(worktimesArray)
}
if (display_work_days == 1 && planDays > 0) {
params.display_work_days = planDays
}
await this.$http('POST', '/api/admin/set_depart_worktime', {
...params
}).then(response => {
if (response.code == 0) {
this.$Message.success(response.msg || '设置成功')
// this.form.worktimes = worktimes;
this.getDoctorHosPreview();
}
}).catch(error => {
console.error(error, 'error')
})
},
//
checkScheduleConflict(newWorktimes, worktime_no_fixed) {
console.log(newWorktimes, worktime_no_fixed,this.rawScheduleData1, 'newWorktimes, worktime_no_fixed');
debugger
const conflicts = [];
let hasConflict = false;
if (!this.rawScheduleData1) {
return { hasConflict: false, conflicts: [] };
}
// console.log(':', this.depart_id);
// console.log(':', newWorktimes);
// console.log(':', this.rawScheduleData1);
//
Object.keys(this.rawScheduleData1).forEach(hospitalId => {
// (depart_id=4)
if (hospitalId === this.depart_id.toString()) {
console.log('跳过当前医院:', hospitalId);
return;
}
const hospital = this.rawScheduleData1[hospitalId];
console.log(`检查医院 ${hospitalId}: ${hospital.h_depart_name}`, hospital);
//
const hospitalConflicts = this.checkHospitalConflict(newWorktimes, hospital, worktime_no_fixed);
console.log(`医院 ${hospitalId} 的冲突:`, hospitalConflicts);
if (hospitalConflicts.length > 0) {
conflicts.push(...hospitalConflicts);
hasConflict = true;
}
});
console.log('最终冲突结果:', { hasConflict, conflicts });
return { hasConflict, conflicts };
},
//
checkHospitalConflict(newWorktimes, hospital) {
debugger
const conflicts = [];
if (hospital.worktime_no_fixed === 0) {
//
conflicts.push(...this.checkVsFixedHospital(newWorktimes, hospital));
} else {
//
conflicts.push(...this.checkVsNonFixedHospital(newWorktimes, hospital));
}
return conflicts;
},
//
checkVsFixedHospital(newWorktimes, hospital) {
const conflicts = [];
console.log('检查固定排班医院冲突:', hospital.h_depart_name, hospital.worktime_list);
//
Object.keys(newWorktimes).forEach(weekDay => {
const newPlan = newWorktimes[weekDay].plan;
if (newPlan === '0') {
return; //
}
//
const hospitalPlan = hospital.worktime_list && hospital.worktime_list[weekDay];
console.log(`${weekDay}: 新排班=${newPlan}, 医院排班=`, hospitalPlan);
if (hospitalPlan && hospitalPlan.plan !== '0') {
//
const conflictShift = this.getConflictShift(newPlan, hospitalPlan.plan);
if (conflictShift) {
console.log(`发现冲突: 周${weekDay}${newPlan} vs 医院${hospitalPlan.plan}, 冲突时段: ${conflictShift}`);
conflicts.push(this.createConflictInfo(
`${this.getWeekDayName(parseInt(weekDay))}`,
hospital.h_depart_name,
newPlan,
conflictShift, //
'固定排班',
hospitalPlan.work_paln_desc,
));
}
}
});
return conflicts;
},
//
checkVsNonFixedHospital(newWorktimes, hospital) {
const conflicts = [];
console.log('检查非固定排班医院冲突:', hospital.h_depart_name, hospital.worktime_list);
if (!hospital.worktime_list) return conflicts;
//
Object.keys(hospital.worktime_list).forEach(dateStr => {
const hospitalPlan = hospital.worktime_list[dateStr];
if (!hospitalPlan || hospitalPlan.plan === '0') return;
//
const date = new Date(dateStr);
const dayOfWeek = date.getDay() === 0 ? 7 : date.getDay();
const weekDayKey = dayOfWeek.toString();
//
const newSchedule = newWorktimes[weekDayKey];
if (!newSchedule || newSchedule.plan === '0') return;
// console.log(`${dateStr}(${dayOfWeek}): =${newSchedule.plan}, =${hospitalPlan.plan}`);
//
const conflictShift = this.getConflictShift(newSchedule.plan, hospitalPlan.plan);
if (conflictShift) {
// console.log(`: ${dateStr} ${newSchedule.plan} vs ${hospitalPlan.plan}, : ${conflictShift}`);
conflicts.push(this.createConflictInfo(
dateStr,
hospital.h_depart_name,
newSchedule.plan,
conflictShift, //
'非固定排班',
hospitalPlan.work_paln_desc,
this.weekPlan[dayOfWeek],//
));
}
});
return conflicts;
},
createConflictInfo(date, hospitalName, newPlan, conflictShift, scheduleType, workDesc, dayOfWeek) {
// console.log(dayOfWeek,this.getWeekDayName(1),'createConflictInfo:dayOfWeek');
const planMap = {
'0': '休息',
'1': '上午班',
'2': '下午班',
'3': '全天班'
};
const conflict = {
date: date,
hospital: hospitalName,
newPlan: planMap[newPlan],
conflictShift: conflictShift, //
scheduleType: scheduleType,
workDesc: workDesc,
dayOfWeek
// displayText: `${date} ${planMap[newPlan]} ${hospitalName} ${conflictShift} `
};
console.log('创建冲突信息:', conflict);
return conflict;
},
getWeekDayName(weekDay) {
const weekDays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
return weekDays[weekDay - 1] || `${weekDay}`;
},
getConflictShift(newPlan, existingPlan) {
const planMap = {
'0': '休息',
'1': '上午',
'2': '下午',
'3': '全天班'
};
//
if (newPlan === '3') {
return planMap[existingPlan]; //
}
if (existingPlan === '3') {
return planMap[newPlan]; //
}
//
if (newPlan === existingPlan) {
return planMap[newPlan];
}
return null; //
},
formatWorktimesArray(worktimes) {
return Object.entries(worktimes).map(([key, value]) => ({
type: parseInt(key),
plan: value.plan
}));
},
}
}
</script>
<style scoped lang="scss">
.visitContent {
max-height: 300px;
overflow-y: auto;
}
.conflictTitle {
display: flex;
margin-bottom: 24px;
font-size: 14px;
color: #333;
line-height: 1.5;
flex-wrap: wrap;
word-wrap: break-word;
word-break: break-word;
white-space: normal;
}
.conflictTitle b {
color: #1890ff;
font-weight: 600;
margin: 0 4px;
word-break: break-all;
}
.hosPlanItem {
p {
color: #1E2226;
margin-bottom: 14px;
}
div {
color: #8A9099;
}
}
.conflictTip {
height: 22px;
display: flex;
justify-content: center;
align-items: center;
padding: 2px 10px;
gap: 6px;
border-radius: 4px;
background: #FFF1F0;
box-sizing: border-box;
border: 1px solid #FFA39E;
font-size: 14px;
font-weight: normal;
line-height: normal;
text-align: center;
letter-spacing: 0.08em;
color: #FF4D4F;
box-sizing: border-box;
margin-right: 6px;
}
</style>
Loading…
Cancel
Save