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 || '设置当天排班人员在线失败' }; } }