This commit is contained in:
Your Name
2026-04-30 17:36:47 +08:00
parent 4c21ee5938
commit 7e557b1ea2
33 changed files with 8718 additions and 94 deletions
@@ -16,6 +16,7 @@ use app\common\model\auth\AdminDept;
use app\common\model\tcm\Prescription;
use app\common\model\tcm\PrescriptionOrder;
use app\common\model\tcm\PrescriptionOrderPayOrder;
use app\common\model\ExpressTracking;
use app\common\service\gancao\GancaoScmRecipelService;
use think\facade\Config;
use think\db\Query;
@@ -66,16 +67,111 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
));
}
/**
* 重点看板统计:去掉审核/履约状态筛选,保留其它筛选(时间、医生、医助、患者、供货方式等)
*
* @return array<int, array{0: string, 1: string, 2: mixed}>
*/
private function searchWhereWithoutStatusFilters(): array
{
return array_values(array_filter(
$this->searchWhere,
static function ($w): bool {
if (!\is_array($w) || \count($w) < 2) {
return true;
}
$field = (string) ($w[0] ?? '');
if (!in_array($field, ['prescription_audit_status', 'payment_slip_audit_status', 'fulfillment_status'], true)) {
return true;
}
$op = strtolower((string) ($w[1] ?? ''));
return $op !== '=';
}
));
}
private function applyPermissionAndExtraFilters($query): void
{
$this->applyDoctorAssistantFilters($query);
$this->applyPatientKeywordFilter($query);
$this->applyExpressCompanyFilter($query);
$this->applyExpressKeywordFilter($query);
$this->applySupplyModeFilter($query);
if (!PrescriptionOrderLogic::canSeeAllPrescriptionOrders($this->adminInfo)) {
$query->where('creator_id', $this->adminId);
}
$this->applyDataScopeForPrescriptionOrder($query);
}
/**
* 按快递公司筛选(点击快捷标签:顺丰 / 京东)
*
* 说明:主表 express_company 常为 auto/空;快递100 回写承运商在 zyt_express_tracking,需一并匹配。
*/
private function applyExpressCompanyFilter($query): void
{
$company = strtolower(trim((string) ($this->params['express_company'] ?? '')));
if (!in_array($company, ['sf', 'jd'], true)) {
return;
}
$poTbl = (new PrescriptionOrder())->getTable();
$etTbl = (new ExpressTracking())->getTable();
if ($company === 'sf') {
$po = "(LOWER(TRIM(IFNULL(`{$poTbl}`.`express_company`,''))) IN ('sf','shunfeng')"
. " OR `{$poTbl}`.`express_company` LIKE '%顺丰%'"
. " OR (TRIM(IFNULL(`{$poTbl}`.`tracking_number`,'')) <> ''"
. " AND (`{$poTbl}`.`tracking_number` LIKE 'SF%' OR `{$poTbl}`.`tracking_number` LIKE 'sf%')))";
$et = "EXISTS (SELECT 1 FROM `{$etTbl}` et WHERE et.`delete_time` IS NULL"
. " AND et.`order_id` = `{$poTbl}`.`id` AND et.`order_type` = 'prescription'"
. " AND (LOWER(TRIM(IFNULL(et.`express_company`,''))) IN ('sf','shunfeng')"
. " OR et.`express_company_name` LIKE '%顺丰%'"
. " OR (TRIM(IFNULL(et.`tracking_number`,'')) <> ''"
. " AND (et.`tracking_number` LIKE 'SF%' OR et.`tracking_number` LIKE 'sf%'))))";
$query->whereRaw("(($po) OR ($et))");
return;
}
$po = "(LOWER(TRIM(IFNULL(`{$poTbl}`.`express_company`,''))) IN ('jd','jingdong')"
. " OR `{$poTbl}`.`express_company` LIKE '%京东%'"
. " OR (TRIM(IFNULL(`{$poTbl}`.`tracking_number`,'')) <> ''"
. " AND (`{$poTbl}`.`tracking_number` LIKE 'JD%' OR `{$poTbl}`.`tracking_number` LIKE 'jd%'"
. " OR `{$poTbl}`.`tracking_number` LIKE 'JDVB%' OR `{$poTbl}`.`tracking_number` LIKE 'jdvb%')))";
$et = "EXISTS (SELECT 1 FROM `{$etTbl}` et WHERE et.`delete_time` IS NULL"
. " AND et.`order_id` = `{$poTbl}`.`id` AND et.`order_type` = 'prescription'"
. " AND (LOWER(TRIM(IFNULL(et.`express_company`,''))) IN ('jd','jingdong')"
. " OR et.`express_company_name` LIKE '%京东%'"
. " OR (TRIM(IFNULL(et.`tracking_number`,'')) <> ''"
. " AND (et.`tracking_number` LIKE 'JD%' OR et.`tracking_number` LIKE 'jd%'"
. " OR et.`tracking_number` LIKE 'JDVB%' OR et.`tracking_number` LIKE 'jdvb%'))))";
$query->whereRaw("(($po) OR ($et))");
}
/**
* 供货方式:甘草(已上传甘草药方单号)/ 自营(无甘草单号,走药房直发等)
*
* 入参 supply_modegancao | self,空表示不限
*/
private function applySupplyModeFilter($query): void
{
$mode = strtolower(trim((string) ($this->params['supply_mode'] ?? '')));
if ($mode === '') {
return;
}
if ($mode === 'gancao') {
$query->whereRaw("TRIM(IFNULL(`gancao_reciperl_order_no`,'')) <> ''");
return;
}
if ($mode === 'self') {
$query->whereRaw("TRIM(IFNULL(`gancao_reciperl_order_no`,'')) = ''");
return;
}
}
/**
* 数据隔离:创建者 ∈ 可见 admin,或 关联诊单医助 ∈ 可见 admin
*/
@@ -302,6 +398,7 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
public function extend(): array
{
$s = $this->computeListStatsForExtend();
$focus = $this->computeFocusCountsForExtend();
return [
'deposit_min_amount' => PrescriptionOrderLogic::depositMinAmount(),
@@ -320,6 +417,32 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
'stats_time_end' => $s['label_end'],
/** 统计口径:all=支付审核白名单全量;assistant=医助仅诊单协助业绩;restricted=与列表同域 */
'stats_scope' => $s['scope'],
'focus_pending_rx_count' => $focus['pending_rx'],
'focus_pending_pay_count' => $focus['pending_pay'],
'focus_pending_ship_count' => $focus['pending_ship'],
'focus_risk_count' => $focus['risk'],
];
}
/**
* 重点看板计数(基于“当前筛选(去除审核/履约状态)”后的全量命中)
*
* @return array{pending_rx:int,pending_pay:int,pending_ship:int,risk:int}
*/
private function computeFocusCountsForExtend(): array
{
$query = PrescriptionOrder::where($this->searchWhereWithoutStatusFilters())->whereNull('delete_time');
$this->applyPermissionAndExtraFilters($query);
return [
// 处方审核待处理
'pending_rx' => (int) (clone $query)->where('prescription_audit_status', 0)->count(),
// 支付审核待处理(前提:处方已通过)
'pending_pay' => (int) (clone $query)->where('prescription_audit_status', 1)->where('payment_slip_audit_status', 0)->count(),
// 履约待发货
'pending_ship' => (int) (clone $query)->where('fulfillment_status', 2)->count(),
// 重点异常:支付审核驳回(与前端「重点异常」快捷筛选口径一致)
'risk' => (int) (clone $query)->where('payment_slip_audit_status', 2)->count(),
];
}
@@ -512,4 +635,30 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
. "AND (dg.`patient_name` LIKE '{$likeSql}' OR dg.`phone` LIKE '{$likeSql}')"
);
}
/**
* 按快递单号 / 快递公司 模糊检索
*/
private function applyExpressKeywordFilter($query): void
{
$kw = trim((string) ($this->params['express_keyword'] ?? ''));
if ($kw === '') {
return;
}
$likeInner = str_replace(['\\', '%', '_'], ['\\\\', '\\%', '\\_'], $kw);
$like = '%' . $likeInner . '%';
$likeSql = str_replace("'", "''", $like);
$poTbl = (new PrescriptionOrder())->getTable();
$etTbl = (new ExpressTracking())->getTable();
$query->whereRaw(
"(IFNULL(`{$poTbl}`.`tracking_number`,'') LIKE '{$likeSql}'"
. " OR IFNULL(`{$poTbl}`.`express_company`,'') LIKE '{$likeSql}'"
. " OR EXISTS (SELECT 1 FROM `{$etTbl}` et WHERE et.`delete_time` IS NULL"
. " AND et.`order_id` = `{$poTbl}`.`id` AND et.`order_type` = 'prescription'"
. " AND (IFNULL(et.`tracking_number`,'') LIKE '{$likeSql}'"
. " OR IFNULL(et.`express_company`,'') LIKE '{$likeSql}'"
. " OR IFNULL(et.`express_company_name`,'') LIKE '{$likeSql}'))"
. ")"
);
}
}