Files
zyt/server/app/adminapi/lists/order/OrderLists.php
T
2026-04-27 15:30:28 +08:00

263 lines
8.8 KiB
PHP

<?php
declare(strict_types=1);
namespace app\adminapi\lists\order;
use app\adminapi\lists\BaseAdminDataLists;
use app\common\lists\ListsSearchInterface;
use app\common\lists\Traits\HasDataScopeFilter;
use app\common\model\Order;
use app\common\model\auth\AdminRole;
/**
* 订单列表
* Class OrderLists
* @package app\adminapi\lists\order
*/
class OrderLists extends BaseAdminDataLists implements ListsSearchInterface
{
use HasDataScopeFilter;
/**
* 将列表「创建时间」参数规范为可解析的日期时间(datetimerange 已是 Y-m-d H:i:s,不能再去拼接 00:00:00,否则会变成非法字符串)
*/
private function normalizeListDateTimeString(string $raw, bool $isEnd): string
{
$raw = trim($raw);
if ($raw === '') {
return '';
}
if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $raw) === 1) {
return $isEnd ? ($raw . ' 23:59:59') : ($raw . ' 00:00:00');
}
if (strlen($raw) === 19 && preg_match('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $raw) === 1) {
return $raw;
}
$ts = strtotime($raw);
if ($ts !== false) {
return date('Y-m-d H:i:s', $ts);
}
return '';
}
/**
* 患者关键词:在诊单表按姓名、手机号或诊单ID匹配(子查询里显式 whereOr,避免 | 在闭包/子查下兼容问题)
*
* @return \Closure|array{} 无匹配关键词时返回空数组表示不加条件
*/
private function patientKeywordSubWhere()
{
$kw = trim((string) ($this->params['patient_keyword'] ?? ''));
if ($kw === '') {
return [];
}
return function ($query) use ($kw) {
$query->table('zyt_tcm_diagnosis')
->whereNull('delete_time')
->where(function ($q) use ($kw) {
$q->where('patient_name', 'like', '%' . $kw . '%')
->whereOr('phone', 'like', '%' . $kw . '%');
if (preg_match('/^\d+$/', $kw) && (int) $kw > 0) {
$q->whereOr('id', '=', (int) $kw);
}
})
->field('id');
};
}
/**
* 创建时间:支持 int 时间戳 与 字符串 datetime 两种存法(用 OR 包裹,至少命中一类)
*/
private function appendCreateTimeWhere(array &$where): void
{
$s = !empty($this->params['create_time_start'])
? $this->normalizeListDateTimeString((string) $this->params['create_time_start'], false)
: '';
$e = !empty($this->params['create_time_end'])
? $this->normalizeListDateTimeString((string) $this->params['create_time_end'], true)
: '';
if ($s === '' && $e === '') {
return;
}
$i0 = $s !== '' ? (int) strtotime($s) : 0;
$i1 = $e !== '' ? (int) strtotime($e) : 0;
if ($i0 > 0 && $i1 > 0 && $i1 < $i0) {
$t = $i0;
$i0 = $i1;
$i1 = $t;
$ts = $s;
$s = $e;
$e = $ts;
}
$intOk = $i0 > 0 || $i1 > 0;
$strOk = $s !== '' || $e !== '';
if (!$intOk && !$strOk) {
return;
}
$where[] = function ($query) use ($s, $e, $i0, $i1, $intOk, $strOk) {
$query->where(function ($q) use ($s, $e, $i0, $i1, $intOk, $strOk) {
if ($intOk) {
$q->where(function ($qi) use ($i0, $i1) {
if ($i0 > 0) {
$qi->where('create_time', '>=', $i0);
}
if ($i1 > 0) {
$qi->where('create_time', '<=', $i1);
}
});
}
if ($strOk) {
if ($intOk) {
$q->whereOr(function ($qs) use ($s, $e) {
if ($s !== '') {
$qs->where('create_time', '>=', $s);
}
if ($e !== '') {
$qs->where('create_time', '<=', $e);
}
});
} else {
$q->where(function ($qs) use ($s, $e) {
if ($s !== '') {
$qs->where('create_time', '>=', $s);
}
if ($e !== '') {
$qs->where('create_time', '<=', $e);
}
});
}
}
});
};
}
/**
* @notes 设置搜索条件
* @return array
*/
public function setSearch(): array
{
return [
'=' => ['order_type', 'status'],
// ListsSearchTrait 只识别 %like% / like% 等,「like」不会命中任何 case,订单号因此搜不到
'%like%' => ['order_no'],
];
}
/**
* 按医助筛选:与「创建人」一致(指派后创建人为该医助)
*/
private function appendAssistantFilter(array &$where): void
{
$assistantId = (int) ($this->params['assistant_id'] ?? 0);
if ($assistantId <= 0) {
return;
}
$where[] = ['creator_id', '=', $assistantId];
}
private function filterByPermission(array &$where): void
{
// 检查是否是超管(root字段为1)
if (!empty($this->adminInfo['root']) && $this->adminInfo['root'] == 1) {
// 超管不过滤,可以看所有订单
return;
}
// 可查看全部订单:project.order_list_view_all_roles;未配置时回退 order_edit_all_roles
$supervisorRoles = config('project.order_list_view_all_roles', null);
if (!\is_array($supervisorRoles) || $supervisorRoles === []) {
$supervisorRoles = config('project.order_edit_all_roles', [0, 3, 4, 9, 6]);
}
// 检查当前用户是否是主管
$roleIds = \app\common\model\auth\AdminRole::where('admin_id', $this->adminId)->column('role_id');
// 如果不是主管,只能看自己创建的订单
$isSupervisor = count(array_intersect($roleIds, $supervisorRoles)) > 0;
if (!$isSupervisor) {
$where[] = ['creator_id', '=', $this->adminId];
}
}
/**
* @notes 获取列表
* @return array
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\DbException
* @throws \think\db\exception\ModelNotFoundException
*/
public function lists(): array
{
$where = $this->searchWhere;
// 权限控制:普通员工只能看自己创建的订单
$this->filterByPermission($where);
// 处理患者关联状态:pending=待关联, associated=已关联
$patientAssociation = $this->params['patient_association'] ?? '';
if ($patientAssociation === 'pending') {
$where[] = ['patient_id', 'null', ''];
} elseif ($patientAssociation === 'associated') {
$where[] = ['patient_id', 'not null', ''];
}
// 处理患者关键词搜索(从诊单表搜索)
$pkw = $this->patientKeywordSubWhere();
if ($pkw !== []) {
$where[] = ['patient_id', 'in', $pkw];
}
$this->appendAssistantFilter($where);
$this->appendCreateTimeWhere($where);
$query = Order::where($where);
$this->applyDataScopeByOwner($query, 'creator_id');
return $query
->with(['patient', 'creator'])
->order(['create_time' => 'desc'])
->limit($this->limitOffset, $this->pageSize)
->select()
->toArray();
}
/**
* @notes 获取数量
* @return int
*/
public function count(): int
{
$where = $this->searchWhere;
// 权限控制:普通员工只能看自己创建的订单
$this->filterByPermission($where);
// 处理患者关联状态
$patientAssociation = $this->params['patient_association'] ?? '';
if ($patientAssociation === 'pending') {
$where[] = ['patient_id', 'null', ''];
} elseif ($patientAssociation === 'associated') {
$where[] = ['patient_id', 'not null', ''];
}
// 处理患者关键词搜索(从诊单表搜索)
$pkw = $this->patientKeywordSubWhere();
if ($pkw !== []) {
$where[] = ['patient_id', 'in', $pkw];
}
$this->appendAssistantFilter($where);
$this->appendCreateTimeWhere($where);
$query = Order::where($where);
$this->applyDataScopeByOwner($query, 'creator_id');
return $query->count();
}
}