336 lines
9.8 KiB
JavaScript
Raw Permalink Normal View History

2026-07-27 11:28:33 +08:00
const dayjs = require("dayjs");
const Sm4Util = require("../../utils/sm4-util");
/**
* 需要加密的字段列表
*/
const ENCRYPTED_FIELDS = ["name", "mobile", "idCard"];
/**
* 加密诊断记录敏感字段
* @param {Object} data - 诊断记录数据
* @returns {Object} 加密后的数据
*/
function encryptDiagnosticRecordFields(data) {
if (!data || typeof data !== "object") {
return data;
}
const encryptedData = { ...data };
ENCRYPTED_FIELDS.forEach((field) => {
if (
encryptedData[field] &&
typeof encryptedData[field] === "string" &&
encryptedData[field].trim() !== ""
) {
try {
encryptedData[field] = Sm4Util.encryptDataForSm3(encryptedData[field]);
} catch (error) {
console.error(`加密字段 ${field} 失败:`, error.message);
}
}
});
return encryptedData;
}
/**
* 解密诊断记录敏感字段
* @param {Object} data - 诊断记录数据
* @returns {Object} 解密后的数据
*/
function decryptDiagnosticRecordFields(data) {
if (!data || typeof data !== "object") {
return data;
}
const decryptedData = { ...data };
ENCRYPTED_FIELDS.forEach((field) => {
if (
decryptedData[field] &&
typeof decryptedData[field] === "string" &&
decryptedData[field].trim() !== ""
) {
try {
decryptedData[field] = Sm4Util.decryptDataForSm3(decryptedData[field]) || decryptedData[field];
} catch (error) {
console.error(`解密字段 ${field} 失败:`, error.message);
// 解密失败时保留原值
}
}
});
return decryptedData;
}
/**
* 批量解密诊断记录列表的敏感字段
* @param {Array} list - 诊断记录列表
* @returns {Array} 解密后的诊断记录列表
*/
function decryptDiagnosticRecordList(list) {
if (!Array.isArray(list)) {
return list;
}
return list.map((item) => decryptDiagnosticRecordFields(item));
}
exports.formatUploadRxData = function (data) {
return {
patientid: data.patientId,
orderno: data.medOrgOrderNo,
doctorcode: data.doctorCode,
unitcode: data.unitCode,
hospid: "108",
phar_code: data.pharmacistNo,
phar_name: data.pharmacist,
phar_chk_time: dayjs(data.auditTime).format("YYYY-MM-DD HH:mm:ss"),
ysjd_time: dayjs(data.prescriptionStartTime).format("YYYY-MM-DD HH:mm:ss"),
prsc_time: dayjs(data.prescriptionEndTime).format("YYYY-MM-DD HH:mm:ss"),
details: data.drugs.map((i) => {
const item = {
drug_id: i.insurance_code,
drug_name: i.drugName,
drug_dosform: "",
drug_spec: i.specification || "",
drug_pric: "0",
drug_cnt: i.quantity,
drug_sumamt: "0",
medc_way_codg: i.usageCode,
medc_way_dscr: i.usageName,
medc_days: i.days,
remark: "",
limit_flag: "0",
used_frqu_codg: i.frequencyCode,
used_frqu_name: i.frequencyName,
sin_doscnt: i.dosage,
sin_dosunt: i.dosage_unit,
unit: i.unit,
appr_flag: i.forceSelfPay === 'Y' ? '2' : '1'
}
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) => ({
icd_code: i.code,
icd_name: i.name,
})),
};
};
exports.formatOnlineMedicinePurchaseData = function (data) {
const details = data.drugs.map(i => {
const item = {
drug_type: "xy",
drug_groupno: i.hisChargeInfo.drugGroupNo,
drug_group: "",
drug_id: i.hisChargeInfo.drugId,
drug_serial: i.hisChargeInfo.drugSerial,
drug_name: i.drugName,
drug_spec: i.specification || "",
drug_pric: i.hisChargeInfo.drugPrice,
drug_cnt: i.quantity,
drug_sumamt: i.hisChargeInfo.drugSumamt, //总金额 总金额=数量*单价
supple_code: i.usageCode,
supple_name: i.usageName,
medc_days: i.days,
drug_times: 1,
drug_comm: "",
drug_ma: "",
remark: "",
limit_flag: "0",
usage: i.frequencyCode,
usage_name: i.frequencyName,
sin_doscnt: i.dosage,
sin_dosunt: i.dosage_unit_code,
unit: i.unit,
appr_flag: i.forceSelfPay === 'Y' ? '2':'1'
}
if (item.appr_flag === '2') {
//[his要求]当appr_flag=2时必填如果这个药品维护了限制使用范围的传1否则就传2
item.self_pay_rea = i.limitUsageScope === 'Y' ? '1' : '2'
}
return item
})
return {
patientid: data.patientId,
registerid: "",
orderno: data.medOrgOrderNo,
doctorcode: data.doctorCode,
unitcode: data.unitCode,
visit_time: dayjs(data.prescriptionStartTime).format("YYYY-MM-DD HH:mm:ss"),
area_code: data.areaCode,
hospid: "108",
details,
icds: data.diagnosisList.map((i, idx) => ({
icd_code: i.code,
icd_name: i.name,
sort: idx + 1
}))
}
}
exports.formatWinePurchaseData = function (data, order) {
const [wine] = data.wines;
return {
patientid: data.patientId,
registerid: order.medorg_order_no,
orderno: data.medOrgOrderNo,
doctorcode: data.doctorCode,
unitcode: data.unitCode,
visit_time: dayjs(data.prescriptionStartTime).format("YYYY-MM-DD HH:mm:ss"),
operator_id: data.drugStoreNo,
tc_code: wine.hisId,
drug_times: wine.quantity,
delivery: data.pickUpType === 'delivery' ? 1 :0,//是否配送 1配送 0自提 order.pickUpType === 'delivery' ? 1 :0
hospid: "108",
icds: data.diagnosisList.map((i) => ({
icd_code: i.code,
icd_name: i.name,
})),
};
}
/**
* 构建支持明文+密文混合搜索的查询条件
* 用于数据迁移期间数据库中同时存在明文和密文数据的情况
*
* @param {string} fieldName - 字段名 'name', 'mobile', 'idCard'
* @param {string} searchValue - 搜索值明文
* @param {boolean} exactMatch - 是否精确匹配默认为false模糊匹配
* @returns {Object} MongoDB查询条件对象
*/
function buildHybridSearchQuery(fieldName, searchValue, exactMatch = false) {
if (
!searchValue ||
typeof searchValue !== "string" ||
searchValue.trim() === ""
) {
return null;
}
const trimmedValue = searchValue.trim();
try {
// 尝试加密搜索值
const encryptedValue = Sm4Util.encryptDataForSm3(trimmedValue);
if (exactMatch) {
// 精确匹配:同时匹配明文和密文
return {
$or: [
{ [fieldName]: trimmedValue }, // 明文精确匹配
{ [fieldName]: encryptedValue }, // 密文精确匹配
],
};
} else {
// 模糊匹配:明文用正则,密文用精确匹配(因为密文无法模糊匹配)
return {
$or: [
{ [fieldName]: new RegExp(trimmedValue, "i") }, // 明文模糊匹配(不区分大小写)
{ [fieldName]: encryptedValue }, // 密文精确匹配
],
};
}
} catch (error) {
// 如果加密失败(如环境变量未配置),只搜索明文
console.warn(`加密搜索值失败,只搜索明文数据: ${error.message}`);
if (exactMatch) {
return { [fieldName]: trimmedValue };
} else {
return { [fieldName]: new RegExp(trimmedValue, "i") };
}
}
}
/**
* 批量构建混合搜索条件
* @param {Object} searchParams - 搜索参数对象 { name: '张三', mobile: '138' }
* @param {boolean} exactMatch - 是否精确匹配
* @returns {Array} MongoDB $and 条件数组
*/
function buildMultiFieldHybridSearch(searchParams, exactMatch = false) {
const conditions = [];
Object.keys(searchParams).forEach((fieldName) => {
const searchValue = searchParams[fieldName];
const condition = buildHybridSearchQuery(
fieldName,
searchValue,
exactMatch
);
if (condition) {
conditions.push(condition);
}
});
return conditions;
}
exports.formatReviewData = function (data) {
const details = data.drugs.map(i => {
const item = {
drug_type: "xy",
drug_groupno: i.hisChargeInfo.drugGroupNo,
drug_group: "",
drug_id: i.hisChargeInfo.drugId,
drug_serial: i.hisChargeInfo.drugSerial,
drug_name: i.drugName,
drug_spec: i.specification || "",
drug_pric: i.hisChargeInfo.drugPrice,
drug_cnt: i.quantity,
drug_sumamt: i.hisChargeInfo.drugSumamt, //总金额 总金额=数量*单价
supple_code: i.usageCode,
supple_name: i.usageName,
medc_days: i.days,
drug_times: 1,
drug_comm: "",
drug_ma: "",
remark: "",
limit_flag: "0",
usage: i.frequencyCode,
usage_name: i.frequencyName,
sin_doscnt: i.dosage,
sin_dosunt: i.dosage_unit_code,
unit: i.unit,
appr_flag: i.forceSelfPay === 'Y' ? '2':'1'
}
if (item.appr_flag === '2') {
//[his要求]当appr_flag=2时必填如果这个药品维护了限制使用范围的传1否则就传2
item.self_pay_rea = i.limitUsageScope === 'Y' ? '1' : '2'
}
return item
})
return {
patientid: data.patientId,
registerid: "",
orderno: data.medOrgOrderNo,
doctorcode: data.doctorCode,
unitcode: data.unitCode,
visit_time: dayjs(data.prescriptionStartTime).format("YYYY-MM-DD HH:mm:ss"),
area_code: data.areaCode,
hospid: "108",
details,
icds: data.diagnosisList.map((i, idx) => ({
icd_code: i.code,
icd_name: i.name,
sort: idx + 1
}))
}
}
exports.encryptDiagnosticRecordFields = encryptDiagnosticRecordFields;
exports.decryptDiagnosticRecordFields = decryptDiagnosticRecordFields;
exports.decryptDiagnosticRecordList = decryptDiagnosticRecordList;
exports.buildHybridSearchQuery = buildHybridSearchQuery;
exports.buildMultiFieldHybridSearch = buildMultiFieldHybridSearch;
exports.ENCRYPTED_FIELDS = ENCRYPTED_FIELDS;