You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

850 lines
30 KiB
PHP

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
namespace App\Http\Controllers\API\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Lib\Rs;
use Illuminate\Support\Facades\DB;
use App\Services\UserService;
class WorkbenchController extends Controller
{
protected $userService;
public function __construct(UserService $userService)
{
$this->userService = $userService;
}
/**
* 获取医嘱列表
*/
public function getApplicationList(Request $request)
{
$hisRequestNo = $request->input('his_request_no', '');
$patientName = $request->input('patient_name', '');
$patientPhone = $request->input('patient_phone', '');
$applyDoctorName = $request->input('apply_doctor_name', '');
$status = $request->input('status', null);
$applyTimeStart = $request->input('apply_time_start', '');
$applyTimeEnd = $request->input('apply_time_end', '');
$page = $request->input('page', 1);
$pageSize = $request->input('page_size', 10);
// 获取当前用户信息,非管理员按执行科室或开单医生过滤
$sysUser = $this->userService->getUserInfoFromRequest($request);
$isAdmin = $this->userService->isAdminFromRequest($request);
$deptCode = null;
$hisCode = null;
if (!$isAdmin) {
if (!empty($sysUser->dept_id)) {
$dept = DB::table('department')->where('id', $sysUser->dept_id)->where('deleted', 0)->first();
if ($dept && !empty($dept->code)) {
$deptCode = $dept->code;
}
}
if (!empty($sysUser->his_code)) {
$hisCode = $sysUser->his_code;
}
}
$query = DB::table('exam_application as ea')
->leftJoin('patient_type as pt', 'ea.patient_type', '=', 'pt.mask')
->select([
'ea.id',
'ea.his_order_id',
'ea.his_request_no',
'ea.patient_id',
'ea.patient_type',
'ea.patient_name',
'ea.patient_id_card_no',
'ea.patient_phone',
'ea.patient_gender',
'ea.patient_age',
'ea.patient_birthday',
'ea.apply_department_code',
'ea.apply_department_name',
'ea.apply_doctor_code',
'ea.apply_doctor_name',
'ea.examination_item_name',
'ea.examination_item_code',
'ea.examination_department_code',
'ea.examination_department_name',
'ea.apply_time',
'ea.payment_status',
'ea.clinical_diagnosis',
'ea.notes',
'ea.status',
'ea.created_at',
'ea.updated_at',
'ea.his_cancel_time',
'ea.his_cancel_reason',
'pt.name as patient_type_name'
]);
if (!empty($hisRequestNo)) {
$query->where('ea.his_request_no', 'like', '%' . $hisRequestNo . '%');
}
if (!empty($patientName)) {
$query->where('ea.patient_name', 'like', '%' . $patientName . '%');
}
if (!empty($patientPhone)) {
$query->where('ea.patient_phone', 'like', '%' . $patientPhone . '%');
}
if (!empty($applyDoctorName)) {
$query->where('ea.apply_doctor_name', 'like', '%' . $applyDoctorName . '%');
}
if ($status !== null) {
$query->where('ea.status', $status);
}
if (!empty($applyTimeStart)) {
$query->where('ea.apply_time', '>=', $applyTimeStart);
}
if (!empty($applyTimeEnd)) {
$query->where('ea.apply_time', '<=', $applyTimeEnd . ' 23:59:59');
}
// 非管理员:执行科室是自己科室 OR 开单医生是自己
if (!$isAdmin) {
if ($deptCode !== null || $hisCode !== null) {
$query->where(function ($q) use ($deptCode, $hisCode) {
if ($deptCode !== null) {
$q->where('ea.examination_department_code', $deptCode);
}
if ($hisCode !== null) {
$q->orWhere('ea.apply_doctor_code', $hisCode);
}
});
} else {
$query->whereRaw('1 = 0');
}
}
$total = $query->count();
$list = $query->orderBy('ea.apply_time', 'desc')
->orderBy('ea.id', 'desc')
->skip(($page - 1) * $pageSize)
->take($pageSize)
->get();
// 查询已预约的医嘱的预约信息
$appointmentIds = $list->where('status', 1)->pluck('id')->toArray();
$appointments = [];
if (!empty($appointmentIds)) {
$appointments = DB::table('exam_appointment as ea')
->leftJoin('department_resource as dr', 'ea.department_resource_id', '=', 'dr.id')
->whereIn('ea.exam_application_id', $appointmentIds)
->where('ea.status', 1) // 只获取预约成功的记录
->select([
'ea.id',
'ea.exam_application_id',
'ea.time_slot_id',
'ea.channel_id',
'ea.appointment_time',
'ea.department_resource_id',
'dr.cancel_reason_required'
])
->get()
->keyBy('exam_application_id');
}
// 为每个医嘱添加预约信息
foreach ($list as $item) {
// 如果医嘱已预约,添加预约信息
if ($item->status === 1 && isset($appointments[$item->id])) {
$item->appointment_info = $appointments[$item->id];
} else {
$item->appointment_info = null;
}
}
return Rs::success([
'list' => $list,
'total' => $total,
'page' => $page,
'page_size' => $pageSize,
'total_pages' => ceil($total / $pageSize)
]);
}
/**
* 获取患者预约列表(历史预约记录)
*/
public function getPatientAppointments(Request $request)
{
$patientId = $request->input('patient_id', 0);
$statusArr = $request->input('status_arr');
if (empty($patientId)) {
return Rs::error('患者ID不能为空');
}
$list = collect();
// 状态处理逻辑简化
$hasPending = $statusArr === null || (is_array($statusArr) && in_array(0, $statusArr));
$hasScheduled = $statusArr === null || (is_array($statusArr) && array_intersect([1, 2, 3], $statusArr));
// 查询未预约记录
if ($hasPending) {
$pending = DB::table('exam_application')
->where('patient_id', $patientId)
->where('status', 0)
->select(['id', 'his_order_id', 'patient_id', 'patient_name', 'patient_id_card_no', 'patient_gender', 'patient_age',
'examination_item_name', 'examination_item_code', 'examination_department_name',
'examination_department_code', 'apply_doctor_name', 'apply_doctor_code',
'apply_department_name', 'apply_time', 'payment_status', 'clinical_diagnosis',
'notes', 'status', 'created_at', 'updated_at'])
->orderBy('apply_time', 'desc')
->orderBy('id', 'desc')
->get()
->map(function ($item) {
// 补充预约表字段
return (object) array_merge((array)$item, [
'time_slot_id' => null, 'channel_id' => null, 'exam_application_id' => $item->id,
'appointment_time' => null, 'check_in_time' => null, 'finish_time' => null,
'cancel_time' => null, 'channel_name' => null, 'channel_short_name' => null
]);
});
$list = $list->concat($pending);
}
// 查询已预约记录
if ($hasScheduled) {
$scheduledStatuses = $statusArr === null ? [1, 2, 3] : array_intersect([1, 2, 3], $statusArr);
if (!empty($scheduledStatuses)) {
$appointments = DB::table('exam_appointment as ea')
->leftJoin('channel as c', 'ea.channel_id', '=', 'c.id')
->leftJoin('exam_application as eapp', 'ea.exam_application_id', '=', 'eapp.id')
->leftJoin('plan as p', 'ea.time_slot_id', '=', 'p.id')
->leftJoin('department_resource as dr', 'ea.department_resource_id', '=', 'dr.id')
->select(['ea.id', 'ea.time_slot_id', 'ea.channel_id', 'ea.exam_application_id', 'ea.patient_id',
'ea.patient_name', 'ea.status', 'ea.appointment_time', 'ea.check_in_time',
'ea.finish_time', 'ea.cancel_time', 'ea.created_at', 'ea.updated_at',
'c.name as channel_name', 'c.short_name as channel_short_name',
'eapp.examination_item_name', 'eapp.examination_item_code',
'eapp.examination_department_name', 'eapp.examination_department_code',
'eapp.apply_doctor_name', 'eapp.apply_doctor_code', 'eapp.apply_department_name',
'eapp.apply_time', 'eapp.payment_status', 'eapp.clinical_diagnosis', 'eapp.notes',
'eapp.patient_id_card_no',
'p.start_time as slot_start_time', 'p.end_time as slot_end_time',
'dr.name as room_name', 'dr.cancel_reason_required'])
->where('ea.patient_id', $patientId)
->whereIn('ea.status', $scheduledStatuses)
->orderBy('ea.id', 'desc')
->get();
$list = $list->concat($appointments);
}
}
// 简化排序逻辑
if (!$list->isEmpty()) {
$list = $list->sortByDesc(function ($item) {
return $item->updated_at ?? $item->apply_time ?? $item->created_at;
})->values();
}
return Rs::success($list);
}
/**
* 获取患者详情
*/
public function getPatientDetail(Request $request)
{
$patientId = $request->input('patient_id', 0);
if (empty($patientId)) {
return Rs::error('患者ID不能为空');
}
// 从exam_application表获取患者信息
$patientInfo = DB::table('exam_application')
->where('patient_id', $patientId)
->select([
'patient_id',
'patient_name',
'patient_gender',
'patient_age',
'patient_phone',
'patient_type',
'patient_birthday'
])
->first();
if (!$patientInfo) {
return Rs::error('未找到患者信息');
}
// 获取患者类型名称
$patientTypeName = '';
if ($patientInfo->patient_type == 1) {
$patientTypeName = '门诊患者';
} elseif ($patientInfo->patient_type == 2) {
$patientTypeName = '住院患者';
} elseif ($patientInfo->patient_type == 3) {
$patientTypeName = '急诊患者';
} elseif ($patientInfo->patient_type == 4) {
$patientTypeName = '体检患者';
}
$patientInfo->patient_type_name = $patientTypeName;
return Rs::success($patientInfo);
}
/**
* 根据HIS医嘱ID数组获取医嘱信息
*/
public function getApplicationsByHisOrderIds(Request $request)
{
$hisOrderIds = $request->input('his_order_ids', []);
$channelId = $request->input('channel_id', 2); // 默认护士站
if (empty($hisOrderIds) || !is_array($hisOrderIds)) {
return Rs::error('医嘱ID列表不能为空');
}
$list = DB::table('exam_application as ea')
->leftJoin('patient_type as pt', 'ea.patient_type', '=', 'pt.mask')
->whereIn('ea.his_order_id', $hisOrderIds)
->whereIn('ea.status', [0, 1]) // 只获取申请中和已预约的医嘱
->select([
'ea.id',
'ea.his_request_no',
'ea.his_order_id',
'ea.patient_id',
'ea.patient_type',
'ea.patient_name',
'ea.patient_phone',
'ea.patient_gender',
'ea.patient_age',
'ea.apply_department_code',
'ea.apply_department_name',
'ea.apply_doctor_code',
'ea.apply_doctor_name',
'ea.examination_item_name',
'ea.examination_item_code',
'ea.examination_department_code',
'ea.examination_department_name',
'ea.apply_time',
'ea.payment_status',
'ea.status',
'ea.clinical_diagnosis',
'ea.notes',
'ea.created_at',
'ea.updated_at',
'ea.his_cancel_time',
'ea.his_cancel_reason',
'pt.name as patient_type_name'
])
->orderBy('ea.apply_time', 'desc')
->orderBy('ea.id', 'desc')
->get();
// 获取渠道掩码
$channel = DB::table('channel')->where('id', $channelId)->value('mask');
$channelMask = $channel ?? 2; // 默认护士站掩码
// 查询已预约的医嘱的预约信息
$appointmentIds = $list->where('status', 1)->pluck('id')->toArray();
$appointments = [];
if (!empty($appointmentIds)) {
$appointments = DB::table('exam_appointment as ea')
->leftJoin('department_resource as dr', 'ea.department_resource_id', '=', 'dr.id')
->whereIn('ea.exam_application_id', $appointmentIds)
->where('ea.status', 1) // 只获取预约成功的记录
->select([
'ea.id',
'ea.exam_application_id',
'ea.time_slot_id',
'ea.channel_id',
'ea.appointment_time',
'ea.department_resource_id',
'dr.cancel_reason_required'
])
->get()
->keyBy('exam_application_id');
}
// 为每个医嘱添加项目状态检查和预约信息
foreach ($list as $item) {
$item->status_messages = $this->checkItemStatus($item->examination_item_code, $channelMask);
// 如果医嘱已预约,添加预约信息
if ($item->status === 1 && isset($appointments[$item->id])) {
$item->appointment_info = $appointments[$item->id];
} else {
$item->appointment_info = null;
}
}
return Rs::success($list);
}
/**
* 检查项目状态
* @param string $itemCode 项目编码
* @param int $channelMask 渠道掩码
* @return array 状态消息数组
*/
private function checkItemStatus($itemCode, $channelMask)
{
$messages = [];
// 1. 检查项目是否存在于数据库
$examItem = DB::table('exam_item')
->where('code', $itemCode)
->where('deleted', 0)
->first();
if (!$examItem) {
$messages[] = '项目不存在';
return $messages;
}
// 2. 检查项目状态是否正常
if ($examItem->status !== 1) {
$messages[] = '项目已停用';
}
// 3. 检查项目是否需要预约
if ($examItem->need_appointment === 0) {
$messages[] = '无需预约';
return $messages;
}
// 4. 检查项目是否支持当前渠道预约
if ($examItem->enable_channel_mask !== null) {
if (($examItem->enable_channel_mask & $channelMask) === 0) {
$messages[] = '不支持此渠道预约';
return $messages;
}
}
// 5. 检查项目是否关联了资源
$resourceCount = DB::table('exam_item_resource')
->where('item_id', $examItem->id)
->where('deleted', 0)
->count();
if ($resourceCount === 0) {
$messages[] = '未关联资源';
}
return $messages;
}
/**
* 获取操作日志
*/
public function getOperationLogs(Request $request)
{
$applicationId = $request->input('application_id', 0);
if (empty($applicationId)) {
return Rs::error('医嘱ID不能为空');
}
$list = DB::table('operation_log')
->where('application_id', $applicationId)
->orderBy('operation_time', 'desc')
->orderBy('id', 'desc')
->get()
->map(function ($item) {
// 解析JSON字段
$item->old_values = $item->old_values ? json_decode($item->old_values, true) : null;
$item->new_values = $item->new_values ? json_decode($item->new_values, true) : null;
// 添加中文描述
$item->operator_type_name = $this->getOperatorTypeName($item->operator_type);
$item->operation_type_name = $this->getOperationTypeName($item->operation_type);
$item->entity_type_name = $this->getEntityTypeName($item->entity_type);
return $item;
});
return Rs::success($list);
}
/**
* 获取操作来源名称
*/
private function getOperatorTypeName($type)
{
$typeMap = [
1 => 'HIS系统',
2 => '预约系统',
3 => '管理员'
];
return $typeMap[$type] ?? '未知';
}
/**
* 获取操作类型名称
*/
private function getOperationTypeName($type)
{
$typeMap = [
1 => '创建',
2 => '更新',
3 => '作废',
4 => '取消'
];
return $typeMap[$type] ?? '未知';
}
/**
* 获取操作实体名称
*/
private function getEntityTypeName($type)
{
$typeMap = [
1 => '检查申请单',
2 => '预约记录'
];
return $typeMap[$type] ?? '未知';
}
/**
* 获取病区患者列表
*/
public function getWardPatientList(Request $request)
{
// 获取查询参数
$appointmentStatus = $request->input('appointment_status', null);
$bedNumber = $request->input('bed_number', '');
$patientName = $request->input('patient_name', '');
$page = $request->input('page', 1);
$pageSize = $request->input('page_size', 20);
// 获取当前用户信息
$sysUser = $this->userService->getUserInfoFromRequest($request);
if (!$sysUser) {
return Rs::error('用户不存在');
}
// 判断是否为管理员(从 JWT payload 中直接判断,无需额外查询)
$isAdmin = $this->userService->isAdminFromRequest($request);
// 构建查询:获取每个患者的最新检查申请记录
$subQuery = DB::table('exam_application as ea')
->select([
'ea.patient_id',
'ea.id',
'ea.bed_code',
'ea.inpatient_id',
'ea.patient_name',
'ea.patient_gender',
'ea.patient_age',
'ea.ward_code',
'ea.ward_name',
'ea.apply_department_name',
'ea.apply_doctor_name',
'ea.clinical_diagnosis',
'ea.status as appointment_status',
'ea.apply_time'
])
->whereIn('ea.id', function($query) {
$query->selectRaw('MAX(id)')
->from('exam_application')
->groupBy('patient_id');
});
// 非管理员只显示对应病区的患者,未绑定病区则拒绝
if (!$isAdmin) {
if (empty($sysUser->ward_code)) {
return Rs::error('用户未绑定病区,无法获取病区患者');
}
$subQuery->where('ea.ward_code', $sysUser->ward_code);
}
// 默认只查询住院患者patient_type = 2
$subQuery->where('ea.patient_type', 2);
// 添加筛选条件
if (!empty($bedNumber)) {
$subQuery->where('ea.bed_code', $bedNumber);
}
if (!empty($patientName)) {
$subQuery->where('ea.patient_name', 'like', '%' . $patientName . '%');
}
if ($appointmentStatus !== null) {
$subQuery->where('ea.status', $appointmentStatus);
}
// 计算总数
$total = $subQuery->count();
// 获取患者列表
$patients = $subQuery
->orderBy('ea.apply_time', 'desc')
->orderBy('ea.id', 'desc')
->skip(($page - 1) * $pageSize)
->take($pageSize)
->get();
// 获取所有患者ID
$patientIds = $patients->pluck('patient_id')->toArray();
// 查询每个患者的待预约数量 (status = 0)
$pendingCounts = [];
if (!empty($patientIds)) {
$pendingCounts = DB::table('exam_application')
->whereIn('patient_id', $patientIds)
->where('status', 0)
->selectRaw('patient_id, COUNT(*) as count')
->groupBy('patient_id')
->pluck('count', 'patient_id')
->toArray();
}
// 查询每个患者的今日检查数量
$today = date('Y-m-d');
$todayCheckCounts = [];
if (!empty($patientIds)) {
$todayCheckCounts = DB::table('exam_appointment')
->join('exam_application', 'exam_appointment.exam_application_id', '=', 'exam_application.id')
->whereIn('exam_application.patient_id', $patientIds)
->where('exam_appointment.status', 1) // 预约成功
->whereDate('exam_appointment.appointment_time', $today)
->selectRaw('exam_application.patient_id, COUNT(*) as count')
->groupBy('exam_application.patient_id')
->pluck('count', 'patient_id')
->toArray();
}
// 组装返回数据
$list = $patients->map(function ($patient) use ($pendingCounts, $todayCheckCounts) {
return [
'id' => $patient->patient_id,
'bed_number' => $patient->bed_code ?? '',
'inpatient_no' => $patient->inpatient_id ?? '',
'patient_name' => $patient->patient_name,
'gender' => $patient->patient_gender,
'age' => $patient->patient_age,
'ward_code' => $patient->ward_code,
'ward_name' => $patient->ward_name ?? '',
'department_name' => $patient->apply_department_name ?? '',
'attending_doctor' => $patient->apply_doctor_name ?? '',
'diagnosis' => $patient->clinical_diagnosis ?? '',
'pending_count' => $pendingCounts[$patient->patient_id] ?? 0,
'today_check_count' => $todayCheckCounts[$patient->patient_id] ?? 0,
'appointment_status' => $patient->appointment_status
];
});
return Rs::success([
'list' => $list,
'total' => $total,
'page' => $page,
'page_size' => $pageSize,
'total_pages' => ceil($total / $pageSize)
]);
}
/**
* 批量获取多个患者的待预约项目
*/
public function getBatchPatientExaminations(Request $request)
{
$patientIds = $request->input('patient_ids', []);
if (empty($patientIds) || !is_array($patientIds)) {
return Rs::error('患者ID列表不能为空');
}
// 限制一次最多查询100个患者
if (count($patientIds) > 100) {
return Rs::error('一次最多查询100个患者');
}
// 查询所有患者的待预约项目status = 0
$examinations = DB::table('exam_application')
->whereIn('patient_id', $patientIds)
->where('status', 0)
->select([
'patient_id',
'patient_name',
'patient_gender',
'patient_age',
'id',
'his_order_id',
'examination_item_name',
'examination_item_code',
'examination_department_name',
'examination_department_code',
'apply_doctor_name',
'apply_doctor_code',
'apply_department_name',
'apply_time',
'payment_status',
'clinical_diagnosis',
'notes'
])
->orderBy('patient_id')
->orderBy('apply_time', 'desc')
->get();
// 按患者ID分组
$groupedExaminations = [];
foreach ($examinations as $exam) {
if (!isset($groupedExaminations[$exam->patient_id])) {
$groupedExaminations[$exam->patient_id] = [];
}
$groupedExaminations[$exam->patient_id][] = (array)$exam;
}
return Rs::success($groupedExaminations);
}
public function getPatientPendingItems(Request $request)
{
$patientId = $request->input('patient_id', 0);
$channelId = $request->input('channel_id', 2);
if (empty($patientId)) {
return Rs::error('患者ID不能为空');
}
$applications = DB::table('exam_application')
->where('patient_id', $patientId)
->where('status', 0)
->select([
'id', 'his_order_id', 'patient_id', 'patient_name',
'examination_item_name', 'examination_item_code',
'examination_department_name', 'examination_department_code',
'apply_doctor_name', 'apply_department_name',
'apply_time', 'payment_status', 'status'
])
->orderBy('apply_time', 'desc')
->get();
if ($applications->isEmpty()) {
return Rs::success([
'items' => [],
'groups' => [],
'extra_his_order_ids' => []
]);
}
$itemCodes = $applications->pluck('examination_item_code')->unique()->toArray();
$examItems = DB::table('exam_item')
->whereIn('code', $itemCodes)
->where('deleted', 0)
->select('id', 'code', 'name', 'use_seats')
->get()
->keyBy('code');
$examItemIds = $examItems->pluck('id')->toArray();
$itemResources = DB::table('exam_item_resource')
->whereIn('item_id', $examItemIds)
->where('deleted', 0)
->select('item_id', 'resource_id')
->get();
$resourcesByItem = [];
foreach ($itemResources as $ir) {
$resourcesByItem[$ir->item_id][] = $ir->resource_id;
}
$resourcesInfo = [];
if (!empty($itemResources)) {
$resourceIds = $itemResources->pluck('resource_id')->unique()->toArray();
$resourcesInfo = DB::table('department_resource')
->whereIn('id', $resourceIds)
->pluck('name', 'id')
->toArray();
}
$groupMap = [];
foreach ($applications as $app) {
$examItem = $examItems->get($app->examination_item_code);
if (!$examItem) {
continue;
}
$itemId = $examItem->id;
$resourceIds = $resourcesByItem[$itemId] ?? [];
$groupMap[$app->id] = [
'application_id' => $app->id,
'his_order_id' => $app->his_order_id,
'item_name' => $app->examination_item_name,
'resource_ids' => $resourceIds,
];
}
$assignedGroups = [];
$appGroupIndex = [];
$groupIndex = 0;
foreach ($groupMap as $appId => $info) {
if (isset($appGroupIndex[$appId])) {
continue;
}
$groupApps = [$appId];
$groupResources = $info['resource_ids'];
foreach ($groupMap as $otherAppId => $otherInfo) {
if ($otherAppId === $appId || isset($appGroupIndex[$otherAppId])) {
continue;
}
$intersection = array_intersect($groupResources, $otherInfo['resource_ids']);
if (!empty($intersection)) {
$groupApps[] = $otherAppId;
$groupResources = $intersection;
$appGroupIndex[$otherAppId] = $groupIndex;
}
}
$appGroupIndex[$appId] = $groupIndex;
$primaryResourceId = !empty($groupResources) ? array_values($groupResources)[0] : null;
$assignedGroups[$groupIndex] = [
'resource_id' => $primaryResourceId,
'resource_name' => $primaryResourceId ? ($resourcesInfo[$primaryResourceId] ?? '未知') : '未知',
'application_ids' => [],
'his_order_ids' => [],
'items' => []
];
foreach ($groupApps as $gAppId) {
$gInfo = $groupMap[$gAppId];
$assignedGroups[$groupIndex]['application_ids'][] = $gAppId;
$assignedGroups[$groupIndex]['his_order_ids'][] = $gInfo['his_order_id'];
$assignedGroups[$groupIndex]['items'][] = [
'application_id' => $gAppId,
'his_order_id' => $gInfo['his_order_id'],
'item_name' => $gInfo['item_name']
];
}
$groupIndex++;
}
$groups = array_values($assignedGroups);
$currentHisOrderIds = $request->input('current_his_order_ids', []);
$allHisOrderIds = $applications->pluck('his_order_id')->toArray();
$extraHisOrderIds = array_values(array_diff($allHisOrderIds, $currentHisOrderIds));
return Rs::success([
'items' => $applications,
'groups' => $groups,
'extra_his_order_ids' => $extraHisOrderIds
]);
}
}