with([ "factors" => function ($query) { $query->select("id", "name", "product_id")->orderBy("myindex") ->with(["factorItems" => function ($query) { $query->select("id", "name", "factor_id")->orderBy("myindex"); }]); }]) ->where("project_id", $id) ->select("id", "name", "project_id") ->orderBy("myindex") ->first(); $product->min_price = (new ProductItems())->where("product_id", $product->id)->min("price"); $max_price = (new ProductItems())->where("product_id", $product->id)->max("price"); $max_paramedic_price = (new ProductParamedicLevel())->where("product_id", $product->id)->max("price"); $max_factor_total = DB::select(DB::raw("select * from (select sum(max_price) as max_total,product_id from (select max(price) as max_price,product.id as product_id from product inner join factor on factor.product_id = product.id inner join factor_items on factor.id = factor_items.factor_id group by factor_items.factor_id) as a group by a.product_id) as b left join product on product.id = b.product_id where product.id=" . $product->id)); $product->max_price = ($max_price + $max_paramedic_price + $max_factor_total[0]->max_total); return response()->json($product->toArray()); } /** * @OA\Get( * path="/customer/get-areas-by-project/{id}", * tags={"用户端订单处理"}, * summary="V2-获取医院病区", * description="获取医院病区", * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Parameter(name="id", in="path", @OA\Schema(type="integer"), required=true, description="project id"), * @OA\Response( * response="200", * description="获取医院床位" * ) * ) */ public function getAreasByProject($id) { $buildings = (new Building())->where("project_id", $id)->with(["areas" => function ($query) { $query->select("id", "building_id", "name", "myindex")->orderBy("myindex"); }])->select("id", "project_id", "name", "myindex")->orderBy("myindex")->get(); return response()->json($buildings->toArray()); } /** * @OA\Get( * path="/customer/get-beds-by-area/{id}", * tags={"用户端订单处理"}, * summary="V2-根据病区获取病床", * description="根据病区获取病床", * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Parameter(name="id", in="path", @OA\Schema(type="integer"), required=true, description="area id"), * @OA\Response( * response="200", * description="根据病区获取病床" * ) * ) */ public function getBedsByArea($id) { $area = (new Area())->with(["beds" => function ($query) { $query->with(["room" => function ($query) { $query->select("id", "name"); }])->select("id", "name", "area_id", "room_id"); }])->find($id); return response()->json($area->beds->toArray()); } /** * @OA\Get( * path="/customer/get-available-paramedics", * tags={"用户端订单处理"}, * summary="V2-获取可用护工列表(已基本准确,需进一步打磨)", * description="获取可用护工列表", * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Parameter(name="bed_id", in="query", @OA\Schema(type="integer"), required=true, description="床位ID"), * @OA\Parameter(name="sex", in="query", @OA\Schema(type="string"), required=true, description="性别:[男/女]"), * @OA\Parameter(name="start_date", in="query", @OA\Schema(type="string"), required=false, description="日期,默认为当天"), * @OA\Parameter(name="factors", in="query", @OA\Schema(type="object"), required=true, description="价格因子选择,[{id:1,factor_item_id:1},{...}],如果为空数组请传[]"), * @OA\Response( * response="200", * description="获取可用护工列表" * ) * ) */ public function getAvailableParamedics(Request $request) { $paramedics = (new Orders())->getAvailableParamedics(); return response()->json($paramedics); } /** * @OA\Get( * path="/customer/get-patients", * tags={"用户端订单处理"}, * summary="获取被护理人列表", * description="获取被护理人列表", * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Response( * response="200", * description="获取被护理人列表" * ) * ) */ public function getPatients() { $patients = $this->customer->patients; return response()->json($patients); } /** * @OA\POST( * path="/customer/create-patient", * tags={"用户端订单处理"}, * summary="创建被护理人", * description="创建被护理人", * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Parameter(name="name", in="query", @OA\Schema(type="string"), required=true, description="姓名"), * @OA\Parameter(name="sex", in="query", @OA\Schema(type="string"), required=true, description="性别:[男/女]"), * @OA\Parameter(name="age", in="query", @OA\Schema(type="integer"), required=true, description="年龄,只需填写入院时的年龄"), * @OA\Response( * response="200", * description="创建被护理人" * ) * ) */ public function createPatient() { $data = [ "customer_id" => $this->customer->id, "name" => request()->name, "sex" => request()->sex, "age" => request()->age ]; $vo = (new Patient())->create($data); return response()->json($vo); } /** * @OA\Get( * path="/customer/get-orders", * tags={"用户端订单处理"}, * summary="V2-获取订单列表", * description="获取订单列表", * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Parameter(name="keyword", in="query", @OA\Schema(type="string"), required=false, description="查询关键词"), * @OA\Parameter(name="page", in="query", @OA\Schema(type="integer"), required=false, description="当前页码,默认为1"), * @OA\Parameter(name="page_size", in="query", @OA\Schema(type="integer"), required=false, description="每页数量,默认为5"), * @OA\Parameter(name="status", in="query", @OA\Schema(type="string"), required=false, description="订单状态:[unconfirmed=>待确认,unassigned=>待派单,ongoing=>进行中,finished=>已完成]"), * @OA\Response( * response="200", * description="获取订单列表" * ) * ) */ public function list() { $data = (new Orders())->ofCustomer($this->customer->id); //$data = new Orders(); if (request()->keyword) { $keyword = request()->keyword; $data = $data->where(function ($query) use ($keyword) { $query ->where("serial", "like", "%{$keyword}%") ->orWhereHas("patient", function ($query) use ($keyword) { $query->where("name", "like", "%{$keyword}%"); })->orWhereHas("paramedic", function ($query) use ($keyword) { $query->where("name", "like", "%{$keyword}%"); }); }); } try { $status = "STATUS_" . strtoupper(request()->status); $data = $data->where("status", constant(Orders::class . "::{$status}")); } catch (\Exception $exception) { // } $page_size = request()->page_size ? (int)request()->page_size : 5; $data = $data->with([ "customer", "project", "product", "patient", "productItem", "building", "bed" => function ($query) { $query->with(["room", "building"]); }, "paramedic" ])->paginate($page_size); foreach ($data as $order) { $order = $order->refreshTotal(); } return response()->json($data->toArray()); } /** * @OA\Get( * path="/customer/get-order/{id}", * tags={"用户端订单处理"}, * summary="V2-获取订单详情", * description="获取订单详情", * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Parameter(name="id", in="path", @OA\Schema(type="integer"), required=true, description="id"), * @OA\Response( * response="200", * description="获取订单详情" * ) * ) */ public function getOrder($id) { $order = (new Orders())->with([ "orderItems" => function ($query) { $query->with(["bed", "paramedic", "productParamedicLevel", "paramedicLevel"]); }, "project", "product", "customer", "manager", "patient", "productItem", "productParamedicLevel", "paramedicLevel", "bed" => function ($query) { $query->with(["room", "building"]); }, "paramedic" ])->find($id); $order = $order->refreshTotal(); $order->balance = $order->customer->balance; return response()->json($order->toArray()); } /** * @OA\Get( * path="/customer/get-project-paramedics/{project_id}", * tags={"用户端订单处理"}, * summary="V2-获取护工列表", * description="获取护工列表", * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Parameter(name="project_id", in="path", @OA\Schema(type="integer"), required=true, description="project_id"), * @OA\Parameter(name="order_by", in="query", @OA\Schema(type="string"), required=false, description="排序方式:age|work_years|stars(暂不支持)"), * @OA\Parameter(name="asc_or_desc", in="query", @OA\Schema(type="string"), required=false, description="升序或降序,默认升序asc"), * @OA\Parameter(name="page", in="query", @OA\Schema(type="integer"), required=false, description="当前页码,默认为1"), * @OA\Parameter(name="page_size", in="query", @OA\Schema(type="integer"), required=false, description="每页数量,默认为5"), * @OA\Response( * response="200", * description="获取护工列表" * ) * ) */ public function getProjectParamedics($project_id) { $model = new Paramedic(); $model = $model->ofProject($project_id); $model = $model->where("status", 1); $model = $model->with(["project", "levelInProject"]); $model = $model->withCount(["orders"]); $model = $model->select("id", "name", "avatar", "sex", "birthday", "hometown", "work_years", "paramedic_level_id", "project_id"); $asc_or_desc = request()->asc_or_desc == "desc" ? "desc" : "asc"; switch (request()->order_by) { case "age": $order_by = "birthday"; $asc_or_desc = $asc_or_desc == "desc" ? "asc" : "desc"; break; case "work_years": $order_by = "work_years"; break; default: $order_by = "id"; } $page_size = request()->page_size ?? 5; $paramedics = $model->orderBy($order_by, $asc_or_desc)->paginate($page_size); return response()->json($paramedics ? $paramedics->toArray() : null); } /** * @OA\Get( * path="/customer/get-paramedic/{id}", * tags={"用户端订单处理"}, * summary="V2-获取护工详情", * description="获取护工详情", * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Parameter(name="id", in="path", @OA\Schema(type="integer"), required=true, description="id"), * @OA\Response( * response="200", * description="获取护工详情" * ) * ) */ public function getParamedic($id) { $paramedic = (new Paramedic())->with(["level", "project"])->find($id); return response()->json($paramedic ? $paramedic->toArray() : null); } /** * @OA\POST( * path="/customer/create-order", * tags={"用户端订单处理"}, * summary="V2-创建订单", * description="创建订单", * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Parameter(name="product_id", in="query", @OA\Schema(type="integer"), required=true, description="产品id"), * @OA\Parameter(name="factors", in="query", @OA\Schema(type="object"), required=true, description="价格因子选择,[{id:1,factor_item_id:1},{...}],如果为空数组请传[]"), * @OA\Parameter(name="bed_id", in="query", @OA\Schema(type="integer"), required=true, description="床位id"), * @OA\Parameter(name="paramedic_id", in="query", @OA\Schema(type="integer"), required=false, description="护工id"), * @OA\Parameter(name="patient_name", in="query", @OA\Schema(type="integer"), required=true, description="被看护人姓名"), * @OA\Parameter(name="patient_sex", in="query", @OA\Schema(type="integer"), required=true, description="被看护人性别"), * @OA\Parameter(name="from_date", in="query", @OA\Schema(type="string"), required=true, description="开始日期"), * @OA\Parameter(name="to_date", in="query", @OA\Schema(type="string"), required=true, description="结束日期"), * @OA\Parameter(name="contact", in="query", @OA\Schema(type="string"), required=false, description="家属姓名"), * @OA\Parameter(name="mobile", in="query", @OA\Schema(type="string"), required=false, description="家属电话"), * @OA\Response( * response="200", * description="创建订单" * ) * ) */ public function createOrder() { DB::beginTransaction(); try { $has_orders = Orders::where("customer_id", $this->customer->id)->whereIn("status", [Orders::STATUS_UNCONFIRMED, Orders::STATUS_UNASSIGNED, Orders::STATUS_ONGOING])->count(); if ($has_orders) { return response()->json([ "errorcode" => "0", "errormsg" => "您有即将开始或正在进行中的订单,暂不可以再次下单" ]); } $request = request(); $product = Product::find($request->product_id); if ($request->paramedic_id) { $paramedic = Paramedic::withCount(["orders" => function ($query) use ($request) { $query->where("status", Orders::STATUS_ONGOING); //todo:计算自动结单对当前所选日期的订单数的影响 }])->find($request->paramedic_id); $product_paramedic_level = (new ProductParamedicLevel())->where("paramedic_level_id", $paramedic->paramedic_level_id)->first(); $product_item = (new ProductItems())->where("patient_quantity", "<=", $paramedic->orders_count + 1)->orderBy("patient_quantity", "desc")->first(); } else { $product_paramedic_level = (new ProductParamedicLevel())->where("product_id", $request->product_id)->where("price", 0)->first(); $product_item = (new ProductItems())->where("product_id", $request->product_id)->where("patient_quantity", 1)->first(); } $price = $product_item->price + $product_paramedic_level->price; $factors = (new Orders())->requestFactorsToOrderFactors(); $price += collect($factors)->sum("price"); $patient = Patient::firstOrCreate([ "customer_id" => $this->customer->id, "name" => $request->patient_name, "sex" => $request->patient_sex ]); $order = (new Orders())->create([ "customer_id" => $this->customer->id, "project_id" => $product->project_id, "product_id" => $request->product_id, "patient_id" => $patient->id, "contact" => $request->contact, "mobile" => $request->mobile, "from_date" => $request->from_date, "to_date" => $request->to_date, "product_item_id" => $product_item->id, "product_paramedic_level_id" => $product_paramedic_level->id, "bed_id" => $request->bed_id, "paramedic_id" => $request->paramedic_id, "price" => $price, "factors" => json_encode($factors) ]); $order->getSerial(); DB::commit(); return $this->getOrder($order->id); } catch (\Exception $exception) { DB::rollBack(); return response()->json([ "errorcode" => $exception->getCode(), "errormsg" => $exception->getMessage() ]); } } /** * @OA\POST( * path="/customer/reserve-order/{id}", * tags={"用户端订单处理"}, * summary="预约/取消预约护工", * description="预约/取消预约护工", * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Parameter(name="id", in="path", @OA\Schema(type="integer"), required=true, description="订单id"), * @OA\Parameter(name="paramedic_id", in="query", @OA\Schema(type="integer"), required=false, description="预约的护工id,为空表示取消预约护工,恢复等待管理老师安排"), * @OA\Response( * response="200", * description="预约/取消预约护工" * ) * ) */ public function reserveOrder($id) { $order = (new Orders())->with("orderItems")->find($id); if ($order->status !== Orders::STATUS_UNCONFIRMED && $order->status !== Orders::STATUS_UNASSIGNED) { return response()->json([ "errorcode" => 50001, "errormsg" => "订单状态不适配" ]); } if (Carbon::parse(date("Y-m-d"))->greaterThanOrEqualTo($order->from_date)) { return response()->json([ "errorcode" => 50002, "errormsg" => "开始服务日需晚于当前日期才可以进行预约。请联系管理老师或取消订单" ]); } DB::beginTransaction(); try { $order->update([ "paramedic_id" => request()->paramedic_id ]); DB::commit(); return response()->json($order); } catch (\Exception $exception) { DB::rollBack(); return response()->json([ "errorcode" => $exception->getCode(), "errormsg" => $exception->getMessage() ]); } } /** * @OA\POST( * path="/customer/cancel-order/{id}", * tags={"用户端订单处理"}, * summary="V2-取消订单", * description="取消订单", * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Parameter(name="id", in="path", @OA\Schema(type="integer"), required=true, description="订单id"), * @OA\Response( * response="200", * description="取消订单" * ) * ) */ public function cancelOrder($id) { $order = (new Orders())->with("orderItems")->find($id); if ($order->status !== Orders::STATUS_UNCONFIRMED) { return response()->json([ "errorcode" => 50001, "errormsg" => "订单状态不适配" ]); } DB::beginTransaction(); try { foreach ($order->orderItems as $orderItem) { $orderItem->delete(); } $order->delete(); DB::commit(); return response()->json($order); } catch (\Exception $exception) { DB::rollBack(); return response()->json([ "errorcode" => $exception->getCode(), "errormsg" => $exception->getMessage() ]); } } /** * @OA\Get( * path="/customer/get-reservable-paramedics/{order_id}", * tags={"用户端订单处理"}, * summary="获取可预约的护工", * description="获取可预约的护工", * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Parameter(name="order_id", in="path", @OA\Schema(type="integer"), required=false, description="订单id"), * @OA\Response( * response="200", * description="获取可预约的护工" * ) * ) */ public function getReservableParamedics($order_id) { $order = (new Orders())->find($order_id); if ($order->status !== Orders::STATUS_UNCONFIRMED && $order->status !== Orders::STATUS_UNASSIGNED) { return response()->json([ "errorcode" => 50001, "errormsg" => "订单状态不适配" ]); } if (Carbon::parse(date("Y-m-d"))->greaterThanOrEqualTo($order->from_date)) { return response()->json([ "errorcode" => 50002, "errormsg" => "开始服务日需晚于当前日期才可以进行预约。请联系管理老师或取消订单" ]); } $paramedics = (new Paramedic()) ->where("status", Paramedic::STATUS_ACTIVE) ->where("project_id", $order->project_id) ->whereDoesntHave("orders", function ($query) use ($order) { //订单正在进行,或者未确认|未派单 $query->whereIn("status", [Orders::STATUS_UNCONFIRMED, Orders::STATUS_UNASSIGNED, Orders::STATUS_ONGOING]); })->paginate(10); return response()->json($paramedics->toArray()); } /** * @OA\Get( * path="/customer/recharge", * tags={"用户端订单处理"}, * summary="V2-获取充值接口信息", * description="获取充值接口信息", * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Parameter(name="money", in="query", @OA\Schema(type="number"), required=true, description="充值金额"), * @OA\Parameter(name="order_id", in="query", @OA\Schema(type="integer"), required=false, description="订单id,表示需要结单的id"), * @OA\Response( * response="200", * description="获取充值接口信息" * ) * ) */ public function recharge() { $openid = $this->customer->openid; $unifiedOrder = new \UnifiedOrderPub(); $jsApi = new \JsApiPub(); $recharge = (new Recharge())->create([ "customer_id" => $this->customer->id, "money" => request()->money, "order_id" => request()->order_id, "payment" => "weixin", "merchant_id" => env("WEIXINPAY_MCHID") ]); $recharge = $recharge->getSerial(); //设置统一支付接口参数 //设置必填参数 //appid已填,商户无需重复填写 //mch_id已填,商户无需重复填写 //noncestr已填,商户无需重复填写 //spbill_create_ip已填,商户无需重复填写 //sign已填,商户无需重复填写 $unifiedOrder->setParameter("openid", $openid);//openid $unifiedOrder->setParameter("body", "充值" . request()->money . "元");//商品描述 $unifiedOrder->setParameter("out_trade_no", $recharge->serial);//商户订单号 $unifiedOrder->setParameter("total_fee", $recharge->money * 100);//总金额 $unifiedOrder->setParameter("notify_url", get_http_type() . $_SERVER["HTTP_HOST"] . "/customer/pay-callback");//通知地址 $unifiedOrder->setParameter("trade_type", "JSAPI");//交易类型 //非必填参数,商户可根据实际情况选填 //$unifiedOrder->setParameter("sub_mch_id","XXXX");//子商户号 //$unifiedOrder->setParameter("device_info","XXXX");//设备号 //$unifiedOrder->setParameter("attach","XXXX");//附加数据 //$unifiedOrder->setParameter("time_start","XXXX");//交易起始时间 //$unifiedOrder->setParameter("time_expire","XXXX");//交易结束时间 //$unifiedOrder->setParameter("goods_tag","XXXX");//商品标记 //$unifiedOrder->setParameter("openid","XXXX");//用户标识 //$unifiedOrder->setParameter("produc,"XXXX");//商品ID //生成预支付ID $prepay_id = $unifiedOrder->getPrepayId(); if (!$prepay_id) { return response()->json([ "errorcode" => "60000", "errormsg" => "生成支付请求失败" ]); } //第三步,前端调起支付 $jsApi->setPrepayId($prepay_id); $jsApiParameters = $jsApi->getParameters(); return response()->json(compact("recharge", "jsApiParameters")); } /** * @OA\Get( * path="/customer/get-balances", * tags={"用户端订单处理"}, * summary="V2-获取资金流水信息", * description="获取资金流水信息", * @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"), * @OA\Parameter(name="page", in="query", @OA\Schema(type="number"), required=false, description="页码"), * @OA\Response( * response="200", * description="获取资金流水信息" * ) * ) */ public function getBalances() { $balances = (new Balance())->where("customer_id", $this->customer->id)->with([ "order" => function ($query) { $query->select("id", "serial"); } ])->select("id", "customer_id", "money", "balance", "belongs_type", "belongs_id", "remark", "order_id", "created_at")->orderBy("id", "desc")->paginate(10); return response()->json($balances->toArray()); } }