const { ObjectId } = require('mongodb'); const BigNumber = require('bignumber.js'); const dayjs = require('dayjs'); const common = require('../../common'); const zytHis = require('../zyt-his'); const Sm4Util = require("../../utils/sm4-util"); const trade = require('../trade'); const format = require('./format'); const ems = require('../ems-express'); const devAmount = Number(process.env.CONFIG_DEV_UNION_PAY_AMOUNT); let scheduleTaskIsRunning = false; exports.main = async (ctx, db) => { switch (ctx.type) { case 'getRxMedicalWineOrder': return getRxMedicalWineOrder(ctx, db); case 'getWineOrderPayQrcode': return getWineOrderPayQrcode(ctx, db); case 'initRxMedicalWineOrder': return initRxMedicalWineOrder(ctx, db); case 'refundRxMedicalWineOrder': return refundRxMedicalWineOrder(ctx, db); case 'invokeMedicalWinePurchasePaySuccess': return invokeMedicalWinePurchasePaySuccess(ctx, db); case 'checkReceiveAddress': return checkReceiveAddress(ctx, db); case 'runChineseMedicineOrderSchedule': return runChineseMedicineOrderSchedule(ctx, db); case 'getWineShippingList': return getWineShippingList(ctx, db); case 'getWineShippingDetail': return getWineShippingDetail(ctx); case 'updateWineAfterSaleInfo': return updateWineAfterSaleInfo(ctx, db); case 'getWineOrderStatus': return getWineOrderStatus(ctx, db); case 'refundWineOrderFee': return refundWineOrderFee(ctx, db); case 'refundWineOrderShippingFee': return refundWineOrderShippingFee(ctx, db); case 'getWineOrderPatient': return getWineOrderPatient(ctx, db); case 'reCreateWineEmsOrder': return reCreateWineEmsOrder(ctx, db); case 'wineTest': return await wineTest(ctx, db); } } function validChargeAmount(amount) { if (typeof amount !== 'number' || !(amount >= 0)) { return false } // 金额最多精确到分 const cent = new BigNumber(amount).multipliedBy(100).toNumber(); return Number.isInteger(cent) && cent >= 0; } async function checkReceiveAddress(ctx) { try { const region = Array.isArray(ctx.region) ? ctx.region.filter(i => typeof i === 'string' && i.trim()) : []; const address = typeof ctx.address === 'string' ? ctx.address.trim() : ''; if (region.length === 0 || address === '') { return { success: false, message: '参数错误' } } const res = await ems.parseAddress(region.join('') + address); if (!res || !res.success) { return { success: false, message: `收货地址校验失败:${res?.message}` } } const [province, city, area] = region; const result = await ems.checkAddress({ province, city, area, address }); return { success: true, data: result, message: '地址校验成功' }; } catch (e) { return { success: false, message: `地址校验失败:${e?.message}` } } } async function getWineShippingList(ctx, db) { try { const orderNo = typeof ctx.orderNo === 'string' ? ctx.orderNo.trim() : ''; const name = typeof ctx.name === 'string' ? ctx.name.trim() : ''; const receiveName = typeof ctx.receiveName === 'string' ? ctx.receiveName.trim() : ''; const backShippingNo = typeof ctx.backShippingNo === 'string' ? ctx.backShippingNo.trim() : ''; const startDate = ctx.startDate && dayjs(ctx.startDate).isValid() ? dayjs(ctx.startDate).startOf('day') : null; const endDate = ctx.endDate && dayjs(ctx.endDate).isValid() ? dayjs(ctx.endDate).endOf('day') : null; const page = Number.isInteger(ctx.page) && ctx.page > 0 ? ctx.page : 0; const pageSize = Number.isInteger(ctx.pageSize) && ctx.pageSize > 0 ? ctx.pageSize : 10; const skip = (page - 1) * pageSize; const query = { payTime: { $exists: true } }; if (ctx.storeIds && ctx.storeIds.length > 0) { query.storeId = { $in: ctx.storeIds }; } if (orderNo) { query.orderNo = orderNo; } if (name) { query.name = RegExp(name, 'i'); } if (receiveName) { query['receiveInfo.name'] = RegExp(receiveName, 'i'); } if (backShippingNo) { query['afterSale.waybillNo'] = backShippingNo; } if (Array.isArray(ctx.statusList) && ctx.statusList.length > 0) { query.status = { $in: ctx.statusList }; } if (startDate) { query.createTime = { $gte: startDate.valueOf() }; } if (endDate) { query.createTime = query.createTime || {}; query.createTime['$lte'] = endDate.valueOf(); } const data = await db.collection('chinese-medicine-order').find(query).sort({ createTime: -1 }).skip(skip).limit(pageSize).toArray(); const total = await db.collection('chinese-medicine-order').countDocuments(query); const pages = Math.ceil(total / pageSize); return { success: true, data: { list: data, total, pages }, message: '查询订单成功' }; } catch (e) { return { success: false, message: `获取订单失败:${e?.message}` } } } async function getRxMedicalWineOrder(ctx, db) { try { const corpId = typeof ctx.corpId === 'string' ? ctx.corpId.trim() : ''; const id = ObjectId.isValid(ctx.id) ? new ObjectId(ctx.id) : null; const withChargeInfo = typeof ctx.withChargeInfo === 'boolean' ? ctx.withChargeInfo : false; if (!id) { return { success: false, message: '参数错误' } } const order = await db.collection('chinese-medicine-order').findOne({ _id: id }); if (!order) { return { success: false, message: '中药饮配方配方订单不存在' } } const result = { success: true, data: order, message: '查询中药饮配方配方订单成功' }; if (order.status === 'unpay' && withChargeInfo) { const store = await db.collection('store-list').findOne({ store_id: order.storeId }); if (!store) { return { success: false, message: '门店不存在' } } result.storeSaleWine = Boolean(store.saleWine); const res = await getExpressFee(corpId, db); if (!res.success) { return res } result.deliveryCharge = res.data; } return result; } catch (e) { return { success: false, message: `查询浸酒方失败:${e?.message}` } } } async function getWineOrderPayQrcode(ctx, db) { try { const id = ObjectId.isValid(ctx.id) ? new ObjectId(ctx.id) : null; const name = typeof ctx.name === 'string' ? ctx.name.trim() : ''; const mobile = typeof ctx.mobile === 'string' ? ctx.mobile.trim() : ''; const region = Array.isArray(ctx.region) ? ctx.region.filter(i => typeof i === 'string' && i.trim()) : []; const address = typeof ctx.address === 'string' ? ctx.address.trim() : ''; const paperInvoice = typeof ctx.paperInvoice === 'boolean' ? ctx.paperInvoice : false; if (!id || name === '' || mobile === '' || region.length === 0 || address === '') { return { success: false, message: '参数错误' } } if (!/^1[3456789]\d{9}$/.test(mobile)) { return { success: false, message: '手机号格式错误' } } const order = await db.collection('chinese-medicine-order').findOne({ _id: id }); if (!order) { return { success: false, message: '浸酒订单不存在' } } if (order.status !== 'unpay' || order.pickUpType != 'delivery') { return { success: false, message: '当前订单状态不支持生成支付二维码' } } await db.collection('chinese-medicine-order').updateOne({ _id: order._id }, { $set: { receiveInfo: { name, mobile, region, address, }, paperInvoice } }) const totalAmount = devAmount > 0 ? new BigNumber(devAmount).plus(order.shippingFee).toNumber() : order.totalFee; const data = { totalAmount, businessNo: order.orderNo, businessType: 'chineseMedicineOrder', desc: `【震元堂】中药饮片订单`, expireTime: order.expireTime, } const res = await trade.createUnionPayTrade(data); if (!res || !res.success) { return res } return { success: true, data: res.qrcode, message: '生成中药饮片订单支付二维码成功' } } catch (e) { return { success: false, message: `获取中药饮片订单支付二维码失败:${e?.message}` } } } async function initRxMedicalWineOrder(ctx, db) { try { const rpNo = typeof ctx.rpNo === 'string' ? ctx.rpNo.trim() : ''; const corpId = typeof ctx.corpId === 'string' ? ctx.corpId.trim() : ''; if (!ObjectId.isValid(rpNo)) { return { success: false, message: '参数错误' } } const order = await db.collection('chinese-medicine-order').findOne({ rpNo, disabled: false }); if (order) { return { success: true, data: { status: order.status, id: order._id }, message: '该处方已经生成浸酒订单' } } const rx = await db.collection('diagnostic-record').findOne({ _id: new ObjectId(rpNo) }); if (!rx) { return { success: false, message: '处方不存在' } } if (rx.status !== 'PASS' || rx.prescriptionType !== 'medicalWinePurchase') { return { success: false, message: '当前处方不支持生成浸酒订单' } } if (Date.now() > rx.expireTime) { return { success: false, message: '处方已过期' } } const data = { createTime: Date.now(), rpNo, storeId: rx.drugStoreNo, name: Sm4Util.decryptDataForSm3(rx.name), mobile: Sm4Util.decryptDataForSm3(rx.mobile), patientId: rx.patientId, orderNo: rx.medOrgOrderNo, orderId: rx.orderId, status: rx.pickUpType === 'selfTake' ? 'completed' : 'unpay', // 自提订单默认已完成 线下支付 pickUpType: rx.pickUpType, expireTime: rx.expireTime, disabled: false } const store = await db.collection('store-list').findOne({ store_id: data.storeId }); if (!store) { return { success: false, message: '门店不存在' } } data.storeName = store.name; const wineInfo = await getWineInfo(rx.wines, db); if (!wineInfo.success) { return wineInfo } data.wines = wineInfo.data; const res = await zytHis({ type: 'getHisMedicinePurchase', patientId: rx.patientId, orderNo: data.orderNo }) if (!res.success) { return res } const total_amount = Number(res.data.total_amount); if (!validChargeAmount(total_amount)) { return { success: false, message: '金额格式错误' } } if (res.data.patientid !== rx.patientId) { return { success: false, message: '患者ID不匹配' } } data.goodsFee = total_amount; if (rx.pickUpType === 'selfTake') { data.shippingFee = 0; data.shippingDiscount = 0; data.shippingOriginalFee = 0; } else { const res = await getExpressFee(corpId, db); if (!res.success) { return res } data.shippingFee = res.data.shippingFee; data.shippingDiscount = res.data.shippingDiscount; data.shippingOriginalFee = res.data.shippingOriginalFee; } const totalFee = new BigNumber(data.goodsFee).plus(data.shippingFee).toNumber(); data.totalFee = totalFee; if (!validChargeAmount(totalFee)) { return { success: false, message: '总金额计算错误' } } const { insertedId } = await db.collection('chinese-medicine-order').insertOne(data); if (!insertedId) { return { success: false, message: '生成浸酒订单失败' } } return { success: true, data: { status: data.status, id: insertedId }, message: '生成浸酒订单成功' } } catch (e) { return { success: false, message: e.message } } } async function refundRxMedicalWineOrder(ctx, db) { try { const id = ObjectId.isValid(ctx.id) ? new ObjectId(ctx.id) : null; if (!id) { return { success: false, message: '参数错误' } } const order = await db.collection('chinese-medicine-order').findOne({ _id: id }); if (!order) { return { success: false, message: '浸酒订单不存在' } } if (order.status !== 'paid') { return { success: false, message: '当前订单状态不支持退款' } } const data = { businessNo: order.orderNo, businessType: 'chineseMedicineOrder', tradeNo: order.tradeNo, } const res = await trade.refundUnionPayTrade(data); if (!res.success) { return res } return { success: true, data: res, message: '浸酒订单退款成功' } } catch (e) { return { success: false, message: `获取浸酒订单退款失败:${e?.message}` } } } async function invokeMedicalWinePurchasePaySuccess(ctx, db) { try { const { tradeNo, businessNo, payTime } = ctx; const order = await db.collection('chinese-medicine-order').findOne({ orderNo: businessNo }); if (!order) { return { success: false, message: '浸酒订单不存在' } } if (order.status !== 'unpay') { return { success: false, message: '当前订单状态不支持支付成功回调' } } const timestamp = payTime && dayjs(payTime).isValid() ? dayjs(payTime).valueOf() : Date.now(); await db.collection('chinese-medicine-order').updateOne({ _id: order._id }, { $set: { status: 'paid', tradeNo, payTime: timestamp, updateTime: Date.now() } }); order.status = 'paid'; order.payTime = timestamp; order.tradeNo = tradeNo; await syncHisWineOrderInfo(order, db) await createDeliveryOrder(order, db); return { success: true, message: '浸酒订单支付成功回调处理成功' } } catch (e) { return { success: false, message: `浸酒订单支付成功回调处理失败:${e?.message}` } } } async function getWineInfo(data, db) { const ids = data.map(i => new ObjectId(i._id)); const wines = await db.collection('chinese-medicine').find({ type: 'wine', disabled: false, _id: { $in: ids } }).toArray(); const result = []; for (const item of data) { const wine = wines.find(i => i._id.toString() === item._id); if (!wine) { return { success: false, message: `浸酒${item.name}不存在` } } result.push({ name: wine.name, details: wine.details, ingredients: wine.ingredients, efficacy: wine.efficacy, quantity: item.quantity, hisId: wine.hisId, unit: wine.unit }) } return { success: true, data: result } } async function getExpressFee(corpId, db) { try { const config = await db.collection('hlw-config').findOne({ corpId }); if (!config) { return { success: false, message: '快递配用配置有误,请联系工作人员' }; } const { wineExpressFee, wineExpressDiscountFee } = config; const list = [wineExpressFee, wineExpressDiscountFee]; if (list.some(i => !validChargeAmount(i))) { return { success: false, message: '快递配用配置有误,请联系工作人员' }; } const shippingFee = new BigNumber(wineExpressFee).minus(wineExpressDiscountFee).toNumber(); if (!(validChargeAmount(shippingFee))) { return { success: false, message: '邮政快递配用配置有误,请联系工作人员' }; } return { success: true, data: { shippingDiscount: wineExpressDiscountFee, shippingOriginalFee: wineExpressFee, shippingFee }, message: '获取快递费用配置成功' } } catch (e) { return { success: false, message: e.message }; } } async function syncHisWineOrderInfo(order, db) { try { if (!['paid', 'shipped'].includes(order.status)) { return { success: false, message: '当前订单状态不支持同步' } } const trade = await db.collection('trades').findOne({ tradeNo: order.tradeNo }, { projection: { tradeStatus: 1, tradeNo: 1, outTradeNo: 1, totalAmount: 1 } }); if (!trade || trade.tradeStatus !== 'paid') { return { success: false, message: '订单不存在或状态错误' } } const data = { patientId: order.patientId, orderNo: order.orderNo, tradeNo: order.tradeNo, outTradeNo: trade.outTradeNo, totalAmount: order.totalFee } const res = await zytHis({ type: 'syncHisChargeStatus', ...data }); if (res.success) { await db.collection('chinese-medicine-order').updateOne({ _id: order._id }, { $set: { syncHisChargeStatus: 'charged' } }); return { success: true, message: '同步浸酒订单信息成功' } } return res } catch (e) { return { success: false, message: e.message } } } async function syncHisRefundStatus(order, db) { try { if (!['goodsFeeRefunded', 'refunded'].includes(order.status)) { return { success: false, message: '当前订单状态不支持同步' } } const refundRecords = Array.isArray(order.refundRecords) ? order.refundRecords.reverse() : []; const refund = refundRecords.find(i => i.type === 'goodsFee' && i.result === 'refunded'); if (!refund) { return { success: false, message: '订单不存在退款记录' } } const data = { patientId: order.patientId, orderNo: order.orderNo, refundSerialNo: refund.refundSerialNo, } const res = await zytHis({ type: 'syncHisRefundStatus', ...data }); if (res.success) { await db.collection('chinese-medicine-order').updateOne({ _id: order._id }, { $set: { syncHisChargeStatus: 'refunded' } }); return { success: true, message: '同步浸酒订单信息成功' } } return res } catch (e) { return { success: false, message: e.message } } } async function getWineShippingDetail(ctx) { try { const shippingNo = typeof ctx.shippingNo === 'string' ? ctx.shippingNo.trim() : ''; if (!shippingNo) { return { success: false, message: '配送单号不能为空' } } const emsApi = require('../ems-express'); const res = await emsApi.getShippingDetail(shippingNo); return { success: true, data: res.data, message: '获取配送详情成功' } } catch (e) { return { success: false, message: e.message }; } } async function createDeliveryOrder(order, db) { try { const emsApi = require('../ems-express'); const emsOrderData = format.formatEMSOrderData(order); const { success, data } = await emsApi.createOrder(emsOrderData); if (success && data) { await db.collection('chinese-medicine-order').updateOne({ _id: order._id }, { $set: { status: 'shipped', 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 updateWineAfterSaleInfo(ctx, db) { 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('chinese-medicine-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 getWineOrderStatus(ctx, db) { try { const rpNo = ObjectId.isValid(ctx.rpNo) ? ctx.rpNo : ''; if (!rpNo) { return { success: false, message: '参数错误' } } const rx = await db.collection('diagnostic-record').findOne({ _id: new ObjectId(rpNo) }); if (!rx) { return { success: false, message: '记录不存在' } } const order = await db.collection('chinese-medicine-order').findOne({ rpNo }); const rxExpired = !order && Date.now() < rx.expireTime; const payExpired = order.status === 'unpay' && Date.now() > order.expireTime; const orderExpired = order.status === 'expired'; if (rxExpired || payExpired || orderExpired) { return { success: true, status: 'expired' } } if (Date.now() < rx.expireTime && (!order || order.status === 'unpay')) { return { success: true, status: 'unpay', expireTime: rx.expireTime } } return { success: true, status: order?.status, message: '查询成功' } } catch (e) { return { success: false, message: e.message } } } async function refundWineOrderFee(ctx, db) { 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.length > 200) { return { success: false, message: "[邮政快递]退费原因不能超过200个字符" }; } const order = await db.collection('chinese-medicine-order').findOne({ _id: new ObjectId(id), orderNo }); if (!order) { return { success: false, message: '浸酒订单不存在' } } if (['goodsFeeRefunded', 'refunded'].includes(order.status)) { return { success: false, message: "配药订单医保费用已退费" }; } if (!['paid', 'shipped'].includes(order.status)) { return { success: false, message: "配药订单状态不正确" }; } const refundOrderId = common.generateUniqueStr('3JHR'); const res = await trade.refundUnionPayTrade({ tradeNo: order.tradeNo, businessNo: order.orderNo, businessType: 'chineseMedicineOrder', refundAmount: devAmount || order.goodsFee, refundOrderId, }); if (!res.success) { return { success: false, message: res.message || '退费失败' }; } const refundRecord = { amount: order.goodsFee, applyTime, platform: 'unionPay', reason, type: 'goodsFee', refundSerialNo: refundOrderId, refundTime: applyTime, result: res.success ? 'refunded' : 'refund_fail', operator, operatorId } const refundRecords = order.refundRecords || []; refundRecords.push(refundRecord); await db.collection('chinese-medicine-order').updateOne({ _id: order._id }, { $set: { refundRecords } }); if (order.shippingFee === 0) { await db.collection('chinese-medicine-order').updateOne({ _id: order._id }, { $set: { status: 'refunded' } }); } else if (order.shippingFee > 0) { await db.collection('chinese-medicine-order').updateOne({ _id: order._id }, { $set: { status: 'goodsFeeRefunded' } }); } if (order.shippingFee === 0 && order.shippingNo) { const emsApi = require('../ems-express'); const { success } = await emsApi.cancelOrder({ logisticsOrderNo: order.orderNo, waybillNo: order.shippingNo, cancelReason: reason }); if (success) { await db.collection('chinese-medicine-order').updateOne({ _id: order._id }, { $set: { deliveryCancelled: true } }); } } return { success: true, message: "费用退费成功" }; } catch (e) { return { success: false, message: e.message } } } async function refundWineOrderShippingFee(ctx, db) { 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.length > 200) { return { success: false, message: "[邮政快递]退费原因不能超过200个字符" }; } const order = await db.collection('chinese-medicine-order').findOne({ _id: new ObjectId(id), orderNo }); if (!order) { return { success: false, message: '浸酒订单不存在' } } if ('goodsFeeRefunded' !== order.status) { return { success: false, message: "配药订单状态不正确" }; } const refundOrderId = common.generateUniqueStr('3JHR'); const res = await trade.refundUnionPayTrade({ tradeNo: order.tradeNo, businessNo: order.orderNo, businessType: 'chineseMedicineOrder', refundAmount: order.shippingFee, refundOrderId, }); const refundRecord = { amount: order.shippingFee, applyTime, platform: 'unionPay', reason, type: 'shippingFee', refundSerialNo: refundOrderId, refundTime: applyTime, result: res.success ? 'refunded' : 'refund_fail', operator, operatorId } const refundRecords = order.refundRecords || []; refundRecords.push(refundRecord); await db.collection('chinese-medicine-order').updateOne({ _id: order._id }, { $set: { refundRecords } }); if (!res.success) { return { success: false, message: res.message || '退费失败' }; } await db.collection('chinese-medicine-order').updateOne({ _id: order._id }, { $set: { status: 'refunded' } }); const emsApi = require('../ems-express'); const { success } = await emsApi.cancelOrder({ logisticsOrderNo: order.orderNo, waybillNo: order.shippingNo, cancelReason: reason }); if (success) { await db.collection('chinese-medicine-order').updateOne({ _id: order._id }, { $set: { deliveryCancelled: true } }); } return { success: true, message: "费用退费成功" }; } catch (e) { return { success: false, message: e.message } } } // 定时任务 // 查询 超时未支付的浸酒订单 async function runChineseMedicineOrderSchedule(ctx, db) { if (scheduleTaskIsRunning) return; const logText = [`${'='.repeat(8)}浸酒订单定时任务开始${'='.repeat(8)}`]; scheduleTaskIsRunning = true; try { // 当日未支付且超时的订单 const list = await db.collection('chinese-medicine-order').find( { status: 'unpay', expireTime: { $lt: Date.now() }, createTime: { $gt: dayjs().startOf('day').valueOf() } }).toArray(); logText.push(`[${dayjs().format('YYYY-MM-DD HH:mm:ss')}]支付超时数: ${list.length}`); for (let item of list) { const { status } = await trade.checkUnionPayUnpay({ businessNo: item.orderNo, businessType: 'chineseMedicineOrder' }); if (status === 'unpay') { await db.collection('chinese-medicine-order').updateOne({ _id: item._id }, { $set: { status: 'expired' } }); } else if (status === 'refunded') { await db.collection('chinese-medicine-order').updateOne({ _id: item._id }, { $set: { status: 'refunded' } }); } } // 已经支付但是没有同步his状态的同步his const paidList = await db.collection('chinese-medicine-order').find({ status: { $in: ['paid', 'shipped'] }, syncHisChargeStatus: { $exists: false }, createTime: { $gt: dayjs().startOf('day').valueOf() }, payTime: { $gt: dayjs().startOf('day').valueOf(), $lt: dayjs().subtract(5, 'minute').valueOf(), } }).toArray(); logText.push(`[${dayjs().format('YYYY-MM-DD HH:mm:ss')}]同步支付数: ${paidList.length}`); for (let item of paidList) { await syncHisWineOrderInfo(item, db); } const refundList = await db.collection('chinese-medicine-order').find({ status: { $in: ['goodsFeeRefunded', 'refunded'] }, syncHisChargeStatus: 'charged', refundRecords: { $elemMatch: { type: 'goodsFee', result: 'refunded', refundTime: { $gt: dayjs().startOf('day').valueOf() } } } }).toArray(); logText.push(`[${dayjs().format('YYYY-MM-DD HH:mm:ss')}]同步退款数: ${refundList.length}`); for (let item of refundList) { await syncHisRefundStatus(item, db); } // 已经支付但是没有发货的 发货 const shippedList = await db.collection('chinese-medicine-order').find( { status: 'paid', pickUpType: 'delivery', disabled: false, createTime: { $gt: dayjs().startOf('day').valueOf() }, payTime: { $lt: dayjs().subtract(3, 'minute').valueOf() } }).toArray(); logText.push(`[${dayjs().format('YYYY-MM-DD HH:mm:ss')}]待发货数: ${shippedList.length}`); for (let item of shippedList) { await createDeliveryOrder(item, db); } // 待同步his购药订单物流信息 同步his购药订单已收取运费或已退还运费信息 const updateDeliveryOrders = await db.collection('chinese-medicine-order').find({ $or: [ { disabled: false, status: 'shipped', shippingNo: { $exists: true }, syncHisDelivery: { $exists: false }, payTime: { $gt: dayjs().startOf('day').valueOf() } }, // 已经收取运费 未同步his { disabled: false, status: 'refunded', shippingNo: { $exists: true }, syncHisDelivery: { $ne: 'refunded' }, refundRecords: { $elemMatch: { refundTime: { $gt: dayjs().startOf('day').valueOf() } } } }, // 已退还运费 未同步his ] }).toArray(); logText.push(`[${dayjs().format('YYYY-MM-DD HH:mm:ss')}]待同步物流数: ${updateDeliveryOrders.length}`); for (let updateDeliveryOrder of updateDeliveryOrders) { const region = updateDeliveryOrder.receiveInfo.region || []; const address = updateDeliveryOrder.receiveInfo.address || ''; const invoice = updateDeliveryOrder.paperInvoice ? 1 : 0; const fullAddress = region.join('') + address; const shippingType = '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 { success } = await zytHis({ type: 'updateMedicinePurchaseDelivery', ...updateDeliveryOrder, shippingType, fullAddress, payTime, invoice, backFlag }) if (success) { const target = backFlag === 0 ? 'charged' : 'refunded'; await db.collection('chinese-medicine-order').updateOne({ _id: updateDeliveryOrder._id }, { $set: { syncHisDelivery: target } }); } } } catch (e) { console.log('执行定时任务出现错误: ', e.message) } scheduleTaskIsRunning = false; logText.push(`${'='.repeat(8)}浸酒订单定时任务结束${'='.repeat(8)}`); logText.forEach(item => console.log(item)) } async function getWineOrderPatient(ctx, db) { const patientId = typeof ctx.patientId === 'string' ? ctx.patientId.trim() : ''; const orderNo = typeof ctx.orderNo === 'string' ? ctx.orderNo.trim() : ''; if (!patientId || !orderNo) { return { success: false, message: '参数错误' } } try { const order = await db.collection('chinese-medicine-order').findOne({ disabled: false, patientId, orderNo }); if (!order) { return { success: false, message: '订单不存在' } } const rx = await db.collection('diagnostic-record').findOne({ _id: new ObjectId(order.rpNo) }); if (!rx) { return { success: false, message: '处方不存在' } } const anotherIdNo = typeof rx.idCard === 'string' ? rx.idCard.trim() : ''; if (!anotherIdNo) { return { success: false, message: '处方中没有患者身份证号' } } return await zytHis({ type: 'getHisCustomer', anotherIdNo }) } catch (e) { return { success: false, message: e.message } } } async function reCreateWineEmsOrder(ctx, db) { const orderNo = typeof ctx.orderNo === 'string' ? ctx.orderNo.trim() : ''; if (!orderNo) { return { success: false, message: '参数错误' } } try { const order = await db.collection('chinese-medicine-order').findOne({ disabled: false, orderNo, status: 'paid', pickUpType: 'delivery' }); if (!order) { return { success: false, message: '订单不存在' } } if (order.shippingNo) { return { success: false, message: '当前订单已创建邮政订单' } } if (!order.tradeNo) { return { success: false, message: '支付订单号不存在' } } const res1 = await trade.checkUnionPayUnpay({ businessNo: order.orderNo, businessType: 'chineseMedicineOrder' }); const { status } = res1 || {}; if (!res1 || status !== 'paid') { return { success: false, message: '银联订单支付状态异常' } } const res = await createDeliveryOrder(order, db); return res } catch (e) { return { success: false, message: e.message } } } async function wineTest(ctx, db) { }