2026-09-21 17:04:40 +08:00

164 lines
6.4 KiB
JavaScript

const dayjs = require('dayjs');
module.exports = async (item, db) => {
switch (item.type) {
case 'getHlwSchedule':
return getHlwSchedule(item, db);
case 'saveHlwSchedule':
return saveHlwSchedule(item, db);
case 'setTodayScheduledPeopleOnline':
return setTodayScheduledPeopleOnline(db);
}
};
function getDate(value) {
if (typeof value !== 'string' || !/^\d{4}-\d{2}-\d{2}$/.test(value)) return '';
const parsed = dayjs(value);
return parsed.isValid() && parsed.format('YYYY-MM-DD') === value ? value : '';
}
function getMonth(value) {
if (typeof value !== 'string' || !/^\d{4}-\d{2}$/.test(value)) return '';
const parsed = dayjs(`${value}-01`);
return parsed.isValid() && parsed.format('YYYY-MM') === value ? value : '';
}
async function getHlwSchedule({ corpId, month }, db) {
const normalizedCorpId = typeof corpId === 'string' ? corpId.trim() : '';
const normalizedMonth = getMonth(month);
if (!normalizedCorpId || !normalizedMonth) return { success: false, message: '机构或月份参数错误' };
try {
const startDate = `${normalizedMonth}-01`;
const endDate = dayjs(startDate).add(1, 'month').format('YYYY-MM-DD');
const data = await db.collection('hlw-schedule')
.find({ corpId: normalizedCorpId, date: { $gte: startDate, $lt: endDate } }, { projection: { _id: 0 } })
.sort({ date: 1 })
.toArray();
return { success: true, message: '查询成功', data };
} catch (error) {
return { success: false, message: error.message || '查询排班失败' };
}
}
async function saveHlwSchedule({ corpId, date, doctorNos = [], pharmacistNos = [], operator, operatorId }, db) {
const normalizedCorpId = typeof corpId === 'string' ? corpId.trim() : '';
const normalizedDate = getDate(date);
if (!normalizedCorpId || !normalizedDate) return { success: false, message: '机构或日期参数错误' };
if (dayjs(normalizedDate).isBefore(dayjs(), 'day')) return { success: false, message: '过去日期的排班不可编辑' };
const normalizeNos = values => [...new Set((Array.isArray(values) ? values : [])
.filter(value => typeof value === 'string' && value.trim())
.map(value => value.trim()))];
const normalizedDoctorNos = normalizeNos(doctorNos);
const normalizedPharmacistNos = normalizeNos(pharmacistNos);
try {
const personnel = await db.collection('hlw-doctor').find(
{
corpId: normalizedCorpId,
doctorNo: { $in: [...normalizedDoctorNos, ...normalizedPharmacistNos] },
job: { $in: ['doctor', 'pharmacist'] }
},
{ projection: { doctorNo: 1, doctorName: 1, job: 1 } }
).toArray();
const peopleByNo = new Map(personnel.map(person => [person.doctorNo, person]));
const toPeople = (nos, job) => {
const people = nos.map(no => peopleByNo.get(no));
return people.length === nos.length && people.every(person => person && person.job === job)
? people.map(({ doctorNo, doctorName }) => ({ doctorNo, doctorName }))
: null;
};
const doctors = toPeople(normalizedDoctorNos, 'doctor');
const pharmacists = toPeople(normalizedPharmacistNos, 'pharmacist');
if (!doctors || !pharmacists) return { success: false, message: '排班人员不存在或岗位不匹配' };
await db.collection('hlw-schedule').updateOne(
{ corpId: normalizedCorpId, date: normalizedDate },
{
$set: {
doctors,
pharmacists,
updater: typeof operator === 'string' ? operator : '',
updaterId: typeof operatorId === 'string' ? operatorId : '',
updateTime: Date.now()
},
$setOnInsert: { corpId: normalizedCorpId, date: normalizedDate, createTime: Date.now() }
},
{ upsert: true }
);
if (normalizedDate === dayjs().format('YYYY-MM-DD')) {
const onlineResult = await setTodayScheduledPeopleOnline(db);
if (!onlineResult.success) {
return { success: false, message: `排班已保存,但设置当天排班人员在线失败:${onlineResult.message}` };
}
}
return { success: true, message: '排班保存成功' };
} catch (error) {
return { success: false, message: error.message || '保存排班失败' };
}
}
async function setTodayScheduledPeopleOnline(db) {
const date = dayjs().format('YYYY-MM-DD');
try {
const schedules = await db.collection('hlw-schedule')
.find({ date }, { projection: { corpId: 1, doctors: 1, pharmacists: 1 } })
.toArray();
const peopleByCorp = new Map();
const addPeople = (corpId, people, job) => {
if (typeof corpId !== 'string' || !corpId.trim()) return;
if (!peopleByCorp.has(corpId)) {
peopleByCorp.set(corpId, { doctors: new Set(), pharmacists: new Set() });
}
const target = job === 'doctor'
? peopleByCorp.get(corpId).doctors
: peopleByCorp.get(corpId).pharmacists;
(Array.isArray(people) ? people : []).forEach((person) => {
if (typeof person?.doctorNo === 'string' && person.doctorNo.trim()) {
target.add(person.doctorNo.trim());
}
});
};
schedules.forEach(({ corpId, doctors, pharmacists }) => {
addPeople(corpId, doctors, 'doctor');
addPeople(corpId, pharmacists, 'pharmacist');
});
const updateTime = Date.now();
const operations = [];
for (const [corpId, { doctors, pharmacists }] of peopleByCorp) {
if (doctors.size > 0) {
operations.push({
updateMany: {
filter: { corpId, doctorNo: { $in: [...doctors] }, job: 'doctor' },
update: { $set: { onlineStatus: 'online', offlineTime: null, updateTime } }
}
});
}
if (pharmacists.size > 0) {
operations.push({
updateMany: {
filter: { corpId, doctorNo: { $in: [...pharmacists] }, job: 'pharmacist' },
update: { $set: { onlineStatus: 'online', offlineTime: null, updateTime } }
}
});
}
}
if (operations.length === 0) {
return { success: true, message: '当天无排班人员', data: { date, matchedCount: 0, modifiedCount: 0 } };
}
const result = await db.collection('hlw-doctor').bulkWrite(operations);
return {
success: true,
message: '当天排班人员已上线',
data: { date, matchedCount: result.matchedCount, modifiedCount: result.modifiedCount }
};
} catch (error) {
return { success: false, message: error.message || '设置当天排班人员在线失败' };
}
}