feat: 优化需求
This commit is contained in:
parent
a88b0edd77
commit
0c369655b7
2
.env.dev
2
.env.dev
@ -26,3 +26,5 @@ CONFIG_PRESCRIPTION_PDF_BASE_URL=https://patient.youcan365.com/hn
|
||||
## 查询药品信息的时候 带上corpId (测试数据 药品信息存在多家机构, 但是线上各自独立部署, 所以测试环境带corpId区分下)
|
||||
CONFIG_SEARCH_DRUG_WITH_CORPID=YES
|
||||
|
||||
## 生成的咨询订单挂号id编号前缀, 也用于后续生成处方的编号 (his正式环境和测试环境同一个 生成序号规则相同, 产生同编号的话有问题, 所以加个前缀区分下)
|
||||
CONFIG_CONSULT_REGISTER_ID_PREFIX=Test
|
||||
2
.env.hn
2
.env.hn
@ -37,4 +37,6 @@ CONFIG_PRESCRIPTION_PDF_BASE_URL=https://patient.youcan365.com/hn
|
||||
## 查询药品信息的时候 带上corpId (测试数据 药品信息存在多家机构, 但是线上各自独立部署, 所以测试环境带corpId区分下)
|
||||
CONFIG_SEARCH_DRUG_WITH_CORPID=YES
|
||||
|
||||
## 生成的咨询订单挂号id编号前缀, 也用于后续生成处方的编号 (his正式环境和测试环境同一个 生成序号规则相同, 产生同编号的话有问题, 所以加个前缀区分下)
|
||||
CONFIG_CONSULT_REGISTER_ID_PREFIX=Test
|
||||
|
||||
|
||||
@ -498,7 +498,7 @@ function getFailureNotificationExt(error) {
|
||||
? `HIS上传错误:${cleanHisUploadFailureMessage(rawReason) || "未知错误"}`
|
||||
: errorSource === ERROR_SOURCES.RATIONAL_DRUG
|
||||
? `合理用药错误:${rawReason || "未知错误"}`
|
||||
: `系统错误:${rawReason || "未知错误"}`;
|
||||
: `系统错误:${rawReason || "未知错误"}`;
|
||||
return { errorSource, reason };
|
||||
}
|
||||
|
||||
@ -845,6 +845,7 @@ async function resolvePrescriptionDrugs(db, order) {
|
||||
dosage,
|
||||
dosage_unit: dosageUnit.name,
|
||||
dosage_unit_code: dosageUnit.code,
|
||||
dose_time_name: requested.dose_time_name || "",
|
||||
drugName: master.name,
|
||||
specification: master.specification || "",
|
||||
frequencyCode: frequency.code,
|
||||
|
||||
@ -1027,6 +1027,7 @@ describe("automatic prescription assembly", () => {
|
||||
dosage_form: "片剂",
|
||||
days: 3,
|
||||
dosage_unit: "mg",
|
||||
dose_time_name: "餐后",
|
||||
administration_method: "口服",
|
||||
freq: "每日两次",
|
||||
unit: "盒",
|
||||
@ -1083,6 +1084,7 @@ describe("automatic prescription assembly", () => {
|
||||
_id: drugId.toString(),
|
||||
erpId: "ERP-1",
|
||||
dosage_unit_code: "MG",
|
||||
dose_time_name: "餐后",
|
||||
frequencyCode: "BID",
|
||||
usageCode: "PO",
|
||||
quantity: 1,
|
||||
|
||||
@ -10,6 +10,7 @@ const { encryptOrderFields, decryptOrderFields, decryptOrderList } = require("./
|
||||
const { getRequiredDrugAccessLevels, doctorMeetsDrugAccessLevels } = require("../drug-access-level");
|
||||
|
||||
const doctorOrPharmacistOfflineMessage = "当前医生或药师不在线,暂无法提交问诊单,请稍后再试";
|
||||
const registerIdPrefix = process.env.CONFIG_CONSULT_REGISTER_ID_PREFIX || '';
|
||||
|
||||
const hisPayStatus = {
|
||||
0: "已支付",
|
||||
@ -158,7 +159,6 @@ async function addConsultOrder(item) {
|
||||
|
||||
async function addOnlineConsultOrder(params) {
|
||||
try {
|
||||
params.registerId = await generateRegisterId(db);
|
||||
const requiredDrugAccessLevels = await getRequiredDrugAccessLevels(db, params.drugs);
|
||||
const storeApi = require("../drug-store");
|
||||
const { success, list, message } = await storeApi(
|
||||
@ -187,6 +187,7 @@ async function addOnlineConsultOrder(params) {
|
||||
params.drugStoreName = store.name;
|
||||
params.drugStoreNo = store.login_no;
|
||||
const doctorCode = params.doctorCode.trim();
|
||||
params.registerId = await generateRegisterId(db);
|
||||
// 指定医生
|
||||
if (doctorCode) {
|
||||
const doctor = await db.collection("hlw-doctor").findOne(
|
||||
@ -261,7 +262,9 @@ async function addOnlineConsultOrder(params) {
|
||||
errorInfo: imAccountResult.errorInfo,
|
||||
};
|
||||
}
|
||||
params.medorg_order_no = common.generateUniqueStr('HLW', 12);
|
||||
const registerId = await generateRegisterId(db);
|
||||
params.registerId = registerId
|
||||
params.medorg_order_no = registerId;
|
||||
// 加密敏感字段
|
||||
const encryptedParams = encryptOrderFields(params);
|
||||
const { insertedId } = await db
|
||||
@ -2378,5 +2381,5 @@ async function generateRegisterId(db, type = 'consult-register-id') {
|
||||
}
|
||||
);
|
||||
const sequence = result.sequence;
|
||||
return `${day}${String(sequence).padStart(4, '0')}`;
|
||||
return `${registerIdPrefix}${day}${String(sequence).padStart(4, '0')}`;
|
||||
}
|
||||
|
||||
@ -130,10 +130,10 @@ exports.formatUploadRxData = function (data, opt) {
|
||||
appr_flag: i.forceSelfPay === 'Y' ? '2' : '1',
|
||||
dose_time_name: i.dose_time_name,
|
||||
}
|
||||
if (item.appr_flag === '2') {
|
||||
//[his要求]当appr_flag=2时必填,如果这个药品维护了限制使用范围的,传1,否则就传2
|
||||
item.self_pay_rea = i.limitUsageScope === 'Y' ? '1' : '2'
|
||||
}
|
||||
// if (item.appr_flag === '2') {
|
||||
// //[his要求]当appr_flag=2时必填,如果这个药品维护了限制使用范围的,传1,否则就传2
|
||||
// item.self_pay_rea = i.limitUsageScope === 'Y' ? '1' : '2'
|
||||
// }
|
||||
return item
|
||||
}),
|
||||
icds: data.diagnosisList.map((i) => ({
|
||||
|
||||
@ -2234,6 +2234,7 @@ async function getYbReviewResult(ctx, db) {
|
||||
name: 1,
|
||||
dosage_form: 1,
|
||||
specification: 1,
|
||||
forceSelfPay: 1
|
||||
},
|
||||
}
|
||||
)
|
||||
@ -2264,6 +2265,7 @@ async function getYbReviewResult(ctx, db) {
|
||||
dosage: drug.dosage,
|
||||
dosage_unit: drug.dosage_unit,
|
||||
dose_time_name: drug.dose_time_name,
|
||||
forceSelfPay: dbDrug.forceSelfPay
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
@ -31,6 +31,18 @@ function validateAccountId(accountId) {
|
||||
return { success: true, accountId: accountId.trim() };
|
||||
}
|
||||
|
||||
function isValidBirthday(birthday) {
|
||||
if (!/^\d{4}-\d{2}-\d{2}$/.test(birthday)) return false;
|
||||
const [year, month, day] = birthday.split('-').map(Number);
|
||||
const date = new Date(Date.UTC(year, month - 1, day));
|
||||
return (
|
||||
date.getUTCFullYear() === year
|
||||
&& date.getUTCMonth() + 1 === month
|
||||
&& date.getUTCDate() === day
|
||||
&& date.getTime() <= Date.now()
|
||||
);
|
||||
}
|
||||
|
||||
function validatePatient(item) {
|
||||
const accountResult = validateAccountId(item && item.accountId);
|
||||
if (!accountResult.success) return accountResult;
|
||||
@ -38,10 +50,27 @@ function validatePatient(item) {
|
||||
const name = typeof item.name === 'string' ? item.name.trim() : '';
|
||||
const certNo = typeof item.certNo === 'string' ? item.certNo.trim() : '';
|
||||
const mobile = typeof item.mobile === 'string' ? item.mobile.trim() : '';
|
||||
let birthday = typeof item.birthday === 'string' ? item.birthday.trim() : '';
|
||||
let sex = typeof item.sex === 'string' ? item.sex.trim() : '';
|
||||
|
||||
if (!name) return { success: false, message: '姓名不能为空' };
|
||||
if (certNo && !validator.isChinaId(certNo)) {
|
||||
return { success: false, message: '证件号格式不正确' };
|
||||
let certInfo = null;
|
||||
if (certNo) {
|
||||
certInfo = validator.getChinaIdInfo(certNo);
|
||||
if (!certInfo) return { success: false, message: '证件号格式不正确' };
|
||||
birthday = birthday || certInfo.birthday;
|
||||
sex = sex || certInfo.sex;
|
||||
}
|
||||
if (!birthday) return { success: false, message: '出生日期不能为空' };
|
||||
if (!isValidBirthday(birthday)) {
|
||||
return { success: false, message: '出生日期格式不正确' };
|
||||
}
|
||||
if (!sex) return { success: false, message: '性别不能为空' };
|
||||
if (!['男', '女'].includes(sex)) {
|
||||
return { success: false, message: '性别格式不正确' };
|
||||
}
|
||||
if (certInfo && (birthday !== certInfo.birthday || sex !== certInfo.sex)) {
|
||||
return { success: false, message: '出生日期或性别与证件号信息不一致' };
|
||||
}
|
||||
if (!mobile) return { success: false, message: '手机号不能为空' };
|
||||
if (!validator.isMobile(mobile)) {
|
||||
@ -62,6 +91,8 @@ function validatePatient(item) {
|
||||
name,
|
||||
certNo,
|
||||
mobile,
|
||||
birthday,
|
||||
sex,
|
||||
address,
|
||||
},
|
||||
data: {
|
||||
@ -69,6 +100,8 @@ function validatePatient(item) {
|
||||
anotherIdNo: certNo ? Sm4Util.encryptDataForSm3(certNo) : '',
|
||||
anotherName: Sm4Util.encryptDataForSm3(name),
|
||||
anotherMobile: Sm4Util.encryptDataForSm3(mobile),
|
||||
birthday,
|
||||
sex,
|
||||
address,
|
||||
},
|
||||
};
|
||||
@ -90,14 +123,16 @@ async function addHlwPatient(item, db) {
|
||||
}
|
||||
}
|
||||
// if (validation.origin.certNo) {
|
||||
const res = await hnHis({
|
||||
type: 'addHisCustomer',
|
||||
name: validation.origin.name,
|
||||
idCard: validation.origin.certNo,
|
||||
mobile: validation.origin.mobile,
|
||||
address: validation.origin.address,
|
||||
})
|
||||
if (!res.success) return res;
|
||||
// const res = await hnHis({
|
||||
// type: 'addHisCustomer',
|
||||
// name: validation.origin.name,
|
||||
// idCard: validation.origin.certNo,
|
||||
// mobile: validation.origin.mobile,
|
||||
// address: validation.origin.address,
|
||||
// birthday: validation.origin.birthday,
|
||||
// sex: validation.origin.sex,
|
||||
// })
|
||||
// if (!res.success) return res;
|
||||
// }
|
||||
|
||||
const result = await db.collection(COLLECTION_NAME).insertOne({
|
||||
@ -150,7 +185,7 @@ async function getHlwPatientList(item, db) {
|
||||
.find({ accountId: validation.accountId, disabled: false })
|
||||
.toArray();
|
||||
|
||||
const data = patients.map(toPatientData);
|
||||
const data = patients.map((patient) => toPatientData(patient, true));
|
||||
|
||||
return { success: true, message: '查询就诊人列表成功', data };
|
||||
} catch (error) {
|
||||
@ -181,13 +216,39 @@ async function getHlwPatient(item, db) {
|
||||
}
|
||||
}
|
||||
|
||||
function toPatientData(patient) {
|
||||
function calculateAge(birthday) {
|
||||
if (!isValidBirthday(birthday)) return '';
|
||||
|
||||
const [birthYear, birthMonth, birthDay] = birthday.split('-').map(Number);
|
||||
const today = new Date();
|
||||
let age = today.getFullYear() - birthYear;
|
||||
const hasHadBirthdayThisYear = (
|
||||
today.getMonth() + 1 > birthMonth
|
||||
|| (today.getMonth() + 1 === birthMonth && today.getDate() >= birthDay)
|
||||
);
|
||||
|
||||
if (!hasHadBirthdayThisYear) age -= 1;
|
||||
return age > 0 ? age : 1;
|
||||
}
|
||||
|
||||
function toPatientData(patient, normalizeDemographics = false) {
|
||||
const certNo = Sm4Util.decryptDataForSm3(patient.anotherIdNo);
|
||||
const certInfo = normalizeDemographics && certNo
|
||||
? validator.getChinaIdInfo(certNo)
|
||||
: null;
|
||||
// 证件号信息仅用于本次响应,不回写数据库中的历史就诊人数据。
|
||||
const birthday = certInfo ? certInfo.birthday : (patient.birthday || '');
|
||||
const sex = certInfo ? certInfo.sex : (patient.sex || '');
|
||||
|
||||
return {
|
||||
id: patient._id.toString(),
|
||||
accountId: patient.accountId,
|
||||
name: Sm4Util.decryptDataForSm3(patient.anotherName),
|
||||
certNo: Sm4Util.decryptDataForSm3(patient.anotherIdNo),
|
||||
certNo,
|
||||
mobile: Sm4Util.decryptDataForSm3(patient.anotherMobile),
|
||||
birthday,
|
||||
sex,
|
||||
...(normalizeDemographics ? { age: calculateAge(birthday) } : {}),
|
||||
address: patient.address || '',
|
||||
createTime: patient.createTime,
|
||||
};
|
||||
|
||||
@ -77,8 +77,11 @@ async function addHisCustomer(item) {
|
||||
const mdtrt_cert_no = typeof item.mdtrt_cert_no === 'string' ? item.mdtrt_cert_no.trim() : '';
|
||||
const ecToken = typeof item.ecToken === 'string' ? item.ecToken.trim() : '';
|
||||
const card_sn = typeof item.card_sn === 'string' ? item.card_sn.trim() : '';
|
||||
const birthday = typeof item.birthday === 'string' ? item.birthday.trim() : '';
|
||||
const sex = typeof item.sex === 'string' ? item.sex.trim() : '';
|
||||
|
||||
if (!name || !mobile) {
|
||||
return { success: false, message: '姓名、证件号、手机号不能为空' }
|
||||
return { success: false, message: '姓名、手机号不能为空' }
|
||||
}
|
||||
const payload = {
|
||||
type: 'addHisCustomer',
|
||||
@ -88,6 +91,10 @@ async function addHisCustomer(item) {
|
||||
address,
|
||||
buildType: '1', // 1.自费建档 2.电子凭证建档 3.线下医保
|
||||
};
|
||||
if (!idCard) {
|
||||
payload.brdy = birthday;
|
||||
payload.gend = sex === '男' ? 1 : 2
|
||||
}
|
||||
// 电子凭证建档 医保插件授权建档
|
||||
if (psnToken) {
|
||||
payload.psnToken = psnToken;
|
||||
|
||||
@ -173,10 +173,32 @@ function isChinaId(s) {
|
||||
return true
|
||||
}
|
||||
|
||||
function getChinaIdInfo(s) {
|
||||
if (typeof s !== 'string' || !isChinaId(s)) return null;
|
||||
|
||||
const sId = idTransfer(s);
|
||||
const birthday = `${sId.substring(6, 10)}-${sId.substring(10, 12)}-${sId.substring(12, 14)}`;
|
||||
const [year, month, day] = birthday.split('-').map(Number);
|
||||
const date = new Date(Date.UTC(year, month - 1, day));
|
||||
if (
|
||||
date.getUTCFullYear() !== year
|
||||
|| date.getUTCMonth() + 1 !== month
|
||||
|| date.getUTCDate() !== day
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
birthday,
|
||||
sex: Number(sId.charAt(16)) % 2 === 0 ? '女' : '男',
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
verifyString,
|
||||
verifyNumber,
|
||||
verifyListItem,
|
||||
isMobile,
|
||||
isChinaId
|
||||
}
|
||||
isChinaId,
|
||||
getChinaIdInfo,
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user