hasPagePermission()) { return $this->fail('权限不足,无法访问我的患者'); } return $this->dataLists(new MyPatientLists()); } /** 当前角色/部门患者范围内的处方业务订单。 */ public function orders() { if (!$this->hasPagePermission()) { return $this->fail('权限不足,无法查看患者订单'); } return $this->dataLists(new MyPatientOrderLists()); } /** 当前角色/部门患者范围内的挂号面诊进度。 */ public function progress() { if (!$this->hasPagePermission()) { return $this->fail('权限不足,无法查看面诊进度'); } return $this->dataLists(new MyPatientProgressLists()); } /** 当前患者范围内的订单详情;仍要求原订单详情权限。 */ public function orderDetail() { $params = (new PrescriptionOrderValidate())->get()->goCheck('detail'); if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/detail') === null) { return $this->fail($this->orderGuardError); } $detail = PrescriptionOrderLogic::detail((int) $params['id'], $this->adminId, $this->adminInfo); if ($detail === null) { return $this->fail(PrescriptionOrderLogic::getError()); } return $this->data($detail); } /** 编辑当前患者范围内的订单,参数只允许原编辑表单支持的字段。 */ public function orderEdit() { $params = (new PrescriptionOrderValidate())->post()->goCheck('edit'); if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/edit') === null) { return $this->fail($this->orderGuardError); } if ((float) ($params['amount'] ?? 0) < 0) { return $this->fail('订单金额不能为负数'); } $params = $this->onlyParams($params, [ 'id', 'recipient_name', 'recipient_phone', 'shipping_province', 'shipping_city', 'shipping_district', 'shipping_address', 'is_follow_up', 'medication_days', 'dose_unit', 'dose_count', 'prev_staff', 'service_channel', 'service_package', 'tracking_number', 'express_company', 'fee_type', 'amount', 'remark_extra', 'remark_assistant', 'pay_order_ids', 'internal_cost', ]); $result = PrescriptionOrderLogic::edit($params, $this->adminId, $this->adminInfo); if ($result === false) { return $this->fail(PrescriptionOrderLogic::getError()); } return $this->success('保存成功', $result); } public function orderAuditPrescription() { $params = (new PrescriptionOrderValidate())->post()->goCheck('auditPrescription'); if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/auditPrescription') === null) { return $this->fail($this->orderGuardError); } $result = PrescriptionOrderLogic::auditPrescription( (int) $params['id'], (string) $params['action'], (string) ($params['remark'] ?? ''), $this->adminId, $this->adminInfo ); if ($result === false) { return $this->fail(PrescriptionOrderLogic::getError()); } return $this->success('操作成功', $result); } public function orderRevokeRxAudit() { $params = (new PrescriptionOrderValidate())->post()->goCheck('detail'); if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/auditPrescription') === null) { return $this->fail($this->orderGuardError); } $result = PrescriptionOrderLogic::revokeRxAudit((int) $params['id'], $this->adminId, $this->adminInfo); if ($result === false) { return $this->fail(PrescriptionOrderLogic::getError()); } return $this->success('处方审核已撤回', $result); } public function orderAuditPayment() { $params = (new PrescriptionOrderValidate())->post()->goCheck('auditPayment'); if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/auditPayment') === null) { return $this->fail($this->orderGuardError); } $result = PrescriptionOrderLogic::auditPaymentSlip( (int) $params['id'], (string) $params['action'], (string) ($params['remark'] ?? ''), $this->adminId, $this->adminInfo ); if ($result === false) { return $this->fail(PrescriptionOrderLogic::getError()); } return $this->success('操作成功', $result); } public function orderRevokePayAudit() { $params = (new PrescriptionOrderValidate())->post()->goCheck('detail'); if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/auditPayment') === null) { return $this->fail($this->orderGuardError); } $result = PrescriptionOrderLogic::revokePayAudit((int) $params['id'], $this->adminId, $this->adminInfo); if ($result === false) { return $this->fail(PrescriptionOrderLogic::getError()); } return $this->success('支付单审核已撤回', $result); } public function orderDdcode() { $params = (new PrescriptionOrderValidate())->post()->goCheck('ddcode'); if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/ddcode') === null) { return $this->fail($this->orderGuardError); } $result = PrescriptionOrderLogic::ddcode( (int) $params['id'], (string) ($params['express_company'] ?? 'auto'), (string) $params['tracking_number'], $this->adminId, $this->adminInfo ); if ($result === false) { return $this->fail(PrescriptionOrderLogic::getError()); } return $this->success('快递单号已保存', $result); } public function orderShip() { $params = (new PrescriptionOrderValidate())->post()->goCheck('ship'); if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/ship') === null) { return $this->fail($this->orderGuardError); } $result = PrescriptionOrderLogic::ship( (int) $params['id'], (string) ($params['express_company'] ?? 'auto'), (string) ($params['tracking_number'] ?? ''), (string) ($params['ship_mode'] ?? 'gancao'), $this->adminId, $this->adminInfo ); if ($result === false) { return $this->fail(PrescriptionOrderLogic::getError()); } return $this->success('发货成功', $result); } public function orderAddPayOrder() { $params = (new PrescriptionOrderValidate())->post()->goCheck('addPayOrder'); if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/addPayOrder') === null) { return $this->fail($this->orderGuardError); } $params = $this->onlyParams($params, [ 'id', 'order_type', 'pay_amount', 'pay_remark', 'completion_request', 'pay_create_type', ]); $result = PrescriptionOrderLogic::addPayOrder($params, $this->adminId, $this->adminInfo); if ($result === false) { return $this->fail(PrescriptionOrderLogic::getError()); } return $this->success('新增支付单成功', $result); } public function orderComplete() { $params = (new PrescriptionOrderValidate())->post()->goCheck('complete'); if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/complete') === null) { return $this->fail($this->orderGuardError); } $result = PrescriptionOrderLogic::complete( (int) $params['id'], $this->adminId, $this->adminInfo, (int) $params['fulfillment_status'] ); if ($result === false) { return $this->fail(PrescriptionOrderLogic::getError()); } return $this->success('操作成功', $result); } public function orderRefund() { $params = (new PrescriptionOrderValidate())->post()->goCheck('refund'); if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/refund') === null) { return $this->fail($this->orderGuardError); } $rawRefundAmount = $params['refund_amount'] ?? null; $refundAmount = ($rawRefundAmount === null || $rawRefundAmount === '') ? null : round((float) $rawRefundAmount, 2); $result = PrescriptionOrderLogic::refund( (int) $params['id'], (string) ($params['reason'] ?? ''), $this->adminId, $this->adminInfo, $refundAmount ); if ($result === false) { return $this->fail(PrescriptionOrderLogic::getError()); } return $this->success('退款成功', $result); } public function orderWithdraw() { $params = (new PrescriptionOrderValidate())->post()->goCheck('withdraw'); if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/withdraw') === null) { return $this->fail($this->orderGuardError); } $result = PrescriptionOrderLogic::withdraw((int) $params['id'], $this->adminId, $this->adminInfo); if ($result === false) { return $this->fail(PrescriptionOrderLogic::getError()); } return $this->success('已撤回', $result); } public function orderUploadToPharmacy() { $params = (new PrescriptionOrderValidate())->post()->goCheck('uploadToPharmacy'); if ($this->guardOrder((int) $params['id'], 'tcm.prescriptionOrder/uploadToPharmacy') === null) { return $this->fail($this->orderGuardError); } $result = PrescriptionOrderLogic::uploadToPharmacy((int) $params['id'], $this->adminId, $this->adminInfo); if ($result === false) { return $this->fail(PrescriptionOrderLogic::getError()); } return $this->success('药方上传成功', $result); } /** 从“我的患者”页面创建挂号,写操作复用原逻辑但先做患者行级校验。 */ public function createAppointment() { if (!$this->hasPagePermission()) { return $this->fail('权限不足,无法创建挂号'); } $params = (new AppointmentValidate())->post()->goCheck('create'); $diagnosisId = (int) ($params['patient_id'] ?? 0); if (!MyPatientLogic::canAccessDiagnosis($diagnosisId, $this->adminId, $this->adminInfo)) { return $this->fail('患者不存在或无权操作'); } $params['assistant_id'] = $this->adminId; $result = AppointmentLogic::create($params, $this->adminId, $this->adminInfo); if ($result === false) { return $this->fail(AppointmentLogic::getError()); } return $this->success('挂号成功', $result); } /** 从“我的患者”页面取消挂号,按挂号所属诊单再次校验数据范围。 */ public function cancelAppointment() { if (!$this->hasPagePermission()) { return $this->fail('权限不足,无法取消挂号'); } $params = (new AppointmentValidate())->post()->goCheck('cancel'); $appointment = Appointment::findOrEmpty((int) ($params['id'] ?? 0)); if ($appointment->isEmpty()) { return $this->fail('挂号记录不存在'); } if (!MyPatientLogic::canAccessDiagnosis((int) $appointment->patient_id, $this->adminId, $this->adminInfo)) { return $this->fail('患者不存在或无权操作'); } $result = AppointmentLogic::cancel($params, $this->adminId, $this->adminInfo); if ($result === false) { return $this->fail(AppointmentLogic::getError()); } return $this->success('取消挂号成功'); } private function hasPagePermission(): bool { if ((int) ($this->adminInfo['root'] ?? 0) === 1) { return true; } return in_array(self::LIST_PERMISSION, AuthLogic::getAuthByAdminId($this->adminId), true); } private function hasOriginalPermission(string $permission): bool { if ((int) ($this->adminInfo['root'] ?? 0) === 1) { return true; } return in_array($permission, AuthLogic::getAuthByAdminId($this->adminId), true); } private function guardOrder(int $orderId, string $permission): ?PrescriptionOrder { $this->orderGuardError = '订单不存在或无权操作'; if (!$this->hasPagePermission() || !$this->hasOriginalPermission($permission) || $orderId <= 0) { return null; } $order = PrescriptionOrder::where('id', $orderId)->whereNull('delete_time')->find(); if ($order === null) { return null; } if (!MyPatientLogic::canAccessDiagnosis((int) $order->diagnosis_id, $this->adminId, $this->adminInfo)) { return null; } return $order; } /** @param array $params @param array $keys */ private function onlyParams(array $params, array $keys): array { return array_intersect_key($params, array_flip($keys)); } }