2026-07-27 11:28:33 +08:00

1227 lines
52 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const dayjs = require("dayjs");
const validator = require('../../utils/validator.js');
const { ObjectId } = require("mongodb");
const tradeApi = require('../trade');
const hlwConfigApi = require('../hlw-config');
const BigNumber = require('bignumber.js');
const Sm4Util = require('../../utils/sm4-util');
const zytHis = require('../zyt-his');
const types = require('./types');
const format = require('./format');
const { buildHybridSearchQuery } = require('../diagnostic-record/format');
const { output } = types;
const HisPayStatus = {
0: '已收费',
1: '已退费',
5: '未收费',
x: '已作废',
}
let scheduleTaskIsRunning = false; // 定时任务是否正在运行
let db
module.exports = async (item, mongodb) => {
db = mongodb;
switch (item.type) {
case "getRxMedicinePurchaseOrderId":
return await getRxMedicinePurchaseOrderId(item);
case "addMedicinePurchaseOrder":
return await addMedicinePurchaseOrder(item);
case "getMedicinePurchaseOrder":
return await getMedicinePurchaseOrder(item);
case "getMedicinePurchaseOrderList":
return await getMedicinePurchaseOrderList(item);
case "getMedicinePurchaseShippingList":
// 新增接口:供 PC HLWSHIPPINGLIST 使用,支持更多筛选条件
return await getMedicinePurchaseShippingList(item);
case "getMedicinePurchaseOrderDetail":
return await getMedicinePurchaseOrderDetail(item);
case "getMedicineOrderTradeNo":
return await getMedicineOrderTradeNo(item);
case "reloadYbPayStatus":
return await reloadYbPayStatus(item);
case "reloadZfPayStatus":
return await reloadZfPayStatus(item);
case "getCostDetails":
return await getCostDetails(item);
case "invokeOnlineMedicinePurchasePaySuccess":
return await invokeOnlineMedicinePurchasePaySuccess(item);
case "getOrderInvoice":
return await getOrderInvoice(item);
case "getShippingDetail":
return await getShippingDetail(item);
case "runMedicinePurchaseOrderSchedule":
return await runMedicinePurchaseOrderSchedule(item);
case "refundMedicinePurchaseOrderYbFee":
return await refundMedicinePurchaseOrderYbFee(item);
case "refundMedicinePurchaseOrderSelfFee":
return await refundMedicinePurchaseOrderSelfFee(item);
case "purchaseTest":
return await purchaseTest(item);
case "updateAfterSaleInfo":
return await updateAfterSaleInfo(item);
case "getLastestPurchaseOrder":
return await getLastestPurchaseOrder(item);
case "getPatientPurchaseOrderList":
return await getPatientPurchaseOrderList(item);
case "getHighFreqAddressOrders":
return await getHighFreqAddressOrders(item);
}
}
function validMedicineAmount(amount) {
if (typeof amount !== 'number' || !(amount >= 0)) {
return false
}
// 金额最多精确到分
const cent = new BigNumber(amount).multipliedBy(100).toNumber();
return Number.isInteger(cent)
}
async function generatePickupCode(db, type = 'fengniao-pickup-code') {
const key = dayjs().format('YYYY-MM-DD');
const collection = db.collection('sequence-counter');
const result = await collection.findOneAndUpdate(
{ key, type }, // 添加 type 字段区分不同场景
{
$inc: { sequence: 1 },
$setOnInsert: { key, type }
},
{
upsert: true,
returnDocument: 'after'
}
);
const sequence = result.sequence;
return `${String(sequence).padStart(3, '0')}`;
}
async function createDeliveryOrder(order) {
try {
if (order.shippingType === 'fengniao') {
const fengniaoApi = require('../fengniao');
// 查询蜂鸟配送订单是否已经存在 如果存在则更新物流单号 如果不存在则创建订单
const detailRes = await fengniaoApi.main({ type: 'getOrderDetail', orderNo: order.orderNo });
const { data, unexist } = detailRes;
if (data && data.shippingNo) {
await db.collection('medicine-purchase-order').updateOne({ _id: order._id }, { $set: { shippingNo: data.shippingNo } });
return { success: true, message: '蜂鸟配送订单已存在', data: { shippingNo: data.shippingNo } };
}
if (unexist === true) {
const pickupCode = await generatePickupCode(db);
const fengniaoOrderData = format.formatFengniaoOrderData(order, pickupCode);
const { shippingNo } = await fengniaoApi.main({ type: 'createOrder', data: fengniaoOrderData });
if (shippingNo) {
await db.collection('medicine-purchase-order').updateOne({ _id: order._id }, { $set: { shippingNo, pickupCode } });
return { success: true, message: '蜂鸟配送订单创建成功', data: { shippingNo } };
}
}
} else if (order.shippingType === 'ems') {
const emsApi = require('../ems-express');
const emsOrderData = format.formatEMSOrderData(order);
const { success, data } = await emsApi.createOrder(emsOrderData);
if (success && data) {
await db.collection('medicine-purchase-order').updateOne({ _id: order._id }, { $set: { shippingNo: data.waybillNo } });
return { success: true, message: 'ems订单创建成功', data: { shippingNo: data.waybillNo } };
}
}
return { success: false, message: '购药订单物流下单失败' };
} catch (e) {
return { success: false, message: `购药订单物流下单错误:${e.message}` };
}
}
async function getMedicinePurchaseOrder(ctx) {
try {
if (typeof ctx.accountId !== 'string' || ctx.accountId.trim() === '') {
return { success: false, message: "账号id不能为空" };
}
if (typeof ctx.id !== 'string' || ctx.id.trim() === '') {
return { success: false, message: "配药订单id不能为空" };
}
const order = await db.collection('medicine-purchase-order').findOne({ accountId: ctx.accountId.trim(), _id: new ObjectId(ctx.id) }, { projection: output.orderDetail });
if (!order) {
return { success: false, message: "订单不存在" };
}
// 主动查询his订单支付状态, 如果支付状态变更, 则更新购药订单状态
if (order.status === 'unpay') {
const res = await getHisMedicinePurchase(order.patientId, order.orderNo);
if (res && res.success) {
if (res.data.pay_mark === '0') {
await db.collection('medicine-purchase-order').updateOne({ _id: order._id }, { $set: { status: 'ybPaid' } });
order.status = 'ybPaid';
}
else if (res.data.pay_mark === '1') {
await db.collection('medicine-purchase-order').updateOne({ _id: order._id }, { $set: { status: 'refunded' } });
order.status = 'refunded';
}
}
}
// 未支付的订单, 如果已过期, 则更新购药订单状态为已过期
else if (order.status === 'unpay' && dayjs(order.expireTime).isBefore(dayjs())) {
await db.collection('medicine-purchase-order').updateOne({ _id: order._id }, { $set: { status: 'expired' } });
order.status = 'expired';
}
order.anotherName = order.name; // 支付宝医保支付需要加密后的姓名和证件号
order.name = Sm4Util.decryptDataForSm3(order.name);
const result = { success: true, message: "查询购药订单成功", data: order };
if (ctx.withExpressInfo) {
const expressFeeRes = await getExpressFee(ctx.corpId.trim(), db);
if (!expressFeeRes.success) {
return expressFeeRes;
}
result.exprssFee = expressFeeRes.data;
}
return result;
} catch (e) {
return { success: false, message: e.message };
}
}
/**
* 获取购药订单交易单号以及支付类型
* @param {Object} ctx 请求参数
* @param {string} ctx.accountId 账号id
* @param {string} ctx.id 购药订单id
* @param {string} ctx.shippingType 配送方式
* @param {string} ctx.receiveName 收货人姓名
* @param {string} ctx.receivePhone 收货人手机号
* @param {string[]} ctx.receiveRegion 收货人地区
* @param {string} ctx.receiveAddress 收货人地址
* @param {number} ctx.receiveLatitude 收货人纬度
* @returns
*/
async function getMedicineOrderTradeNo(ctx) {
try {
const accountId = typeof ctx.accountId === 'string' ? ctx.accountId.trim() : '';
const id = typeof ctx.id === 'string' ? ctx.id.trim() : '';
if (accountId === '' || id === '') {
return { success: false, message: "账号id或购药订单id不能为空" };
}
const order = await db.collection('medicine-purchase-order').findOne({ accountId, _id: new ObjectId(id) });
if (!order) {
return { success: false, message: "购药订单不存在" };
}
if (order.status === 'unpay') {
const shippingType = typeof ctx.shippingType === 'string' ? ctx.shippingType.trim() : '';
const receiveName = typeof ctx.receiveName === 'string' ? ctx.receiveName.trim() : '';
const receivePhone = typeof ctx.receivePhone === 'string' ? ctx.receivePhone.trim() : '';
const receiveRegion = Array.isArray(ctx.receiveRegion) ? ctx.receiveRegion.map(i => typeof i == 'string' && i.trim()) : [];
const receiveAddress = typeof ctx.receiveAddress === 'string' ? ctx.receiveAddress.trim() : '';
const receiveLatitude = typeof ctx.receiveLatitude === 'number' ? ctx.receiveLatitude : 0;
const receiveLongitude = typeof ctx.receiveLongitude === 'number' ? ctx.receiveLongitude : 0;
let receiveData = { pass: false, msg: '' };
if (!['ems', 'fengniao'].includes(shippingType)) {
receiveData.msg = "配送方式无效";
receiveData.pass = false;
} else if (receiveName === '') {
receiveData.msg = "收货人姓名不能为空";
receiveData.pass = false;
} else if (receivePhone === '') {
receiveData.msg = "收货人手机号不能为空";
receiveData.pass = false;
} else if (!validator.isMobile(receivePhone)) {
receiveData.msg = "收货人手机号格式不正确";
receiveData.pass = false;
} else if (receiveRegion.length < 1 || receiveRegion.length > 3 || receiveRegion.some(i => typeof i !== 'string' || i.trim() === '' || i.length > 30)) {
receiveData.msg = "收货人地区格式不正确";
receiveData.pass = false;
} else if (receiveAddress === '') {
receiveData.msg = "收货人地址不能为空";
receiveData.pass = false;
} else if (receiveAddress.length > 200) {
receiveData.msg = "收货人地址不能超过200个字";
receiveData.pass = false;
} else if (typeof receiveLatitude !== 'number' || typeof receiveLongitude !== 'number') {
receiveData.msg = "收货人经纬度格式不正确";
receiveData.pass = false;
} else {
receiveData.pass = true;
}
// 之前没有保存过收货地址 校验收货地址信息
if (!order.receiveName && !receiveData.pass) {
return { success: false, message: receiveData.msg };
}
const expressFeeRes = await getExpressFee(ctx.corpId.trim(), db);
if (!expressFeeRes.success) {
return expressFeeRes;
}
const { shippingFee, shippingDiscount, shippingOriginalFee } = expressFeeRes.data[shippingType];
if (receiveData.pass) {
const updateRes = await db.collection('medicine-purchase-order').updateOne({ _id: new ObjectId(id) }, { $set: { shippingType, shippingFee, shippingDiscount, shippingOriginalFee, receiveName, receivePhone, receiveRegion, receiveAddress, receiveLatitude, receiveLongitude } });
if (!updateRes.matchedCount) {
return { success: false, message: "更新收货地址信息失败" };
}
}
}
if (order.status === 'unpay') {
const orderRes = await getHisMedicinePurchase(order.patientId, order.orderNo);
if (!orderRes || !orderRes.success) return orderRes;
if (!['0', '5'].includes(orderRes.data.pay_mark)) {
return { success: false, message: `购药订单支付状态异常:${HisPayStatus[orderRes.data.pay_mark] || '未知状态'}` };
}
if (orderRes.data.pay_mark === '5' && order.expireTime && dayjs(order.expireTime).isBefore(dayjs())) {
await db.collection('medicine-purchase-order').updateOne({ _id: order._id }, { $set: { status: 'expired' } });
return { success: false, message: "购药订单已过期", statusChanged: true };
}
if (orderRes.data.pay_mark === '5') {
return { success: true, message: "获取交易号成功", tradeNo: order.orderNo, payType: 'ybPay' };
}
if (orderRes.data.pay_mark === '0') {
return await settleZFMoney(order)
}
}
else if (order.status === 'ybPaid') {
return await settleZFMoney(order)
}
else if (order.status === 'expired') {
return { success: false, message: "购药订单已过期", statusChanged: true };
}
else if (order.status === 'shipped') {
return { success: true, message: "购药订单已支付", statusChanged: true };
}
else if (order.status === 'refunded') {
return { success: false, message: "购药订单已退款", statusChanged: true };
}
return { success: false, message: "购药订单状态不正确" };
} catch (e) {
return { success: false, message: e.message };
}
}
/**
* 获取处方购药订单id, 没有购药订单则创建购药订单
* @param {Object} ctx 请求参数
* @param {string} ctx.corpId 机构id
* @param {string} ctx.accountId 账号id
* @param {string} ctx.rpNo 关联处方订单
* @returns
*/
async function getRxMedicinePurchaseOrderId(ctx) {
try {
if (typeof ctx.corpId !== 'string' || ctx.corpId.trim() === '') {
return { success: false, message: "机构id不能为空" };
}
if (typeof ctx.accountId !== 'string' || ctx.accountId.trim() === '') {
return { success: false, message: "账号id不能为空" };
}
if (typeof ctx.rpNo !== 'string' || ctx.rpNo.trim() === '') {
return { success: false, message: "关联处方订单不能为空" };
}
const record = await db.collection('medicine-purchase-order').findOne({ rpNo: ctx.rpNo.trim(), accountId: ctx.accountId.trim() });
if (record && record.status === 'unpay' && dayjs(record.expireTime).isBefore(dayjs())) {
return { success: true, message: "获取处方购药订单成功", id: record._id.toString(), status: 'expired' };
} else if (record) {
return { success: true, message: "获取处方购药订单成功", id: record._id.toString(), status: record.status };
}
const rx = await db.collection('diagnostic-record').findOne({ _id: new ObjectId(ctx.rpNo.trim()), accountId: ctx.accountId.trim() });
if (!rx) {
return { success: false, message: "处方不存在" };
}
if (rx.prescriptionType !== 'onlineMedicinePurchase') {
return { success: false, message: "暂只支持配药订单" };
}
if (rx.status !== 'PASS') {
return { success: false, message: "处方状态不正确, 暂不支持购药" };
}
if (!rx.expireTime || dayjs(rx.expireTime).isBefore(dayjs())) {
return { success: false, message: "处方已过期, 暂不支持购药" };
}
if (!Array.isArray(rx.drugs) || rx.drugs.length === 0) {
return { success: false, message: "处方药品信息为空, 暂不支持购药" };
}
const patinetInfo = await getPatientRegInfo(rx.idCard, rx.name)
if (!patinetInfo.success) {
return patinetInfo;
}
const { regFee } = patinetInfo;
const orderNo = rx.medOrgOrderNo;
const data = {
accountId: ctx.accountId.trim(),
anotherIdNo: rx.idCard, // 亲情付 需要
anotherName: rx.name, // 亲情付 需要
corpId: typeof ctx.corpId === 'string' ? ctx.corpId.trim() : undefined,
createTime: Date.now(),
disabled: false,
drugs: rx.drugs.map(med => ({
_id: med._id,
chargeCode: med.hisChargeInfo.drugId,
drugName: med.drugName,
insuranceCode: med.insurance_code,
price: med.hisChargeInfo.drugPrice,
quantity: med.quantity,
spec: med.specification,
totalPrice: med.hisChargeInfo.drugSumamt,
})),
expireTime: rx.expireTime,
idCard: rx.idCard,
name: rx.name,
orderId: rx.orderId,
orderNo,
patientId: rx.patientId,
regFee,
rpNo: rx._id.toString(),
status: 'unpay',
blhno: rx.blhno
}
const drugFee = data.drugs.reduce((acc, med) => {
return acc.plus(med.totalPrice > 0 ? med.totalPrice : 0);
}, new BigNumber(0));
data.drugFee = drugFee.toNumber();
const { insertedId } = await db.collection('medicine-purchase-order').insertOne(data);
if (!insertedId) {
return { success: false, message: "新增购药订单失败" };
}
return { success: true, message: "新增购药订单成功", id: insertedId.toString(), status: 'unpay' };
} catch (e) {
return { success: false, message: e.message };
}
}
async function getTradeNo(order) {
try {
const data = {
totalAmount: order.shippingFee,
businessNo: order.orderNo,
businessType: 'onlineMedicinePurchase',
desc: '震元配药订单配送费',
openId: order.accountId,
}
const { success, message, tradeNo, paid } = await tradeApi.getAlipayTradeNo(data);
if (success && paid) {
await reloadZfPayStatus({ tradeNo, id: order._id.toString() });
return { success: true, message: "购药订单已经支付", statusChanged: true };
}
if (success && tradeNo) {
await db.collection('medicine-purchase-order').updateOne({ _id: order._id }, { $set: { tradeNo } });
return { success: true, message: "获取交易号成功", tradeNo };
}
if (success && refunded) {
return { success: true, message: "购药订单已经退款", statusChanged: true };
}
return { success: false, message: message };
} catch (e) {
return { success: false, message: e.message };
}
}
async function settleZFMoney(order) {
try {
// 根据配送费 判断是否需要支付配送费
// 1.需要 获取配送费支付流水号 返回前端
// 2.不需要 更新购药订单状态为待配送状态 并调用物流下单接口
if (order.shippingFee > 0) {
const tradeRes = await getTradeNo(order);
if (tradeRes.success && tradeRes.tradeNo) {
return { success: true, message: "获取交易号成功", tradeNo: tradeRes.tradeNo, payType: 'alipay' };
}
if (tradeRes.success && tradeRes.statusChanged) {
return { success: true, message: '购药订单支付状态已经变更, 请刷新', statusChanged: true }
}
return tradeRes;
} else if (order.shippingFee === 0) {
await db.collection('medicine-purchase-order').updateOne({ _id: order._id }, { $set: { status: 'shipped', payTime: Date.now() } });
if (!order.shippingNo) {
await createDeliveryOrder(order);
}
return { success: true, message: '购药订单支付状态已经变更, 请刷新', statusChanged: true }
}
} catch (e) {
return { success: false, message: `购药订单自费结算错误: ${e.message}` }
}
}
async function getMedicinePurchaseOrderList(ctx) {
try {
const page = parseInt(ctx.page) > 0 ? parseInt(ctx.page) : 1;
const pageSize = parseInt(ctx.pageSize) > 0 ? parseInt(ctx.pageSize) : 10;
const query = { disabled: false };
if (typeof ctx.accountId == 'string' && ctx.accountId.trim() !== '') {
query.accountId = ctx.accountId.trim();
}
if (typeof ctx.name == 'string' && ctx.name.trim() !== '') {
query.name = { $regex: ".*" + ctx.name.trim() + ".*", $options: "i" };
}
if (Array.isArray(ctx.statusList) && ctx.statusList.length) {
query.status = { $in: ctx.statusList };
}
if (ctx.startDate && dayjs(ctx.startDate).isValid()) {
query.createTime = { $gte: dayjs(ctx.startDate).startOf('day').valueOf() };
}
if (ctx.endDate && dayjs(ctx.endDate).isValid()) {
query.createTime = {
...(query.createTime || {}),
$lte: dayjs(ctx.endDate).endOf('day').valueOf()
};
}
const total = await db.collection('medicine-purchase-order').countDocuments(query);
const list = await db.collection('medicine-purchase-order').find(query).sort({ createTime: -1 }).skip((page - 1) * pageSize).limit(pageSize).toArray();
return { success: true, message: "查询购药订单列表成功", list, total, page, pageSize, pages: Math.ceil(total / pageSize) };
} catch (e) {
return { success: false, message: e.message };
}
}
async function getMedicinePurchaseShippingList(ctx) {
try {
const page = parseInt(ctx.page, 10) > 0 ? parseInt(ctx.page, 10) : 1;
const pageSize = parseInt(ctx.pageSize, 10) > 0 ? parseInt(ctx.pageSize, 10) : 10;
const ids = Array.isArray(ctx.ids) ? ctx.ids.filter(i => ObjectId.isValid(i)).map(i => new ObjectId(i)) : null;
// 基础查询条件:只查询未禁用的数据
const query = { disabled: false };
const andConditions = [];
// 机构维度隔离PC 端按机构查看;患者端可以不传 corpId
if (typeof ctx.corpId === 'string' && ctx.corpId.trim() !== '') {
query.corpId = ctx.corpId.trim();
}
// 兼容账号维度的查询(如患者端按 accountId 查询)
if (typeof ctx.accountId === 'string' && ctx.accountId.trim() !== '') {
query.accountId = ctx.accountId.trim();
}
// 患者姓名查询:兼容旧的 name 字段和新的 patientName 字段
const rawName =
(typeof ctx.patientName === 'string' && ctx.patientName.trim() !== '' && ctx.patientName.trim()) ||
(typeof ctx.name === 'string' && ctx.name.trim() !== '' && ctx.name.trim()) ||
'';
if (rawName) {
// 使用混合明文/密文查询,兼容历史数据
const condition = buildHybridSearchQuery('name', rawName, false);
if (condition) {
andConditions.push(condition);
}
}
// 收件人姓名模糊查询(字段未加密,可直接正则)
if (typeof ctx.recipientName === 'string' && ctx.recipientName.trim() !== '') {
andConditions.push({
receiveName: {
$regex: ".*" + ctx.recipientName.trim() + ".*",
$options: "i",
},
});
}
// 退回运单号(售后)模糊查询:匹配 afterSale.waybillNo
// 兼容参数名afterSaleWaybillNoPC HLWSHIPPINGLIST或 waybillNo通用
const rawAfterSaleWaybillNo =
(typeof ctx.afterSaleWaybillNo === 'string' && ctx.afterSaleWaybillNo.trim() !== '' && ctx.afterSaleWaybillNo.trim()) ||
(typeof ctx.waybillNo === 'string' && ctx.waybillNo.trim() !== '' && ctx.waybillNo.trim()) ||
'';
if (rawAfterSaleWaybillNo) {
andConditions.push({
'afterSale.waybillNo': {
$regex: ".*" + rawAfterSaleWaybillNo + ".*",
$options: 'i',
},
});
}
// 配送状态筛选:支持 statusList优先、status兼容单状态
let statusList = Array.isArray(ctx.statusList)
? ctx.statusList
.filter((i) => typeof i === 'string' && i.trim() !== '')
.map((i) => i.trim())
: [];
if (!statusList.length && typeof ctx.status === 'string' && ctx.status.trim() !== '') {
statusList = [ctx.status.trim()];
}
if (statusList.length) {
query.status = { $in: statusList };
}
// 创建时间范围
if (ctx.startDate && dayjs(ctx.startDate).isValid()) {
query.createTime = { $gte: dayjs(ctx.startDate).startOf('day').valueOf() };
}
if (ctx.endDate && dayjs(ctx.endDate).isValid()) {
query.createTime = {
...(query.createTime || {}),
$lte: dayjs(ctx.endDate).endOf('day').valueOf(),
};
}
if (ids) {
query._id = { $in: ids };
}
const finalQuery = andConditions.length ? { ...query, $and: andConditions } : query;
const collection = db.collection('medicine-purchase-order');
const total = await collection.countDocuments(finalQuery);
const list = await collection
.find(finalQuery)
.sort({ createTime: -1 })
.skip((page - 1) * pageSize)
.limit(pageSize)
.toArray();
// 聚合计算总金额
const totalResult = await collection.aggregate([
{ $match: finalQuery },
{
$group: {
_id: null,
totalDrugFee: { $sum: "$drugFee" },
totalShippingFee: { $sum: "$shippingFee" },
totalRegFee: { $sum: "$regFee" },
}
}
]).toArray();
const totals = totalResult.length > 0 ? totalResult[0] : {};
// 解密患者姓名,便于前端展示
const decryptedList = list.map((item) => {
const result = { ...item };
if (result.name && typeof result.name === 'string' && result.name.trim() !== '') {
try {
result.name = Sm4Util.decryptDataForSm3(result.name) || result.name;
} catch (err) {
// 解密失败时保留原值,避免影响整体返回
}
}
return result;
});
const pages = Math.ceil(total / pageSize);
const statistics = {
totalDrugFee: totals.totalDrugFee || 0,
totalShippingFee: totals.totalShippingFee || 0,
totalRegFee: totals.totalRegFee || 0,
};
const data = {
list: decryptedList,
total,
page,
pageSize,
pages,
statistics
};
// 兼容旧用法(直接返回 list/total同时为 PC 端提供 data 包装
return {
success: true,
message: "获取成功",
data
};
} catch (e) {
return { success: false, message: e.message };
}
}
async function getMedicinePurchaseOrderDetail(ctx) {
try {
const id = typeof ctx.id === 'string' ? ctx.id.trim() : '';
if (!id) {
return { success: false, message: "id不能为空" };
}
const order = await db.collection('medicine-purchase-order').findOne({ _id: new ObjectId(id) });
if (!order) {
return { success: false, message: "购药订单不存在" };
}
order.name = Sm4Util.decryptDataForSm3(order.name) || order.name;
return { success: true, message: "查询购药订单详情成功", data: order };
} catch (e) {
return { success: false, message: e.message };
}
}
async function reloadYbPayStatus(ctx) {
try {
if (typeof ctx.ybTradeNo !== 'string' || ctx.ybTradeNo.trim() === '') {
return { success: false, message: "医保交易号不能为空" };
}
if (typeof ctx.id !== 'string' || ctx.id.trim() === '') {
return { success: false, message: "id不能为空" };
}
const order = await db.collection('medicine-purchase-order').findOne({ _id: new ObjectId(ctx.id), ybTradeNo: ctx.ybTradeNo.trim() });
if (!order) {
return { success: false, message: "购药订单不存在" };
}
if (order.status !== 'unpay') {
return { success: false, message: "购药订单状态不正确" };
}
const hasPaid = true; // 调用his接口查询医保是否支付成功
if (!hasPaid) {
return { success: false, message: "医保支付失败" };
}
await db.collection('medicine-purchase-order').updateOne({ _id: order._id }, { $set: { status: 'ybPaid' } });
return { success: true, message: "医保支付成功" };
} catch (e) {
return { success: false, message: e.message };
}
}
async function reloadZfPayStatus(ctx) {
try {
if (typeof ctx.tradeNo !== 'string' || ctx.tradeNo.trim() === '') {
return { success: false, message: "交易号不能为空" };
}
if (typeof ctx.id !== 'string' || ctx.id.trim() === '') {
return { success: false, message: "id不能为空" };
}
const order = await db.collection('medicine-purchase-order').findOne({ _id: new ObjectId(ctx.id), tradeNo: ctx.tradeNo.trim() });
if (!order) {
return { success: false, message: "购药订单不存在" };
}
if (order.status !== 'ybPaid') {
return { success: false, message: "购药订单状态不正确" };
}
const { data } = await tradeApi.queryAlipayTradeNo({ tradeNo: ctx.tradeNo });
if (data && (data.tradeStatus === 'TRADE_SUCCESS' || data.tradeStatus === 'TRADE_FINISHED')) {
await db.collection('medicine-purchase-order').updateOne({ _id: order._id }, { $set: { status: 'shipped', payTime: dayjs(data.sendPayDate).valueOf() } });
return { success: true, message: "自费支付成功", };
}
return { success: false, message: "自费支付失败" };
} catch (e) {
return { success: false, message: e.message };
}
}
async function getCostDetails(ctx) {
try {
if (typeof ctx.areaCode !== 'string' || ctx.areaCode.trim() === '') {
return { success: false, message: "区域代码不能为空" };
}
const insuranceCodes = Array.isArray(ctx.insuranceCodes) ? ctx.insuranceCodes.filter(typeof i === 'string' && i.trim() !== '') : [];
if (insuranceCodes.length === 0) {
return { success: false, message: "药品医保编码不能为空" };
}
const { success, message, data } = await zytHis.getHisDrugInfo({ insuranceCodes, areaCode: ctx.areaCode });
if (success && data) {
return { success: true, message: "查询药品信息成功", data };
}
return { success: false, message: message };
} catch (e) {
return { success: false, message: e.message };
}
}
async function getPatientRegInfo(idNo, patientName) {
try {
const idCard = Sm4Util.decryptDataForSm3(idNo);
const name = Sm4Util.decryptDataForSm3(patientName);
const patientRes = await zytHis({ type: 'getHisCustomer', idCard });
if (!patientRes || !patientRes.success) {
return { success: false, message: patientRes && patientRes.message ? patientRes.message : '获取患者信息失败' };
}
if (!patientRes.patient) {
return { success: false, message: "获取患者档案失败" };
}
if (patientRes.patient.name !== name) {
return { success: false, message: "患者姓名不匹配" };
}
const gh_fee = patientRes.patient.gh_fee;
const regFee = Number(gh_fee) == gh_fee && gh_fee >= 0 && gh_fee !== '' ? Number(gh_fee) : undefined;
if (typeof regFee !== 'number') {
return { success: false, message: "挂号费获取失败" };
}
return { success: true, regFee }
} catch (e) {
return { success: false, message: e.message };
}
}
async function getExpressFee(corpId, db) {
try {
const res = await hlwConfigApi({ type: 'getHlwConfig', corpId }, db)
if (!res || !res.success || !res.data) {
return { success: false, message: res && res.message ? res.message : '获取快递费用配置失败' };
}
const { fengNiaoExpressDiscountFee, fengNiaoExpressFee, emsExpressFee, emsExpressDiscountFee } = res.data;
const list = [fengNiaoExpressDiscountFee, fengNiaoExpressFee, emsExpressFee, emsExpressDiscountFee];
if (list.some(i => !validMedicineAmount(i))) {
return { success: false, message: '快递配用配置有误,请联系工作人员' };
}
const fengNiaoFee = new BigNumber(fengNiaoExpressFee).minus(fengNiaoExpressDiscountFee).toNumber();
const emsFee = new BigNumber(emsExpressFee).minus(emsExpressDiscountFee).toNumber();
if (emsFee < 0) {
return { success: false, message: '邮政快递配用配置有误,请联系工作人员' };
}
if (fengNiaoFee < 0) {
return { success: false, message: '蜂鸟配送费用配置有误,请联系工作人员' };
}
return {
success: true,
data: {
fengniao: {
shippingDiscount: fengNiaoExpressDiscountFee,
shippingOriginalFee: fengNiaoExpressFee,
shippingFee: fengNiaoFee
},
ems: {
shippingDiscount: emsExpressDiscountFee,
shippingOriginalFee: emsExpressFee,
shippingFee: emsFee
}
},
message: '获取快递费用配置成功'
}
} catch (e) {
return { success: false, message: e.message };
}
}
async function getHisMedicinePurchase(patientId, orderNo) {
try {
return await zytHis({ type: 'getHisMedicinePurchase', patientId, orderNo });
} catch (e) {
return { success: false, message: e.message };
}
}
async function invokeOnlineMedicinePurchasePaySuccess({ tradeNo, businessNo: orderNo, payTime }) {
try {
const order = await db.collection('medicine-purchase-order').findOne({ orderNo, tradeNo });
if (order && order.status === 'ybPaid' && order.shippingType && !order.shippingNo) {
await db.collection('medicine-purchase-order').updateOne({ _id: order._id }, { $set: { status: 'shipped', payTime: payTime.getTime() } });
await createDeliveryOrder(order);
return { success: true, message: "配送费支付成功, 订单状态已更新" };
}
return { success: false, message: "购药订单不存在或状态不正确" };
} catch (e) {
console.log('购药订单支付回调错误: ', e.message)
return { success: false, message: e.message };
}
}
async function getShippingDetail(ctx) {
try {
const id = typeof ctx.id === 'string' ? ctx.id.trim() : '';
const accountId = typeof ctx.accountId === 'string' ? ctx.accountId.trim() : '';
if (!id || !accountId) {
return { success: false, message: "id或accountId不能为空" };
}
const order = await db.collection('medicine-purchase-order').findOne({ _id: new ObjectId(id), accountId }, { projection: output.shippingDetail });
if (order) {
if (order.shippingType === 'fengniao') {
const fengniaoApi = require('../fengniao');
const res = await fengniaoApi.main({ type: 'getOrderDetail', shippingNo: order.shippingNo });
if (res.success && res.data) {
order.shippingDetail = res.data
}
} else if (order.shippingType === 'ems') {
const emsApi = require('../ems-express');
const res = await emsApi.getShippingDetail(order.shippingNo);
if (res.success && res.data) {
order.shippingDetail = res.data
}
}
return { success: true, message: "获取配送详情成功", data: order };
}
return { success: false, message: "订单不存在" };
} catch (e) {
return { success: false, message: e.message };
}
}
async function refundMedicinePurchaseOrderYbFee(ctx) {
try {
const applyTime = Date.now();
const id = typeof ctx.id === 'string' ? ctx.id.trim() : '';
const orderNo = typeof ctx.orderNo === 'string' ? ctx.orderNo.trim() : '';
const operator = typeof ctx.operator === 'string' ? ctx.operator.trim() : '';
const operatorId = typeof ctx.operatorId === 'string' ? ctx.operatorId.trim() : '';
if (!id || !orderNo || !operator || !operatorId) {
return { success: false, message: "参数不能为空" };
}
const order = await db.collection('medicine-purchase-order').findOne({ _id: new ObjectId(id), orderNo });
if (!order) {
return { success: false, message: "配药订单不存在" };
}
if (['ybFeeRefunded', 'refunded'].includes(order.status)) {
return { success: false, message: "配药订单医保费用已退费" };
}
if (!['shipped', 'ybPaid'].includes(order.status)) {
return { success: false, message: "配药订单状态不正确" };
}
const { success, message, data } = await zytHis({ type: 'getHisMedicinePurchase', patientId: order.patientId, orderNo: order.orderNo });
if (!success) {
return { success: false, message: message };
}
if (data && data.pay_mark === '1') {
// 是否需要退运费
const shouldRefundSelfFee = order.status === 'shipped' && order.shippingFee > 0;
const targetStatus = shouldRefundSelfFee ? 'ybFeeRefunded' : 'refunded';
await db.collection('medicine-purchase-order').updateOne({ _id: order._id }, { $set: { status: targetStatus } });
return { success: true, message: "配药订单医保费用退费成功" };
}
if (!data || data.pay_mark !== '0') {
return { success: false, message: `his购药订单支付状态异常【${HisPayStatus[data?.pay_mark] || '未知状态'}` };
}
const refundRes = await zytHis({ type: 'refundMedicinePurchase', patientId: order.patientId, orderNo: order.orderNo });
if (!refundRes.success) {
return { success: false, message: refundRes.message };
}
const refundRecords = Array.isArray(order.refundRecords) ? order.refundRecords : [];
refundRecords.push({
amount: new BigNumber(order.drugFee).plus(order.regFee).toNumber(),
applyTime,
platform: 'his',
reason: '',
refundTime: Date.now(),
refundSerialNo: order.orderNo,
result: 'refunded',
tradeStatus: '1',
operator,
operatorId
});
const shouldRefundSelfFee = order.status === 'shipped' && order.shippingFee > 0;
const targetStatus = shouldRefundSelfFee ? 'ybFeeRefunded' : 'refunded';
const obj = { refundRecords, status: targetStatus }
const { modifiedCount, } = await db.collection('medicine-purchase-order').updateOne({ _id: order._id }, { $set: obj });
if (modifiedCount > 0) {
return { success: true, message: "配药订单医保费用退费成功" };
}
return { success: false, message: "配药订单医保费用退费失败" };
} catch (e) {
return { success: false, message: `购药订单医保退费错误: ${e.message}` };
}
}
async function refundMedicinePurchaseOrderSelfFee(ctx) {
try {
const applyTime = Date.now();
const id = typeof ctx.id === 'string' ? ctx.id.trim() : '';
const orderNo = typeof ctx.orderNo === 'string' ? ctx.orderNo.trim() : '';
const operator = typeof ctx.operator === 'string' ? ctx.operator.trim() : '';
const operatorId = typeof ctx.operatorId === 'string' ? ctx.operatorId.trim() : '';
const reason = typeof ctx.reason === 'string' ? ctx.reason.trim() : '';
if (!id || !orderNo || !operator || !operatorId) {
return { success: false, message: "参数不能为空" };
}
if (reason === '') {
return { success: false, message: "退费原因不能为空" };
}
const order = await db.collection('medicine-purchase-order').findOne({ _id: new ObjectId(id), orderNo });
if (!order) {
return { success: false, message: "配药订单不存在" };
}
if ('refunded' === order.status) {
return { success: false, message: "配药订单自费费用已退费" };
}
if (!['ems', 'fengniao'].includes(order.shippingType) || !order.shippingNo) {
return { success: false, message: "配药订单物流信息异常,暂不支持退费" };
}
if (!(order.shippingFee > 0 && order.payTime && order.tradeNo)) {
return { success: false, message: "配药订单没有运费或支付状态异常,暂不支持退费" };
}
if ("shipped" == order.status) {
return { success: false, message: "请先完成配药订单医保退费" };
}
if ("ybFeeRefunded" !== order.status) {
return { success: false, message: "配药订单状态不正确,暂不支持退费" };
}
const refundRecords = Array.isArray(order.refundRecords) ? order.refundRecords : [];
const copyArr = refundRecords.map(i => ({ ...i })).sort((a, b) => b.applyTime - a.applyTime);
const lastRecord = copyArr.find(i => i.platform === 'alipay');// 找到最新一条支付宝的退费记录
if (lastRecord && lastRecord.result === 'refunded') {
await db.collection('medicine-purchase-order').updateOne({ _id: order._id }, { $set: { status: 'refunded' } });
return { success: true, message: "配药订单自费费用退费成功" };
} else if (lastRecord && lastRecord.result === 'refunding') {
const seconds = Math.floor((applyTime - lastRecord.applyTime) / 1000);
if (seconds < 30) { // 支付宝退费查询要求至少等待10秒再查询
return { success: false, message: `配药订单自费费用退费中,请${30 - seconds}秒后再试` };
}
const { success, message, data } = await tradeApi.queryAlipayRefundDetail({ tradeNo: order.tradeNo });
if (!success) {
return { success, message }
}
const index = refundRecords.findIndex(i => i.platform === 'alipay' && i.applyTime === lastRecord.applyTime);
if (data && data.refundStatus === 'REFUND_SUCCESS') {
refundRecords[index].result = 'refunded';
refundRecords[index].refundTime = dayjs(data.gmtRefundPay).valueOf();
refundRecords[index].tradeStatus = data.tradeStatus;
await db.collection('medicine-purchase-order').updateOne({ _id: order._id }, { $set: { status: 'refunded', refundRecords } });
return { success: true, message: "配药订单自费费用退费成功" };
} else { // 没有返回 或者 退费状态字段不是 REFUND_SUCCESS 认为退费失败
refundRecords[index].result = 'refund_fail';
refundRecords[index].tradeStatus = data?.tradeStatus || '';
await db.collection('medicine-purchase-order').updateOne({ _id: order._id }, { $set: { refundRecords } });
}
}
if (!order.deliveryCancelled && order.shippingType === 'fengniao') {
const cancelCode = typeof ctx.cancelCode === 'string' ? ctx.cancelCode.trim() : '';
const role = typeof ctx.role === 'string' ? ctx.role.trim() : '';
if (!['1', '2'].includes(role)) {
return { success: false, message: "无效的取消类型,仅支持商户或用户取消" };
}
if (cancelCode === '') {
return { success: false, message: "取消编码不能为空" };
}
if (reason.length > 20) {
return { success: false, message: "[蜂鸟配送]退费原因不能超过20个字符" };
}
const fengniaoApi = require('../fengniao');
const { success, message } = await fengniaoApi.main({ type: 'cancelOrder', orderNo: order.orderNo, role, cancelCode, reason });
if (!success) {
return { success, message }
}
await db.collection('medicine-purchase-order').updateOne({ _id: order._id }, { $set: { deliveryCancelled: true } });
} else if (!order.deliveryCancelled && order.shippingType === 'ems') {
if (reason.length > 200) {
return { success: false, message: "[邮政快递]退费原因不能超过200个字符" };
}
const emsApi = require('../ems-express');
const { success, message } = await emsApi.cancelOrder({ logisticsOrderNo: order.orderNo, waybillNo: order.shippingNo, cancelReason: reason });
if (!success) {
return { success, message }
}
await db.collection('medicine-purchase-order').updateOne({ _id: order._id }, { $set: { deliveryCancelled: true } });
}
const applyRecord = {
amount: order.shippingFee,
applyTime,
platform: 'alipay',
reason,
refundSerialNo: order.tradeNo,
result: 'refunding',
operator,
operatorId
}
const res = await tradeApi.refundTrade({ tradeNo: order.tradeNo, reason, totalAmount: order.shippingFee });
if (!res.success) {
return { success: false, message: res.message };
}
const { tradeStatus, refundTime } = res.data;
applyRecord.result = tradeStatus;
applyRecord.refundTime = dayjs(refundTime).valueOf();
refundRecords.push(applyRecord);
const obj = { refundRecords }
if (tradeStatus === 'refunded') {
obj.status = 'refunded';
}
const { modifiedCount } = await db.collection('medicine-purchase-order').updateOne({ _id: order._id }, { $set: obj });
if (modifiedCount > 0) {
return { success: true, message: "配药订单自费费用退费成功" };
}
return { success: false, message: "配药订单自费费用退费失败" };
} catch (e) {
return { success: false, message: `购药订单自费退费错误: ${e.message}` };
}
}
// 定时任务
// 查询 待支付且超时的订单 查询his处方状态 是否为待支付 如果是待支付修改为过期状态 如果是已支付修改为医保支付成功状态 退费状态修改为已退费状态
// 查询 待配送的订单且没有物流单号的订单 去物流下单 同步物流单号
async function runMedicinePurchaseOrderSchedule() {
if (scheduleTaskIsRunning) return;
scheduleTaskIsRunning = true;
try {
// 当日未支付且超时的订单
const expiredOrders = await db.collection('medicine-purchase-order').find({ disabled: false, status: 'unpay', createTime: { $gt: dayjs().startOf('day').valueOf() }, expireTime: { $lt: Date.now() } }, { projection: { _id: 1, patientId: 1, orderNo: 1 } }).toArray();
console.log(`[超时购药订单定时任务]: 查询到超时订单条数: ${expiredOrders.length}`)
for (let expiredOrder of expiredOrders) {
const { success, data } = await getHisMedicinePurchase(expiredOrder.patientId, expiredOrder.orderNo);
if (data && data.pay_mark === '0') {
await db.collection('medicine-purchase-order').updateOne({ _id: expiredOrder._id }, { $set: { status: 'ybPaid' } });
} else if (data && data.pay_mark === '1') {
await db.collection('medicine-purchase-order').updateOne({ _id: expiredOrder._id }, { $set: { status: 'refunded' } });
} else if (!data || data.pay_mark === '5') {
await db.collection('medicine-purchase-order').updateOne({ _id: expiredOrder._id }, { $set: { status: 'expired' } });
} else if (success && data) {
await db.collection('medicine-purchase-order').updateOne({ _id: expiredOrder._id }, { $set: { status: 'abnormal' } });
}
}
// 今日支付完成 待配送的订单且没有物流单号的订单 去物流下单 同步物流单号
const shippedOrders = await db.collection('medicine-purchase-order').find({
disabled: false,
status: 'shipped',
shippingNo: { $exists: false },
shippingType: { $exists: true },
payTime: { $lte: dayjs().subtract(3, 'minute').valueOf(), $gt: dayjs().startOf('day').valueOf() }
}).toArray();
console.log(`[购药订单物流下单定时任务]: 查询到待下单订单条数: ${shippedOrders.length}`)
for (let shippedOrder of shippedOrders) {
await createDeliveryOrder(shippedOrder);
}
// 待同步his购药订单物流信息 同步his购药订单已收取运费或已退还运费信息
const updateDeliveryOrders = await db.collection('medicine-purchase-order').find({
$or: [
{ disabled: false, status: 'shipped', shippingNo: { $exists: true }, syncHisDelivery: { $exists: false } }, // 已经收取运费 未同步his
{ disabled: false, status: 'refunded', shippingNo: { $exists: true }, payTime: { $exists: true }, syncHisDelivery: 'charged' } //已退还运费 但未同步his
]
}).toArray();
console.log(`[购药订单物流同步定时任务]: 查询到待同步订单条数: ${updateDeliveryOrders.length}`)
for (let updateDeliveryOrder of updateDeliveryOrders) {
const regions = Array.isArray(updateDeliveryOrder.receiveRegion) ? updateDeliveryOrder.receiveRegion.map(i => i.trim()) : [];
const address = updateDeliveryOrder.receiveAddress.trim();
const fullAddress = regions.join('') + address;
const shippingType = updateDeliveryOrder.shippingType === 'fengniao' ? 'fengn' : 'ems';
const payTime = updateDeliveryOrder.payTime ? dayjs(updateDeliveryOrder.payTime).format('YYYY-MM-DD HH:mm:ss') : undefined;
const backFlag = updateDeliveryOrder.status === 'shipped' ? 0 : 1; // 0 收取运费 | 1 退还运费
const pickupCode = updateDeliveryOrder.pickupCode;
const { success } = await zytHis({ type: 'updateMedicinePurchaseDelivery', ...updateDeliveryOrder, pickupCode, shippingType, fullAddress, payTime, backFlag })
if (success) {
const target = backFlag === 0 ? 'charged' : 'refunded';
await db.collection('medicine-purchase-order').updateOne({ _id: updateDeliveryOrder._id }, { $set: { syncHisDelivery: target } });
}
}
} catch (e) {
console.log('执行定时任务出现错误: ', e.message)
}
scheduleTaskIsRunning = false;
}
async function updateAfterSaleInfo(ctx) {
try {
const id = typeof ctx.id === 'string' ? ctx.id.trim() : '';
if (id === '') {
return { success: false, message: "配药订单id不能为空" };
}
const afterSale = {};
if ('notes' in ctx && typeof ctx.notes === 'string') {
afterSale.notes = ctx.notes.trim();
}
if ('waybillNo' in ctx && typeof ctx.waybillNo === 'string') {
afterSale.waybillNo = ctx.waybillNo.trim();
}
if (afterSale.notes && afterSale.notes.length > 300) {
return { success: false, message: "售后备注不能超过300个字符" };
}
if (afterSale.waybillNo && afterSale.waybillNo.length > 100) {
return { success: false, message: "物流单号不能超过100个字符" };
}
if (Object.keys(afterSale).length === 0) {
return { success: true, message: "售后信息没有变化" };
}
const { matchedCount } = await db.collection('medicine-purchase-order').updateOne({ _id: new ObjectId(id) }, { $set: { afterSale } });
if (matchedCount > 0) {
return { success: true, message: "更新售后信息成功" };
}
return { success: false, message: "更新售后信息失败" };
} catch (e) {
return { success: false, message: `更新售后信息错误: ${e.message}` };
}
}
async function getLastestPurchaseOrder(ctx) {
try {
const appId = process.env.CONFIG_ALIPAY_MINI_APPID;
const ciphertext = typeof ctx.ciphertext === 'string' ? ctx.ciphertext.trim() : '';
const data = Sm4Util.decryptDataForSm3(ciphertext);
const [, accountId] = data.split(appId);
if (!accountId) {
return { success: false, order: null };
}
const order = await db.collection('medicine-purchase-order').findOne({
accountId,
disabled: false,
status: { $in: ['ybPaid', 'shipped', 'refunded', 'ybFeeRefunded'] }
}, { projection: output.lastestOrder, sort: { createTime: -1 } });
if (order) {
const rx = await db.collection('diagnostic-record').findOne({ _id: new ObjectId(order.rpNo) }, { projection: { doctorName: 1, sex: 1, age: 1 } });
if (rx) {
order.doctorName = rx.doctorName;
order.sex = rx.sex;
order.age = rx.age;
}
order.name = Sm4Util.decryptDataForSm3(order.name);
}
return { success: Boolean(order), order };
} catch (e) {
return { success: false, message: `获取最新购药订单错误: ${e.message}` };
}
}
async function getPatientPurchaseOrderList(ctx) {
try {
const page = Number.isInteger(ctx.page) && ctx.page > 0 ? ctx.page : 1;
const pageSize = Number.isInteger(ctx.pageSize) && ctx.pageSize > 0 ? ctx.pageSize : 1;
const patientId = typeof ctx.patientId === 'string' ? ctx.patientId.trim() : '';
if (patientId === '') {
return { success: false, message: '参数错误' }
}
// , status: 'shipped'
const list = await db.collection('medicine-purchase-order').find({ patientId, disabled: false, status: 'shipped' }, { project: { rpNo: 1 } }).sort({ createTime: -1 }).skip((page - 1) * pageSize).limit(pageSize).toArray();
const total = await db.collection('medicine-purchase-order').countDocuments({ patientId, disabled: false, status: 'shipped' })
const data = await db.collection('diagnostic-record').find({ _id: { $in: list.map(i => new ObjectId(i.rpNo)) } }, {
projection: {
"createTime": 1,
"diagnosisList.name": 1,
"drugs.drugName": 1,
"drugs.specification": 1,
"drugs.quantity": 1,
"drugs.unit": 1,
"drugs.usageName": 1,
"drugs.frequencyName": 1,
"drugs.dosage": 1,
"drugs.dosage_unit": 1
}
}).sort({ createTime: -1 }).toArray()
return { success: true, data, total }
} catch (e) {
return { success: false, message: e.message }
}
}
async function getHighFreqAddressOrders(ctx) {
try {
const startDate = ctx.startDate && dayjs(ctx.startDate).isValid() ? dayjs(ctx.startDate).valueOf() : null;
const endDate = ctx.endDate && dayjs(ctx.endDate).isValid() ? dayjs(ctx.endDate).valueOf() : null;
const times = ctx.times > 1 && Number.isInteger(ctx.times) ? ctx.times : '';
const operator = ['eq', 'gte'].includes(ctx.operator) ? ctx.operator : 'eq';
if (!times || !startDate || !endDate || !(endDate > startDate)) {
return { success: false, message: '参数错误' }
}
const pipeline = [
{
$match: {
disabled: { $ne: true },
receiveAddress: { $exists: true, $ne: null, $ne: '' },
createTime: { $gte: startDate, $lte: endDate }
}
},
{
$sort: { createTime: -1 }
},
{
$group: {
_id: '$receiveAddress',
orderIds: { $push: '$_id' },
count: { $sum: 1 }
}
},
{
$match: operator === 'gte' ? { count: { $gte: times } } : { count: { $eq: times } }
},
{
$project: {
_id: 0,
receiveAddress: '$_id',
orderIds: 1,
count: 1
}
}
];
const data = await db.collection('medicine-purchase-order').aggregate(pipeline).toArray();
return { success: true, data }
} catch (e) {
return { success: false, message: e.message }
}
}
async function purchaseTest() {
try {
const pickupCode = await generatePickupCode(db);
return { success: true, data: pickupCode }
} catch (e) {
return { success: false, message: e.message }
}
}