更新
This commit is contained in:
@@ -293,7 +293,7 @@
|
|||||||
:fetch-fun="prescriptionOrderExport"
|
:fetch-fun="prescriptionOrderExport"
|
||||||
:params="prescriptionOrderExportParams"
|
:params="prescriptionOrderExportParams"
|
||||||
:page-size="pager.size"
|
:page-size="pager.size"
|
||||||
export-hint="导出范围与上方筛选一致(履约状态、创建时间及其他条件均会生效)。含「自媒体渠道(挂号渠道来源)」:优先取该单关联处方登记的挂号;无则诊单下同患者挂号取 id 最大的一条(与前台挂号选择的记录一致);业绩侧栏带渠道筛选导出时与同页列表高亮挂号同源。「服务套餐」按字典 server_order 解析展示;「签收日期」与详情/业绩看板提成口径一致:以快递主表 sign_time 为主,无效时回退至签收类轨迹时间或已签收状态下的最新轨迹时间。"
|
export-hint="导出范围与上方筛选一致(履约状态、创建时间及其他条件均会生效)。含「自媒体渠道(挂号渠道来源)」:优先取该单关联处方登记的挂号;无则诊单下同患者挂号取 id 最大的一条(与前台挂号选择的记录一致);业绩侧栏带渠道筛选导出时与同页列表高亮挂号同源。「服务套餐」按字典 server_order 解析展示。「签收日期」与详情/业绩看板同源:优先库表轨迹;库内无轨迹时导出会按 logisticsTrace 口径补查快递100 并落库(如 PO 单在详情已签收但库内为空)。"
|
||||||
/>
|
/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-form>
|
</el-form>
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ use app\common\model\doctor\Appointment;
|
|||||||
use app\common\model\auth\Admin;
|
use app\common\model\auth\Admin;
|
||||||
use app\common\service\DataScope\DataScopeService;
|
use app\common\service\DataScope\DataScopeService;
|
||||||
use app\common\service\ExpressTrackService;
|
use app\common\service\ExpressTrackService;
|
||||||
|
use app\common\service\ExpressTrackingService;
|
||||||
use app\common\service\gancao\GancaoScmRecipelService;
|
use app\common\service\gancao\GancaoScmRecipelService;
|
||||||
use think\db\Query;
|
use think\db\Query;
|
||||||
use think\facade\Config;
|
use think\facade\Config;
|
||||||
@@ -2672,6 +2673,94 @@ class PrescriptionOrderLogic
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 复诊导出「初诊医助」:同 diagnosis_id 下最早 is_follow_up=0 的业务单医助(非 prev_staff 医生名)
|
||||||
|
*
|
||||||
|
* @param array<int, array<string, mixed>> $diagById
|
||||||
|
* @return array<int, string> diagnosis_id => 医助姓名
|
||||||
|
*/
|
||||||
|
private static function batchFirstVisitAssistantNameByDiagnosis(array $diagIds, array $diagById): array
|
||||||
|
{
|
||||||
|
if ($diagIds === []) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$firstRows = PrescriptionOrder::whereIn('diagnosis_id', $diagIds)
|
||||||
|
->whereNull('delete_time')
|
||||||
|
->where('is_follow_up', 0)
|
||||||
|
->field(['id', 'diagnosis_id', 'prescription_id', 'creator_id', 'create_time'])
|
||||||
|
->order('create_time', 'asc')
|
||||||
|
->order('id', 'asc')
|
||||||
|
->select()
|
||||||
|
->toArray();
|
||||||
|
|
||||||
|
$firstByDiag = [];
|
||||||
|
$rxIds = [];
|
||||||
|
foreach ($firstRows as $row) {
|
||||||
|
$did = (int) ($row['diagnosis_id'] ?? 0);
|
||||||
|
if ($did <= 0 || isset($firstByDiag[$did])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$firstByDiag[$did] = $row;
|
||||||
|
$rxId = (int) ($row['prescription_id'] ?? 0);
|
||||||
|
if ($rxId > 0) {
|
||||||
|
$rxIds[$rxId] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$rxAssistantById = [];
|
||||||
|
if ($rxIds !== []) {
|
||||||
|
$rxAssistantById = Prescription::whereIn('id', array_keys($rxIds))
|
||||||
|
->whereNull('delete_time')
|
||||||
|
->column('assistant_id', 'id');
|
||||||
|
}
|
||||||
|
|
||||||
|
$adminIds = [];
|
||||||
|
foreach ($firstByDiag as $did => $row) {
|
||||||
|
$diag = $diagById[$did] ?? [];
|
||||||
|
$rxId = (int) ($row['prescription_id'] ?? 0);
|
||||||
|
$rxAst = $rxId > 0 ? (int) ($rxAssistantById[$rxId] ?? 0) : 0;
|
||||||
|
$aid = self::resolveAssistantAdminIdForPrescriptionOrderRow(
|
||||||
|
$rxAst,
|
||||||
|
(int) ($diag['assistant_id'] ?? 0)
|
||||||
|
);
|
||||||
|
if ($aid <= 0) {
|
||||||
|
$aid = (int) ($row['creator_id'] ?? 0);
|
||||||
|
}
|
||||||
|
if ($aid > 0) {
|
||||||
|
$adminIds[$aid] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$nameByAdminId = [];
|
||||||
|
if ($adminIds !== []) {
|
||||||
|
$admins = Admin::whereIn('id', array_keys($adminIds))
|
||||||
|
->field(['id', 'name'])
|
||||||
|
->select()
|
||||||
|
->toArray();
|
||||||
|
foreach ($admins as $a) {
|
||||||
|
$nameByAdminId[(int) $a['id']] = trim((string) ($a['name'] ?? ''));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$out = [];
|
||||||
|
foreach ($firstByDiag as $did => $row) {
|
||||||
|
$diag = $diagById[$did] ?? [];
|
||||||
|
$rxId = (int) ($row['prescription_id'] ?? 0);
|
||||||
|
$rxAst = $rxId > 0 ? (int) ($rxAssistantById[$rxId] ?? 0) : 0;
|
||||||
|
$aid = self::resolveAssistantAdminIdForPrescriptionOrderRow(
|
||||||
|
$rxAst,
|
||||||
|
(int) ($diag['assistant_id'] ?? 0)
|
||||||
|
);
|
||||||
|
if ($aid <= 0) {
|
||||||
|
$aid = (int) ($row['creator_id'] ?? 0);
|
||||||
|
}
|
||||||
|
$out[$did] = $aid > 0 ? (string) ($nameByAdminId[$aid] ?? '') : '';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $out;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出用:管理员在 admin_dept 中的部门路径(多部门「;」、路径内「 / 」;业务订单导出取 creator_id)
|
* 导出用:管理员在 admin_dept 中的部门路径(多部门「;」、路径内「 / 」;业务订单导出取 creator_id)
|
||||||
*/
|
*/
|
||||||
@@ -2997,94 +3086,48 @@ class PrescriptionOrderLogic
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 签收时间批量解析:与 ExpressTrackingService::effectiveSignUnixFromTrackingDetail 同口径,
|
// 签收时间:与详情 logisticsTrace / 业绩提成同源;库内无轨迹时导出阶段补查快递100 并落库。
|
||||||
// 取 GREATEST(sign_time, max 签收类轨迹 trace_time_stamp, 已签收主表时的最新轨迹 trace_time_stamp);
|
/** @var array<int, int> $signTsByPoId order_id => Unix 秒 */
|
||||||
// 与详情/业绩看板提成「签收时间」语义一致,避免历史数据 sign_time=0 但实际已签收时被当作「未签收」。
|
$signTsByPoId = [];
|
||||||
/** @var array<string, int> $signTsByTracking trim 后的 tracking_number => Unix 秒 */
|
if ($poIds !== []) {
|
||||||
$signTsByTracking = [];
|
$signItems = [];
|
||||||
$trackingNumbers = [];
|
foreach ($lists as $row) {
|
||||||
foreach ($lists as $row) {
|
$oid = (int) ($row['id'] ?? 0);
|
||||||
$tn = trim((string) ($row['tracking_number'] ?? ''));
|
if ($oid <= 0) {
|
||||||
if ($tn !== '') {
|
continue;
|
||||||
$trackingNumbers[$tn] = true;
|
}
|
||||||
|
$signItems[] = [
|
||||||
|
'order_id' => $oid,
|
||||||
|
'tracking_number' => trim((string) ($row['tracking_number'] ?? '')),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
|
||||||
$trackingNumbers = array_keys($trackingNumbers);
|
|
||||||
if ($trackingNumbers !== []) {
|
|
||||||
try {
|
try {
|
||||||
$etRows = Db::name('express_tracking')
|
$signTsByPoId = ExpressTrackingService::batchResolveSignUnixFromDbForOrders($signItems);
|
||||||
->whereIn('tracking_number', $trackingNumbers)
|
|
||||||
->whereNull('delete_time')
|
|
||||||
->field(['id', 'tracking_number', 'sign_time', 'current_state', 'is_signed'])
|
|
||||||
->select()
|
|
||||||
->toArray();
|
|
||||||
$etIdToNum = [];
|
|
||||||
$signedEtIds = [];
|
|
||||||
$allEtIds = [];
|
|
||||||
foreach ($etRows as $r) {
|
|
||||||
$tn = trim((string) ($r['tracking_number'] ?? ''));
|
|
||||||
$eid = (int) ($r['id'] ?? 0);
|
|
||||||
if ($tn === '' || $eid <= 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$etIdToNum[$eid] = $tn;
|
|
||||||
$allEtIds[] = $eid;
|
|
||||||
$st = (int) ($r['sign_time'] ?? 0);
|
|
||||||
if ($st > 0) {
|
|
||||||
$signTsByTracking[$tn] = max($signTsByTracking[$tn] ?? 0, $st);
|
|
||||||
}
|
|
||||||
if ((string) ($r['current_state'] ?? '') === '3' || (int) ($r['is_signed'] ?? 0) === 1) {
|
|
||||||
$signedEtIds[$eid] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($allEtIds !== []) {
|
|
||||||
$sigCond = "(`status_code` IN ('3','301','302','304') "
|
|
||||||
. "OR `status` LIKE '%签收%' "
|
|
||||||
. "OR `trace_context` LIKE '%签收%' "
|
|
||||||
. "OR `trace_context` LIKE '%妥投%' "
|
|
||||||
. "OR `trace_context` LIKE '%已送达%' "
|
|
||||||
. "OR `trace_context` LIKE '%本人签收%')";
|
|
||||||
$sigTraces = Db::name('express_trace')
|
|
||||||
->whereIn('tracking_id', $allEtIds)
|
|
||||||
->where('trace_time_stamp', '>', 0)
|
|
||||||
->whereRaw($sigCond)
|
|
||||||
->fieldRaw('tracking_id, MAX(trace_time_stamp) AS max_ts')
|
|
||||||
->group('tracking_id')
|
|
||||||
->select()
|
|
||||||
->toArray();
|
|
||||||
foreach ($sigTraces as $t) {
|
|
||||||
$eid = (int) ($t['tracking_id'] ?? 0);
|
|
||||||
$tn = $etIdToNum[$eid] ?? '';
|
|
||||||
$ts = (int) ($t['max_ts'] ?? 0);
|
|
||||||
if ($tn !== '' && $ts > 0) {
|
|
||||||
$signTsByTracking[$tn] = max($signTsByTracking[$tn] ?? 0, $ts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$signedIdList = array_keys($signedEtIds);
|
|
||||||
if ($signedIdList !== []) {
|
|
||||||
$anyTraces = Db::name('express_trace')
|
|
||||||
->whereIn('tracking_id', $signedIdList)
|
|
||||||
->where('trace_time_stamp', '>', 0)
|
|
||||||
->fieldRaw('tracking_id, MAX(trace_time_stamp) AS max_ts')
|
|
||||||
->group('tracking_id')
|
|
||||||
->select()
|
|
||||||
->toArray();
|
|
||||||
foreach ($anyTraces as $t) {
|
|
||||||
$eid = (int) ($t['tracking_id'] ?? 0);
|
|
||||||
$tn = $etIdToNum[$eid] ?? '';
|
|
||||||
$ts = (int) ($t['max_ts'] ?? 0);
|
|
||||||
if ($tn !== '' && $ts > 0) {
|
|
||||||
$signTsByTracking[$tn] = max($signTsByTracking[$tn] ?? 0, $ts);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (\Throwable $e) {
|
} catch (\Throwable $e) {
|
||||||
Log::warning('appendPrescriptionOrderListExportRows resolve sign_time failed: ' . $e->getMessage());
|
Log::warning('appendPrescriptionOrderListExportRows batch sign_time failed: ' . $e->getMessage());
|
||||||
$signTsByTracking = [];
|
$signTsByPoId = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach ($lists as $row) {
|
||||||
|
$oid = (int) ($row['id'] ?? 0);
|
||||||
|
if ($oid <= 0 || (int) ($signTsByPoId[$oid] ?? 0) > 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (trim((string) ($row['tracking_number'] ?? '')) === '') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
$synced = ExpressTrackingService::syncSignUnixFromLogisticsForPrescriptionOrder($oid, true);
|
||||||
|
if ($synced > 0) {
|
||||||
|
$signTsByPoId[$oid] = $synced;
|
||||||
|
}
|
||||||
|
} catch (\Throwable $e) {
|
||||||
|
Log::warning('appendPrescriptionOrderListExportRows sync sign_time order ' . $oid . ': ' . $e->getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$firstVisitAssistantByDiag = self::batchFirstVisitAssistantNameByDiagnosis($diagIdList, $diagById);
|
||||||
$assistantDeptCache = [];
|
$assistantDeptCache = [];
|
||||||
|
|
||||||
foreach ($lists as &$item) {
|
foreach ($lists as &$item) {
|
||||||
@@ -3145,8 +3188,7 @@ class PrescriptionOrderLogic
|
|||||||
$item['export_agency_collect'] = number_format(round($amt - $paid, 2), 2, '.', '');
|
$item['export_agency_collect'] = number_format(round($amt - $paid, 2), 2, '.', '');
|
||||||
|
|
||||||
$item['export_tracking_number'] = (string) ($item['tracking_number'] ?? '');
|
$item['export_tracking_number'] = (string) ($item['tracking_number'] ?? '');
|
||||||
$tnTrim = trim((string) ($item['tracking_number'] ?? ''));
|
$signTs = $poId > 0 ? (int) ($signTsByPoId[$poId] ?? 0) : 0;
|
||||||
$signTs = $tnTrim !== '' ? (int) ($signTsByTracking[$tnTrim] ?? 0) : 0;
|
|
||||||
$item['export_sign_time'] = $signTs > 0 ? date('Y-m-d', $signTs) : '';
|
$item['export_sign_time'] = $signTs > 0 ? date('Y-m-d', $signTs) : '';
|
||||||
$isGc = trim((string) ($item['gancao_reciperl_order_no'] ?? '')) !== '';
|
$isGc = trim((string) ($item['gancao_reciperl_order_no'] ?? '')) !== '';
|
||||||
$item['export_supply_mode'] = $isGc ? '甘草' : '自营';
|
$item['export_supply_mode'] = $isGc ? '甘草' : '自营';
|
||||||
@@ -3161,7 +3203,9 @@ class PrescriptionOrderLogic
|
|||||||
}
|
}
|
||||||
|
|
||||||
$isFu = (int) ($item['is_follow_up'] ?? 0) === 1;
|
$isFu = (int) ($item['is_follow_up'] ?? 0) === 1;
|
||||||
$item['export_first_visit_assistant'] = $isFu ? (string) ($item['prev_staff'] ?? '') : '';
|
$item['export_first_visit_assistant'] = $isFu
|
||||||
|
? (string) ($firstVisitAssistantByDiag[(int) ($item['diagnosis_id'] ?? 0)] ?? '')
|
||||||
|
: '';
|
||||||
|
|
||||||
$hit = (int) ($item['po_assign_snapshot_hit'] ?? 0);
|
$hit = (int) ($item['po_assign_snapshot_hit'] ?? 0);
|
||||||
$rel = (int) ($item['po_assign_is_release'] ?? 0);
|
$rel = (int) ($item['po_assign_is_release'] ?? 0);
|
||||||
|
|||||||
Reference in New Issue
Block a user