更新
This commit is contained in:
@@ -70,6 +70,25 @@ class PrescriptionLists extends BaseAdminDataLists implements ListsSearchInterfa
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 来源:system=系统代开(is_system_auto=1),manual=手工(0 或空)
|
||||
*/
|
||||
private function applySourceFilter($query): void
|
||||
{
|
||||
$sf = (string) ($this->params['source_filter'] ?? '');
|
||||
if ($sf === '' || $sf === 'all') {
|
||||
return;
|
||||
}
|
||||
if ($sf === 'system') {
|
||||
$query->where('is_system_auto', 1);
|
||||
|
||||
return;
|
||||
}
|
||||
if ($sf === 'manual') {
|
||||
$query->where('is_system_auto', 0);
|
||||
}
|
||||
}
|
||||
|
||||
private function applyVisibilityScope($query): void
|
||||
{
|
||||
$query->where(function ($query) {
|
||||
@@ -116,6 +135,7 @@ class PrescriptionLists extends BaseAdminDataLists implements ListsSearchInterfa
|
||||
{
|
||||
$query = Prescription::where($this->searchWhere);
|
||||
$this->applyAuditFilter($query);
|
||||
$this->applySourceFilter($query);
|
||||
$this->applyVisibilityScope($query);
|
||||
$this->applyCreatorIdsFilter($query);
|
||||
|
||||
@@ -208,6 +228,7 @@ class PrescriptionLists extends BaseAdminDataLists implements ListsSearchInterfa
|
||||
{
|
||||
$query = Prescription::where($this->searchWhere);
|
||||
$this->applyAuditFilter($query);
|
||||
$this->applySourceFilter($query);
|
||||
$this->applyVisibilityScope($query);
|
||||
$this->applyCreatorIdsFilter($query);
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@ use app\common\model\tcm\Prescription;
|
||||
use app\common\model\tcm\PrescriptionOrder;
|
||||
use app\common\model\tcm\PrescriptionOrderPayOrder;
|
||||
use app\common\service\gancao\GancaoScmRecipelService;
|
||||
use think\facade\Config;
|
||||
use think\db\Query;
|
||||
|
||||
class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchInterface, ListsExtendInterface
|
||||
{
|
||||
@@ -22,12 +24,45 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
|
||||
return [
|
||||
'=' => ['prescription_id', 'fulfillment_status', 'prescription_audit_status', 'payment_slip_audit_status'],
|
||||
'%like%' => ['order_no'],
|
||||
'between_time' => 'create_time',
|
||||
];
|
||||
}
|
||||
|
||||
public function lists(): array
|
||||
/**
|
||||
* 列表/统计条数:含全部搜索条件(含创建时间区间)
|
||||
*/
|
||||
private function buildFilteredQuery(): Query
|
||||
{
|
||||
$query = PrescriptionOrder::where($this->searchWhere)->whereNull('delete_time');
|
||||
$this->applyPermissionAndExtraFilters($query);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* 今日汇总:与列表相同的「非时间」条件(医生/医助/患者/状态/单号等),不含创建时间区间,避免与「今日」语义重复
|
||||
*
|
||||
* @return array<int, array{0: string, 1: string, 2: mixed}>
|
||||
*/
|
||||
private function searchWhereWithoutCreateTimeRange(): array
|
||||
{
|
||||
return array_values(array_filter(
|
||||
$this->searchWhere,
|
||||
static function ($w): bool {
|
||||
if (!\is_array($w) || \count($w) < 2) {
|
||||
return true;
|
||||
}
|
||||
if (($w[0] ?? '') === 'create_time' && ($w[1] ?? '') === 'between') {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
private function applyPermissionAndExtraFilters($query): void
|
||||
{
|
||||
$this->applyDoctorAssistantFilters($query);
|
||||
$this->applyPatientKeywordFilter($query);
|
||||
if (!PrescriptionOrderLogic::canSeeAllPrescriptionOrders($this->adminInfo)) {
|
||||
@@ -39,6 +74,85 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 医助:仅「诊单医助=本人」的订单计业绩
|
||||
*/
|
||||
private function applyAssistantDiagnosisOnlyFilter($query): void
|
||||
{
|
||||
$poTbl = (new PrescriptionOrder())->getTable();
|
||||
$diagTbl = (new Diagnosis())->getTable();
|
||||
$aid = (int) $this->adminId;
|
||||
$query->whereExists(
|
||||
"SELECT 1 FROM `{$diagTbl}` dg WHERE dg.`id` = `{$poTbl}`.`diagnosis_id` AND dg.`delete_time` IS NULL AND dg.`assistant_id` = {$aid}"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计用查询骨架:不含 create_time 区间;其它筛选项 + 统计专用数据域(不重复 where)
|
||||
*/
|
||||
private function buildBaseQueryForStats(): Query
|
||||
{
|
||||
$query = PrescriptionOrder::where($this->searchWhereWithoutCreateTimeRange())->whereNull('delete_time');
|
||||
$this->applyDoctorAssistantFilters($query);
|
||||
$this->applyPatientKeywordFilter($query);
|
||||
if (PrescriptionOrderLogic::canViewOrderListStatsAllScope($this->adminInfo)) {
|
||||
return $query;
|
||||
}
|
||||
$assistantRid = (int) Config::get('project.prescription_order_stats_assistant_role_id', 2);
|
||||
$myRoles = array_map('intval', $this->adminInfo['role_id'] ?? []);
|
||||
if ($assistantRid > 0 && in_array($assistantRid, $myRoles, true)) {
|
||||
$this->applyAssistantDiagnosisOnlyFilter($query);
|
||||
|
||||
return $query;
|
||||
}
|
||||
if (!PrescriptionOrderLogic::canSeeAllPrescriptionOrders($this->adminInfo)) {
|
||||
$diagIds = Diagnosis::where('assistant_id', $this->adminId)->whereNull('delete_time')->column('id');
|
||||
$query->where(function ($q) use ($diagIds) {
|
||||
$q->where('creator_id', $this->adminId);
|
||||
if ($diagIds !== []) {
|
||||
$q->whereOr('diagnosis_id', 'in', $diagIds);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计所对应的时间:与入参 start_time / end_time 一致;未传则按自然日「今天」
|
||||
*
|
||||
* @return array{0: int, 1: int, 2: string, 3: string}
|
||||
*/
|
||||
private function resolveStatsTimeWindow(): array
|
||||
{
|
||||
$st = trim((string) ($this->params['start_time'] ?? ''));
|
||||
$et = trim((string) ($this->params['end_time'] ?? ''));
|
||||
if ($st !== '' && $et !== '') {
|
||||
$t0 = strtotime($st);
|
||||
$t1 = strtotime($et);
|
||||
if ($t0 !== false && $t1 !== false) {
|
||||
return [(int) $t0, (int) $t1, $st, $et];
|
||||
}
|
||||
}
|
||||
$t0 = strtotime(date('Y-m-d 00:00:00'));
|
||||
$t1 = strtotime(date('Y-m-d 23:59:59'));
|
||||
if ($t0 === false || $t1 === false) {
|
||||
return [0, 0, '', ''];
|
||||
}
|
||||
|
||||
return [
|
||||
(int) $t0,
|
||||
(int) $t1,
|
||||
date('Y-m-d 00:00:00'),
|
||||
date('Y-m-d 23:59:59'),
|
||||
];
|
||||
}
|
||||
|
||||
public function lists(): array
|
||||
{
|
||||
$query = $this->buildFilteredQuery();
|
||||
$lists = $query
|
||||
->order('id', 'desc')
|
||||
->limit($this->limitOffset, $this->limitLength)
|
||||
@@ -159,26 +273,87 @@ class PrescriptionOrderLists extends BaseAdminDataLists implements ListsSearchIn
|
||||
|
||||
public function extend(): array
|
||||
{
|
||||
$s = $this->computeListStatsForExtend();
|
||||
|
||||
return [
|
||||
'deposit_min_amount' => PrescriptionOrderLogic::depositMinAmount(),
|
||||
'gancao_scm_enabled' => GancaoScmRecipelService::isConfigured(),
|
||||
'deposit_min_amount' => PrescriptionOrderLogic::depositMinAmount(),
|
||||
'gancao_scm_enabled' => GancaoScmRecipelService::isConfigured(),
|
||||
'stats_order_amount' => $s['order_amount'],
|
||||
'stats_linked_pay_amount' => $s['linked_pay_amount'],
|
||||
'stats_time_start' => $s['label_start'],
|
||||
'stats_time_end' => $s['label_end'],
|
||||
/** 统计口径:all=支付审核白名单全量;assistant=医助仅诊单协助业绩;restricted=与列表同域 */
|
||||
'stats_scope' => $s['scope'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{order_amount: float, linked_pay_amount: float, label_start: string, label_end: string, scope: string}
|
||||
*/
|
||||
private function computeListStatsForExtend(): array
|
||||
{
|
||||
[$t0, $t1, $l0, $l1] = $this->resolveStatsTimeWindow();
|
||||
if ($t0 <= 0 || $t1 <= 0) {
|
||||
return [
|
||||
'order_amount' => 0.0,
|
||||
'linked_pay_amount' => 0.0,
|
||||
'label_start' => '',
|
||||
'label_end' => '',
|
||||
'scope' => 'restricted',
|
||||
];
|
||||
}
|
||||
if ($t1 < $t0) {
|
||||
$tmp = $t0;
|
||||
$t0 = $t1;
|
||||
$t1 = $tmp;
|
||||
}
|
||||
|
||||
$q = $this->buildBaseQueryForStats()->whereBetween('create_time', [$t0, $t1]);
|
||||
$orderAmount = round((float) (clone $q)->sum('amount'), 2);
|
||||
$ids = (clone $q)->column('id');
|
||||
$ids = array_values(array_filter(array_map('intval', $ids), static function (int $id): bool {
|
||||
return $id > 0;
|
||||
}));
|
||||
if ($ids === []) {
|
||||
return $this->statsExtendPayload($orderAmount, 0.0, $l0, $l1);
|
||||
}
|
||||
$sumPaid = (float) PrescriptionOrderPayOrder::alias('l')
|
||||
->join('order o', 'l.pay_order_id = o.id')
|
||||
->whereIn('l.prescription_order_id', $ids)
|
||||
->whereNull('o.delete_time')
|
||||
->sum('o.amount');
|
||||
$sumPaid = round($sumPaid, 2);
|
||||
|
||||
return $this->statsExtendPayload($orderAmount, $sumPaid, $l0, $l1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array{order_amount: float, linked_pay_amount: float, label_start: string, label_end: string, scope: string}
|
||||
*/
|
||||
private function statsExtendPayload(float $orderAmount, float $linked, string $l0, string $l1): array
|
||||
{
|
||||
$scope = 'restricted';
|
||||
if (PrescriptionOrderLogic::canViewOrderListStatsAllScope($this->adminInfo)) {
|
||||
$scope = 'all';
|
||||
} else {
|
||||
$ar = (int) Config::get('project.prescription_order_stats_assistant_role_id', 2);
|
||||
if ($ar > 0 && in_array($ar, array_map('intval', $this->adminInfo['role_id'] ?? []), true)) {
|
||||
$scope = 'assistant';
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
'order_amount' => $orderAmount,
|
||||
'linked_pay_amount' => $linked,
|
||||
'label_start' => $l0,
|
||||
'label_end' => $l1,
|
||||
'scope' => $scope,
|
||||
];
|
||||
}
|
||||
|
||||
public function count(): int
|
||||
{
|
||||
$query = PrescriptionOrder::where($this->searchWhere)->whereNull('delete_time');
|
||||
$this->applyDoctorAssistantFilters($query);
|
||||
$this->applyPatientKeywordFilter($query);
|
||||
if (!PrescriptionOrderLogic::canSeeAllPrescriptionOrders($this->adminInfo)) {
|
||||
$diagIds = Diagnosis::where('assistant_id', $this->adminId)->whereNull('delete_time')->column('id');
|
||||
$query->where(function ($q) use ($diagIds) {
|
||||
$q->where('creator_id', $this->adminId);
|
||||
if ($diagIds !== []) {
|
||||
$q->whereOr('diagnosis_id', 'in', $diagIds);
|
||||
}
|
||||
});
|
||||
}
|
||||
$query = $this->buildFilteredQuery();
|
||||
|
||||
return (int) $query->count();
|
||||
}
|
||||
|
||||
@@ -124,6 +124,22 @@ class PrescriptionOrderLogic
|
||||
return self::roleIntersect($adminInfo, is_array($allow) ? $allow : []);
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表顶栏金额统计:与「关联支付单」审核白名单同档的角色可见「全量」统计(不缩小到本人/医助诊单域)
|
||||
*/
|
||||
public static function canViewOrderListStatsAllScope(array $adminInfo): bool
|
||||
{
|
||||
if (!empty($adminInfo['root']) && (int) $adminInfo['root'] === 1) {
|
||||
return true;
|
||||
}
|
||||
$allow = Config::get('project.prescription_order_payment_audit_roles', [0, 3, 4, 9, 6]);
|
||||
if (!is_array($allow)) {
|
||||
$allow = [0, 3];
|
||||
}
|
||||
|
||||
return self::roleIntersect($adminInfo, $allow);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string,mixed> $row
|
||||
*/
|
||||
@@ -424,6 +440,12 @@ class PrescriptionOrderLogic
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((int) ($rx['void_status'] ?? 0) === 1) {
|
||||
self::$error = '已作废处方不可创建业务订单';
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (PrescriptionOrder::where('prescription_id', $rxId)->whereNull('delete_time')->where('fulfillment_status', '<>', 4)->count() > 0) {
|
||||
self::$error = '该处方已存在有效业务订单(未撤回前不可重复创建)';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user