const dayjs = require("dayjs"); const customer = require("../customer"); const consultRecordQuery = require("./query"); const eConsultRecord = require("./e-consult-record"); const common = require("../../common"); const api = require("../../api"); let db = null; exports.main = async (content, DB) => { db = DB; switch (content.type) { case "addConsultRecord": return await addConsultRecord(content); case "updateConsultRecord": return await updateConsultRecord(content); case "deleteConsultRecord": return await deleteConsultRecord(content); case "getConsultRecord": return await getConsultRecord(content); case "getFirstTriagePersonUserId": return await getFirstTriagePersonUserId(content); case "getConsultRecordCount": return await consultRecordQuery.main(content, db); case "getConsultStageCount": return await consultRecordQuery.main(content, db); case "addEConsuleRecord": case "updateEConsuleRecord": case "getEConsuleRecord": case "getFirstEConsuleRecord": return await eConsultRecord.main(content, db); } }; /** * 新增咨询记录 * @param {Object} content 咨询记录内容 * @returns {Object} 结果 */ async function addConsultRecord(content) { const { corpId, customerId, triagePersonUserId, receptionPersonUserId, visitType, projects, teamId, triageRemark = "", source, } = content; if (!corpId) return { success: false, message: "机构id不能为空" }; if (!customerId) return { success: false, message: "客户id不能为空" }; const noTradeAmountCount = await db .collection("consult-record") .find({ corpId, customerId, tradeAmount: 0, visitStatus: { $ne: "canceled" }, }) .count(); const tradeAmountCount = await db .collection("consult-record") .find({ corpId, customerId, tradeAmount: { $ne: 0 }, visitStatus: { $ne: "canceled" }, }) .count(); let consultStage = "firstVisit"; if (noTradeAmountCount && !tradeAmountCount) { consultStage = "returnVisit"; } else if (tradeAmountCount) { consultStage = "moreConsumed"; } const query = { _id: common.generateRandomString(24), corpId, customerId, visitStatus: "pending", triageTime: dayjs().valueOf(), triagePersonUserId, receptionPersonUserId, createTime: dayjs().valueOf(), consultStage, visitType, teamId, triageRemark, consumeCount: tradeAmountCount, tradeAmount: 0, projects: Array.isArray(projects) ? projects : [], source: Array.isArray(source) ? source : [], }; await db.collection("consult-record").insertOne(query); await customer.main( { corpId, customerId, inHospitalTime: dayjs().valueOf(), type: "updateCustomerInHospitalTime", }, db ); return { success: true, message: "新增成功" }; } /** * 更新咨询记录 * @param {Object} content 更新内容 * @returns {Object} 结果 */ async function updateConsultRecord(content) { let { corpId, id, params } = content; const { tradeAmount, ...rest } = params; if (!corpId) return { success: false, message: "机构id不能为空" }; if (!id || !params) return { success: false, message: "缺少必要的字段" }; try { let updateParams = { $set: rest }; if (tradeAmount) { updateParams.$inc = { tradeAmount, consumeCount: 1, }; } await db.collection("consult-record").updateOne({ _id: id }, updateParams); return { success: true, message: "更新成功" }; } catch (error) { return { success: false, message: "更新失败" }; } } /** * 删除咨询记录 * @param {Object} content 删除内容 * @returns {Object} 结果 */ async function deleteConsultRecord(content) { const { corpId, id } = content; if (!corpId) return { success: false, message: "机构id不能为空" }; if (!id) return { success: false, message: "咨询记录id不能为空" }; try { await db.collection("consult-record").deleteOne({ corpId, _id: id }); return { success: true, message: "删除成功" }; } catch (error) { return { success: false, message: "删除失败" }; } } /** * 获取咨询记录列表 * @param {Object} content 查询内容 * @returns {Object} 结果 */ async function getConsultRecord(content) { const { corpId, name, mobile, page = 1, pageSize = 10, triageTimeDates, receptionPersonUserIds, reportPeoples, triagePersonUserIds, visitStatus, consumeStatus, consultStages, createTeamId, customerId, projectIds, tradeStatus, receptionDates, teamId, source, customerSource, } = content; if (!corpId) return { success: false, message: "机构id不能为空" }; let matchConditions = { corpId }; if (Array.isArray(projectIds) && projectIds.length) { matchConditions["projects._id"] = { $in: projectIds }; } if ( triageTimeDates && Array.isArray(triageTimeDates) && triageTimeDates.length === 2 ) { matchConditions.triageTime = { $gte: dayjs(triageTimeDates[0]).startOf("day").valueOf(), $lte: dayjs(triageTimeDates[1]).endOf("day").valueOf(), }; } if (source && Array.isArray(source) && source.length > 0) { matchConditions.source = { $in: source }; } if ( receptionDates && Array.isArray(receptionDates) && receptionDates.length === 2 ) { matchConditions.receptionTime = { $gte: dayjs(receptionDates[0]).startOf("day").valueOf(), $lte: dayjs(receptionDates[1]).endOf("day").valueOf(), }; } if ( receptionPersonUserIds && Array.isArray(receptionPersonUserIds) && receptionPersonUserIds.length > 0 ) { matchConditions.receptionPersonUserId = { $in: receptionPersonUserIds }; } if ( triagePersonUserIds && Array.isArray(triagePersonUserIds) && triagePersonUserIds.length > 0 ) { matchConditions.triagePersonUserId = { $in: triagePersonUserIds }; } if (visitStatus && Array.isArray(visitStatus) && visitStatus.length > 0) { matchConditions.visitStatus = { $in: visitStatus }; } if ( consumeStatus && Array.isArray(consumeStatus) && consumeStatus.length > 0 ) { let consumeCountQuery = []; if (consumeStatus.includes("notConsumed")) consumeCountQuery.push(0); if (consumeStatus.includes("consumed")) consumeCountQuery.push(1); if (consumeStatus.includes("moreConsumed")) consumeCountQuery.push({ $gt: 1 }); matchConditions.consumeCount = { $in: consumeCountQuery }; } let memberMatchConditions = {}; if (name) memberMatchConditions["customerInfo.name"] = new RegExp(name, "i"); if (mobile) memberMatchConditions["customerInfo.mobile"] = mobile; if (Array.isArray(customerSource) && customerSource.length) { memberMatchConditions["customerInfo.customerSource"] = { $in: customerSource, }; } if ( reportPeoples && Array.isArray(reportPeoples) && reportPeoples.length > 0 ) { memberMatchConditions["customerInfo.addMethod"] = "eStoreReport"; memberMatchConditions["customerInfo.creator"] = { $in: reportPeoples }; } if ( consultStages && Array.isArray(consultStages) && consultStages.length > 0 ) { matchConditions.consultStage = { $in: consultStages }; } if (customerId) matchConditions.customerId = customerId; if (teamId) matchConditions.teamId = teamId; if (tradeStatus === "traded") matchConditions.tradeAmount = { $ne: 0 }; if (tradeStatus === "untraded") matchConditions.tradeAmount = { $eq: 0 }; try { const totalResult = await db .collection("consult-record") .aggregate([ { $match: matchConditions }, { $lookup: { from: "member", localField: "customerId", foreignField: "_id", as: "customerInfo", }, }, { $unwind: "$customerInfo" }, { $match: memberMatchConditions }, { $count: "totalCount" }, ]) .toArray(); const result = await db .collection("consult-record") .aggregate([ { $match: matchConditions }, { $sort: { createTime: -1 } }, { $lookup: { from: "member", localField: "customerId", foreignField: "_id", as: "customerInfo", }, }, { $unwind: "$customerInfo" }, { $match: memberMatchConditions }, { $lookup: { from: "to-do-events", localField: "customerId", foreignField: "customerId", as: "todo", }, }, { $addFields: { hasPlan: { $cond: { if: { $and: [ { $in: ["untreated", "$todo.eventStatus"] }, { $in: [createTeamId, "$todo.executeTeamId"], }, ], }, then: true, else: false, }, }, }, }, { $project: { todo: 0, }, }, { $skip: (page - 1) * pageSize }, { $limit: pageSize }, ]) .toArray(); const list = result; const projectIds = []; list.forEach((item) => { item.projectIds = Array.isArray(item.projects) ? item.projects .map((project) => (project && project._id ? project._id : "")) .filter(Boolean) : []; projectIds.push(...item.projectIds); }); if (projectIds.length) { const res = await api.getCorpApi({ type: "getProjectNames", corpId, ids: projectIds, }); const m = new Map(); const projects = res && Array.isArray(res.data) ? res.data : []; projects.forEach((item) => { if (item._id && item.projectName) { m.set(item._id, item.projectName); } }); list.forEach((item) => { item.projectNames = item.projectIds .map((id) => m.get(id)) .filter(Boolean); }); } const total = totalResult.length > 0 ? totalResult[0].totalCount : 0; const pages = Math.ceil(total / pageSize); return { success: true, list, total, pages, message: "查询成功" }; } catch (error) { return { success: false, message: "查询失败", error: error.message }; } } /** * 获取首次分诊人用户ID * @param {Object} ctx 查询内容 * @returns {Object} 结果 */ async function getFirstTriagePersonUserId(ctx) { const { customerId, corpId } = ctx; if (!customerId || !corpId) return { success: false, message: "参数错误" }; try { const record = await db .collection("consult-record") .find({ customerId, corpId }) .sort({ triageTime: 1 }) .limit(1) .project({ triagePersonUserId: 1, triageTime: 1, receptionPersonUserId: 1, }) .toArray(); if (record.length > 0) { return { success: true, data: record[0] }; } else { return { success: false, message: "未找到对应的数据" }; } } catch (error) { return { success: false, message: error.message }; } }