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

271 lines
13 KiB

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\Manager;
use App\Models\Area;
use App\Models\Bed;
use App\Models\OrderItems;
use App\Models\Orders;
use App\Models\Paramedic;
use App\Models\Recharge;
use App\Models\Refund;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class StatisticsController extends CommonController
{
/**
* @OA\Get(
* path="/manager/statistics/overview",
* summary="V2-获取项目首页总览数据统计",
* description="获取项目首页总览数据统计",
* @OA\Parameter(name="project_id", in="query", @OA\Schema(type="integer"), required=true, description="医院ID"),
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description="获取项目首页总览数据统计",
* content={
* @OA\MediaType(
* mediaType="application/json",
* @OA\Schema(
* @OA\Property(
* property="orders_all",
* type="integer",
* description="全部订单数"
* ),
* @OA\Property(
* property="orders_pending",
* type="integer",
* description="待处理订单数"
* ),
* @OA\Property(
* property="orders_ongoing",
* type="integer",
* description="进行中订单数"
* ),
* @OA\Property(
* property="orders_finished",
* type="integer",
* description="已完成订单数"
* ),
* @OA\Property(
* property="orders_finished_today",
* type="integer",
* description="今日出院人数"
* ),
* @OA\Property(
* property="paramedics",
* type="integer",
* description="医院护工总数"
* ),
* @OA\Property(
* property="bill_today",
* type="decimal",
* description="今日应扣款"
* ),
* example={
* "orders_all": "999",
* "orders_pending": "60",
* "orders_ongoing": "50",
* "orders_finished": "889",
* "orders_finished_today": "12",
* "paramedics": "126",
* "bill_today": "9980.00"
* }
* )
* )
* }
* )
* )
*/
public function overview()
{
$project_id = request()->project_id;
$counts = [];
$counts["orders_all"] = (new Orders())->ofProject($project_id)->count();
$counts["orders_pending"] = (new Orders())->ofProject($project_id)->whereIn("status", [Orders::STATUS_UNCONFIRMED, Orders::STATUS_UNASSIGNED])->count();
$counts["orders_ongoing"] = (new Orders())->ofProject($project_id)->where("status", Orders::STATUS_ONGOING)->count();
$counts["orders_finished"] = (new Orders())->ofProject($project_id)->where("status", Orders::STATUS_FINISHED)->count();
$counts["orders_finished_today"] = (new Orders())->ofProject($project_id)->where("to_date", date("Y-m-d"))->where("status", Orders::STATUS_FINISHED)->count();
$counts["paramedics"] = (new Paramedic())->ofProject($project_id)->count();
$counts["bill_today"] = (new OrderItems())->where("service_date", date("Y-m-d"))->whereHas("order", function ($query) use ($project_id) {
$query->ofProject($project_id);
})->sum("total");
$counts["paramedic_has_order"] = (new Paramedic())->ofProject($project_id)->whereHas("orders",function($query) {
$query->where("status", Orders::STATUS_ONGOING);
})->count();
$counts["orders_ongoing_in_today"] = (new Orders())->ofProject($project_id)->whereHas("audits", function($query) {
$query->whereRaw();
})->count();
return response()->json(compact("counts"));
}
/**
* @OA\Get(
* path="/manager/statistics/beds",
* summary="V2-获取项目中的床位陪护一览",
* description="获取项目中的床位陪护一览",
* @OA\Parameter(name="project_id", in="query", @OA\Schema(type="integer"), required=true, description="医院ID"),
* @OA\Parameter(name="has_ongoing_order", in="query", @OA\Schema(type="integer"), required=false, description="是否包含正在服务的订单,默认为不筛选"),
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Response(
* response="200",
* description="获取项目中的床位陪护一览"
* )
* )
*/
public function beds(Request $request)
{
DB::enableQueryLog();
$areas = Area::with([
"beds" => function ($query) use ($request) {
if ($request->has_ongoing_order) {
$query->has("onGoingOrder");
}
$query->with(["onGoingOrder" => function ($query) {
$query->leftJoin("paramedic", "orders.paramedic_id", "=", "paramedic.id")
->select("orders.id", "orders.bed_id", "orders.paramedic_id", "orders.status", "paramedic.name as paramedic_name");
}])->select("bed.id", "bed.name", "bed.room_id", "bed.area_id", "bed.myindex")
->leftJoin("room", "bed.room_id", "=", "room.id")
->addSelect("room.name as room_name")
->orderBy("room.name")
->orderBy("bed.name");
}])
->whereRaw("`area`.`project_id` = '{$request->project_id}'")
->orderBy("building.myindex")
->orderBy("area.myindex")
->select("area.id", "area.name", "area.building_id", "area.project_id")
->leftJoin("building", "area.building_id", "=", "building.id")
->addSelect("building.name as building_name")
->withCount("beds")
->get();
if ($request->has_ongoing_order) {
$areas = $areas->filter(function ($item) {
return $item->beds->count();
});
}
return response()->json($areas->toArray());
}
/**
* @OA\Get(
* path="/manager/statistics/by-duration",
* summary="V2-获取时间段内的统计或指定明细",
* description="获取时间段内的统计或指定明细",
* @OA\Parameter(name="token", in="query", @OA\Schema(type="string"), required=true, description="token"),
* @OA\Parameter(name="project_id", in="query", @OA\Schema(type="integer"), required=true, description="医院ID"),
* @OA\Parameter(name="duration", in="query", @OA\Schema(type="string"), required=false, description="统计周期的快捷方式可选方式today,this_week,this_month,yesterday,last_week,last_month"),
* @OA\Parameter(name="from_date", in="query", @OA\Schema(type="string"), required=false, description="开始日期如果没有duration参数此参数必须"),
* @OA\Parameter(name="to_date", in="query", @OA\Schema(type="string"), required=false, description="结束日期如果没有duration参数此参数必须注意结束日期最多可以比开始日期大31天"),
* @OA\Parameter(name="detail_type", in="query", @OA\Schema(type="string"), required=false, description="明细类型此参数不传表示仅获取汇总数据传递时可选项目checkout扣款明细,recharge充值明细,refund退款明细"),
* @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="每页数量默认为10"),
* @OA\Response(
* response="200",
* description="获取时间段内的统计"
* )
* )
*/
public function byDuration(Request $request)
{
$duration = $this->_getDuration();
$from_date = $duration[0];
$to_date = $duration[1];
$from_date_timestamp = strtotime($from_date);
$to_date_timestamp = strtotime($to_date) + 86400 - 1;
if (Carbon::parse($from_date)->diffInDays($to_date) >= 31) {
return response()->json([
"errorcode" => 90001,
"errormsg" => "日期间隔不能超过31天"
]);
}
$model_checkout = OrderItems::whereHas("order", function ($query) use ($request) {
$query->where("project_id", $request->project_id);
})->whereNotNull("paid_at")->whereRaw("UNIX_TIMESTAMP(`paid_at`) between {$from_date_timestamp} and {$to_date_timestamp}");
$model_recharge = Recharge::whereHas("order", function ($query) use ($request) {
$query->where("project_id", $request->project_id);
})->whereNotNull("paid_at")->whereRaw("UNIX_TIMESTAMP(`paid_at`) between {$from_date_timestamp} and {$to_date_timestamp}");
$model_refund = Refund::whereHas("order", function ($query) use ($request) {
$query->where("project_id", $request->project_id);
})->whereNotNull("paid_at")->whereRaw("UNIX_TIMESTAMP(`paid_at`) between {$from_date_timestamp} and {$to_date_timestamp}");
$page_size = $request->has("page_size") ? (int)$request->page_size : 10;
switch ($request->detail_type) {
case "checkout":
$data = $model_checkout->paginate($page_size);
return response()->json($data->toArray());
break;
case "recharge":
$data = $model_recharge->paginate($page_size);
return response()->json($data->toArray());
break;
case "refund":
$data = $model_refund->paginate($page_size);
return response()->json($data->toArray());
break;
}
$checkout = $model_checkout->sum("total");
$refund = $model_refund->sum("money");
$payment_methods = (new Recharge())->payment_methods;
$payment_online_methods = (new Recharge())->payment_online_methods;
$recharge_by_payment = $model_recharge->select("payment", "paid_at", "money", "order_id")->addSelect(DB::raw("sum(`money`) as total"))->groupBy("payment")->get()->keyBy("payment")->toArray();
$recharge = [];
$recharge["total"] = collect($recharge_by_payment)->sum("total");
$recharge["total_online"] = collect($recharge_by_payment)->filter(function($item) use ($payment_online_methods) {
return in_array($item["payment"], array_keys($payment_online_methods));
})->sum("total");
foreach ($payment_methods as $k => $v) {
$val = isset($recharge_by_payment[$k]) ? $recharge_by_payment[$k]["total"] : 0;
$recharge[$k] = $val;
}
return response()->json(compact("checkout", "refund", "recharge", "payment_methods"));
}
public function _getDuration()
{
switch (request()->duration) {
case "today":
$from_date = date("Y-m-d");
$to_date = date("Y-m-d");
break;
case "yesterday":
$from_date = Carbon::today()->sub("1 day")->toDateString();
$to_date = Carbon::today()->sub("1 day")->toDateString();
break;
case "this_week":
$from_date = Carbon::today()->startOfWeek()->toDateString();
$to_date = Carbon::today()->endOfWeek()->toDateString();
break;
case "last_week":
$from_date = Carbon::today()->sub("7 day")->startOfWeek()->toDateString();
$to_date = Carbon::today()->sub("7 day")->endOfWeek()->toDateString();
break;
case "this_month":
$from_date = Carbon::today()->startOfMonth()->toDateString();
$to_date = Carbon::today()->endOfMonth()->toDateString();
break;
case "last_month":
$from_date = Carbon::today()->sub("1 month")->startOfMonth()->toDateString();
$to_date = Carbon::today()->sub("1 month")->endOfMonth()->toDateString();
break;
default:
$from_date = request()->from_date;
$to_date = request()->to_date;
}
return [$from_date, $to_date];
}
}