*/ protected $fillable = [ 'relate_id', 'order_id', 'his_order_id', 'transaction_id', 'status', 'notify_status', 'type', 'pay_type', 'pay_mode', 'fee', 'self_fee', 'reduce_fee', 'refund_fee', 'open_id', 'patient_id', 'patient_name', 'source_id', 'payment_at', 'refunded_at', ]; /** * The attributes that should be cast. * * @var array */ protected $casts = [ 'id' => 'integer', 'relate_id' => 'integer', 'status' => 'integer', 'type' => 'integer', 'pay_type' => 'integer', 'pay_mode' => 'integer', 'fee' => 'integer', 'self_fee' => 'integer', 'reduce_fee' => 'integer', 'refund_fee' => 'integer', 'source_id' => 'integer', 'payment_at' => 'datetime', 'refunded_at' => 'datetime', ]; /** * Relationships Patient. */ public function patient(): belongsTo { return $this->belongsTo(Patient::class, 'patient_id', 'patient_id'); } /** * Relationships Self Order. */ public function order(): HasMany { return $this->hasMany(__CLASS__, 'relate_id'); } /** * Relationships RegistrationRecord Model. * @return HasOne */ public function registrationRecord(): HasOne { return $this->hasOne(RegistrationRecord::class, 'relate_order_id'); } /** * Relationships OutpatientPaymentRecord Model. * @return hasMany */ public function outpatientPaymentRecord(): hasMany { return $this->hasMany(OutpatientPaymentRecord::class, 'relate_order_id'); } /** * 获取订单ID * @param PayType $pay_type 支付类型 * @param string $user W 微信 D 大机器 X 小机器 H his * @return string */ public function getOrderId(PayType $pay_type, string $user = 'D'): string { $order_id = $pay_type->order(). $user. date('YmdHis'). mt_rand(100, 999); if ($this->where('order_id', $order_id)->first()) { return $this->getOrderId($pay_type, $user); } return $order_id; } /** * 获取退款订单ID * @param string $order_id 原订单ID * @param string $source_flag 退款来源标志 _ 程序自动冲正 R 人工退费 H His退款 * @return string */ public function getRefundOrderId(string $order_id, string $source_flag = '_'): string { $refund_order_id = $order_id. $source_flag. mt_rand(100, 999); if ($this->where('order_id', $refund_order_id)->first()) { return $this->getRefundOrderId($order_id); } return $refund_order_id; } /** * 获取订单详情by id * @param string $id * @return mixed */ public function getOrderInfoById(string $id): mixed { return $this->where('id', $id)->with('patient')->first(); } /** * 获取订单详情by order_id * @param string $order_id * @return mixed */ public function getOrderInfoByOrderId(string $order_id): mixed { return $this->where('order_id', $order_id)->with('patient')->first(); } /** * 创建订单 * @param string $order_id * @param PayType $pay_type * @param float $fee * @param float $reduce_fee * @param string $open_id * @param string $patient_id * @param string $patient_name * @param Type $order_type * @param SourceId $source_id * @param array $record_info * @return mixed */ public function createOrder(string $order_id, PayType $pay_type, float $fee, float $reduce_fee, string $open_id, string $patient_id, string $patient_name, Type $order_type, SourceId $source_id, array $record_info = []): mixed { $order_info = [ 'relate_id' => 0, 'order_id' => $order_id, 'his_order_id' => '', 'transaction_id' => '', 'status' => Status::NORMAL->value, 'notify_status' => NotifyStatus::NO_ACCEPTED->value, 'type' => $order_type->value, 'pay_type' => $pay_type, 'pay_mode' => PayMode::PAYMENT->value, 'fee' => $fee, //分 'reduce_fee' => $reduce_fee, //分 'self_fee' => $fee - $reduce_fee, //分 'refund_fee' => 0, 'open_id' => $open_id, 'patient_id' => $patient_id, 'patient_name' => $patient_name, 'source_id' => $source_id, ]; // 操作订单记录进行创建操作 if (in_array($order_type->value, [ Type::TODAY_REGISTRATION->value, Type::APPOINTMENT_REGISTRATION->value, Type::OUTPATIENT_PAYMENT->value ])) { $result = $this->create($order_info); if (!empty($result) && !empty($record_info)) { switch ($order_type->value) { case Type::TODAY_REGISTRATION->value: case Type::APPOINTMENT_REGISTRATION->value: $result->registrationRecord()->create($record_info); break; case Type::OUTPATIENT_PAYMENT->value: $result->outpatientPaymentRecord()->createMany($record_info); break; default: break; } } return $result; } return $this->create($order_info); } /** * 创建退费/冲正订单 * @param int $relate_order_id * @param string $order_id * @param PayType $pay_type * @param float $fee * @param string $open_id * @param string $patient_id * @param string $patient_name * @param Type $order_type * @param SourceId $source_id * @return mixed */ public function createRefundOReverseOrder(int $relate_order_id, string $order_id, PayType $pay_type, float $fee, string $open_id, string $patient_id, string $patient_name, Type $order_type, SourceId $source_id): mixed { $order_info = [ 'relate_id' => $relate_order_id, 'order_id' => $order_id, 'his_order_id' => '', 'transaction_id' => '', 'status' => Status::NORMAL->value, 'notify_status' => NotifyStatus::NO_ACCEPTED->value, 'type' => $order_type, 'pay_type' => $pay_type, 'pay_mode' => PayMode::REFUND->value, 'fee' => $fee, //分 'reduce_fee' => 0, //分 'self_fee' => 0, //分 'refund_fee' => 0, 'open_id' => $open_id, 'patient_id' => $patient_id, 'patient_name' => $patient_name, 'source_id' => $source_id, ]; return $this->create($order_info); } /** * 订单确认 * @param string $order_id * @param string $his_order_id * @param array $response */ public function orderConfirm(string $order_id, string $his_order_id = '', array $response = []): void { $order = $this->where('order_id', $order_id)->first(); !empty($his_order_id) && $order->his_order_id = $his_order_id; $order->status = Status::SUCCESS->value; $order->save(); if (in_array($order->type, [Type::TODAY_REGISTRATION->value, Type::APPOINTMENT_REGISTRATION->value, Type::OUTPATIENT_PAYMENT->value]) && !empty($response)) { switch ($order->type) { case Type::TODAY_REGISTRATION->value: case Type::APPOINTMENT_REGISTRATION->value: $record = $order->registrationRecord; $extra_info = json_decode($record->extra_info, true); $extra_info['confirm_response'] = $response; $record->update(['extra_info' => json_encode($extra_info, JSON_UNESCAPED_UNICODE)]); break; case Type::OUTPATIENT_PAYMENT->value: $record = $order->outpatientPaymentRecord; $extra_info = json_decode($record->extra_info, true); $extra_info['confirm_response'] = $response; foreach ($record as $v) { $v->update(['extra_info' => json_encode($extra_info, JSON_UNESCAPED_UNICODE)]); } break; default: break; } } } /** * 修改订单状态 * @param string $order_id * @param Status $status */ public function changeOrderStatus(string $order_id, Status $status): void { $order = $this->where('order_id', $order_id)->first(); $order->status = $status; $order->save(); } /** * 订单异常(用户交钱成功,his业务确认异常 * @param string $order_id */ public function abnormalOrderOpera(string $order_id): void { $order = $this->where('order_id', $order_id)->first(); $order->status = Status::ABNORMAL->value; $order->save(); } /** * 订单冲正(用户交钱成功,his业务确认失败) * @param string $order_id * @param float $refund_fee 此处是元 * @param bool $is_success 退款是否成功 */ public function reverseOrderOpera(string $order_id, float $refund_fee, bool $is_success): void { $r_order = $this->where('order_id', $order_id)->first(); //原订单 if ($is_success) { $order = $this->where('id', $r_order->relate_id)->first(); $order->refund_fee += $refund_fee * 100; $order->status = Status::REVERSE->value; $order->save(); } // 保存退费/冲正订单 $r_order->status = $is_success ? Status::SUCCESS->value : Status::FAILURE->value; $r_order->refunded_at = date('Y-m-d H:i:s'); $r_order->save(); } /** * 挂号订单解锁 * @param string $order_id * @return void */ public function regOrderUnlock(string $order_id): void { $order = $this->where('order_id', $order_id)->with('registrationRecord')->first(); $order->registrationRecord->lock_status = 2; $order->registrationRecord->unlock_at = date('Y-m-d H:i:s'); $order->registrationRecord->save(); $order->status = Status::FAILURE->value; $order->save(); } /** * 订单取消预结算 * @param string $order_id * @return void */ public function outpatientOderCancelPreSettle(string $order_id): void { $order = $this->where('order_id', $order_id)->with('outpatientPaymentRecord')->first(); $order->outpatientPaymentRecord->pre_settle_status = 2; $order->outpatientPaymentRecord->cancel_pre_settle_at = date('Y-m-d H:i:s'); $order->outpatientPaymentRecord->save(); $order->status = Status::FAILURE->value; $order->save(); } }