feat: 接口调整
This commit is contained in:
parent
c8f4c72205
commit
0165c2c064
@ -261,6 +261,8 @@ async function addHlwDrugInfo(ctx) {
|
|||||||
}
|
}
|
||||||
const diagnosisCodes = await validateApplicableDiagnosisCodes(params, db);
|
const diagnosisCodes = await validateApplicableDiagnosisCodes(params, db);
|
||||||
const { onSale, applicableDiagnosisCodes, ...data } = params;
|
const { onSale, applicableDiagnosisCodes, ...data } = params;
|
||||||
|
// ERP ID is allocated by the service so clients cannot supply or predict it.
|
||||||
|
data.erpId = await generateDrugErpId(db);
|
||||||
let newDrug = {};
|
let newDrug = {};
|
||||||
if (Object.keys(data).length) {
|
if (Object.keys(data).length) {
|
||||||
const [item] = getDrugList([data], true, peopleInfo, 'hlw', optionLists);
|
const [item] = getDrugList([data], true, peopleInfo, 'hlw', optionLists);
|
||||||
@ -299,6 +301,9 @@ async function editHlwDrugInfo(ctx) {
|
|||||||
const optionLists = await getHlwDrugOptionLists(ctx.corpId);
|
const optionLists = await getHlwDrugOptionLists(ctx.corpId);
|
||||||
const diagnosisCodes = await validateApplicableDiagnosisCodes(params, db);
|
const diagnosisCodes = await validateApplicableDiagnosisCodes(params, db);
|
||||||
const { onSale, applicableDiagnosisCodes, ...data } = params;
|
const { onSale, applicableDiagnosisCodes, ...data } = params;
|
||||||
|
// ERP ID is immutable after creation. Ignore it even when sent by an older
|
||||||
|
// client or a manually constructed request.
|
||||||
|
delete data.erpId;
|
||||||
const currentDrug = await db.collection("drug-info").findOne(
|
const currentDrug = await db.collection("drug-info").findOne(
|
||||||
{ _id: new ObjectId(id) },
|
{ _id: new ObjectId(id) },
|
||||||
{ projection: { erpId: 1, product_id: 1, product_id_str: 1 } }
|
{ projection: { erpId: 1, product_id: 1, product_id_str: 1 } }
|
||||||
@ -306,13 +311,6 @@ async function editHlwDrugInfo(ctx) {
|
|||||||
if (!currentDrug) {
|
if (!currentDrug) {
|
||||||
return { success: false, message: "未找到对应药品" }
|
return { success: false, message: "未找到对应药品" }
|
||||||
}
|
}
|
||||||
const legacyErpId = currentDrug.product_id_str || currentDrug.product_id;
|
|
||||||
const erpId = Object.prototype.hasOwnProperty.call(data, "erpId")
|
|
||||||
? data.erpId
|
|
||||||
: (currentDrug.erpId || (legacyErpId || legacyErpId === 0 ? String(legacyErpId) : ""));
|
|
||||||
if (typeof erpId !== "string" || !erpId.trim()) {
|
|
||||||
return { success: false, message: "ERP ID不能为空" }
|
|
||||||
}
|
|
||||||
let updateData = {};
|
let updateData = {};
|
||||||
if (Object.keys(data).length) {
|
if (Object.keys(data).length) {
|
||||||
const peopleInfo = {
|
const peopleInfo = {
|
||||||
@ -349,6 +347,23 @@ async function editHlwDrugInfo(ctx) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function generateDrugErpId(db) {
|
||||||
|
const key = 'drug-erp-id';
|
||||||
|
const type = 'drug-erp-id';
|
||||||
|
const result = await db.collection('sequence-counter').findOneAndUpdate(
|
||||||
|
{ key, type },
|
||||||
|
{
|
||||||
|
$inc: { sequence: 1 },
|
||||||
|
$setOnInsert: { key, type }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
upsert: true,
|
||||||
|
returnDocument: 'after'
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return String(result.sequence).padStart(6, '0');
|
||||||
|
}
|
||||||
|
|
||||||
async function setHlwDrugOnSale(ctx) {
|
async function setHlwDrugOnSale(ctx) {
|
||||||
const { ids, onSale, updaterId, updater } = ctx;
|
const { ids, onSale, updaterId, updater } = ctx;
|
||||||
const _ids = Array.isArray(ids) ? ids.filter(i => typeof i === 'string' && i.trim()).map(i => new ObjectId(i.trim())) : [ids];
|
const _ids = Array.isArray(ids) ? ids.filter(i => typeof i === 'string' && i.trim()).map(i => new ObjectId(i.trim())) : [ids];
|
||||||
|
|||||||
@ -558,6 +558,9 @@ async function getAllDoctorNos(ctx) {
|
|||||||
try {
|
try {
|
||||||
const jobs = Array.isArray(ctx.jobs) ? ctx.jobs : ['doctor'];
|
const jobs = Array.isArray(ctx.jobs) ? ctx.jobs : ['doctor'];
|
||||||
const query = ctx.showAll === true ? {} : { job: { $in: jobs } };
|
const query = ctx.showAll === true ? {} : { job: { $in: jobs } };
|
||||||
|
if (typeof ctx.corpId === 'string' && ctx.corpId.trim()) {
|
||||||
|
query.corpId = ctx.corpId.trim();
|
||||||
|
}
|
||||||
const res = await db
|
const res = await db
|
||||||
.collection("hlw-doctor")
|
.collection("hlw-doctor")
|
||||||
.find(query, { projection: { doctorNo: 1, doctorName: 1, job: 1 } })
|
.find(query, { projection: { doctorNo: 1, doctorName: 1, job: 1 } })
|
||||||
|
|||||||
163
hlw/hlw-schedule/index.js
Normal file
163
hlw/hlw-schedule/index.js
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
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 || '设置当天排班人员在线失败' };
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -29,6 +29,7 @@ const chineseMedicineOrder = require("./chinese-medicine-order");
|
|||||||
const hlwPatient = require("./hlw-patient");
|
const hlwPatient = require("./hlw-patient");
|
||||||
const scannedCardArchive = require("./scanned-card-archive");
|
const scannedCardArchive = require("./scanned-card-archive");
|
||||||
const selfAuth = require("./self-auth");
|
const selfAuth = require("./self-auth");
|
||||||
|
const hlwSchedule = require("./hlw-schedule");
|
||||||
|
|
||||||
module.exports = async (item, db, context) => {
|
module.exports = async (item, db, context) => {
|
||||||
switch (item.type) {
|
switch (item.type) {
|
||||||
@ -88,6 +89,10 @@ module.exports = async (item, db, context) => {
|
|||||||
case "autoSetPeopleOffline":
|
case "autoSetPeopleOffline":
|
||||||
case "getDoctorByNo":
|
case "getDoctorByNo":
|
||||||
return await hlwDoctor(item, db);
|
return await hlwDoctor(item, db);
|
||||||
|
case "getHlwSchedule":
|
||||||
|
case "saveHlwSchedule":
|
||||||
|
case "setTodayScheduledPeopleOnline":
|
||||||
|
return await hlwSchedule(item, db);
|
||||||
case "getDiagnosisList":
|
case "getDiagnosisList":
|
||||||
case "deleteHlwDiagnosis":
|
case "deleteHlwDiagnosis":
|
||||||
case "updateHlwDiagnosis":
|
case "updateHlwDiagnosis":
|
||||||
|
|||||||
17
trigger.js
17
trigger.js
@ -4,9 +4,24 @@ const dayjs = require("dayjs");
|
|||||||
|
|
||||||
exports.initSchedule = () => {
|
exports.initSchedule = () => {
|
||||||
// triggerEveryMinute()
|
// triggerEveryMinute()
|
||||||
triggerAtNight()
|
triggerAtNight();
|
||||||
|
triggerDailySchedulePeopleOnline();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function triggerDailySchedulePeopleOnline() {
|
||||||
|
// node-schedule 格式:秒 分 时 日 月 周;每天 00:30 将当天排班的医生、药师上线。
|
||||||
|
schedule.scheduleJob("0 30 0 * * *", async () => {
|
||||||
|
try {
|
||||||
|
const result = await api.getInternetHospitalApi({ type: "setTodayScheduledPeopleOnline" });
|
||||||
|
if (!result?.success) {
|
||||||
|
console.log(`[${dayjs().format('YYYY-MM-DD HH:mm:ss:SSS')}] 排班人员自动上线失败: ${result?.message || '未知错误'}`);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.log(`[${dayjs().format('YYYY-MM-DD HH:mm:ss:SSS')}] 排班人员自动上线失败: ${error.message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function triggerEveryMinute() {
|
async function triggerEveryMinute() {
|
||||||
schedule.scheduleJob("0 * * * * *", async () => {
|
schedule.scheduleJob("0 * * * * *", async () => {
|
||||||
runHighFrequencyTask()
|
runHighFrequencyTask()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user