adminProject()->orderBy("id", "desc")->get(); view()->share(compact("projects")); return $projects; } public function getYears() { $start_year = config("start_year"); $years = []; for ($i = date("Y"); $i >= $start_year; $i--) { $years[] = $i; } view()->share(compact("years")); } public function _getMonths() { $months = []; for ($i = 1; $i <= 12; $i++) { $mm = $i < 10 ? "0" . $i : $i; $months[] = (date("Y") - 2) . "-" . $mm; } for ($i = 1; $i <= 12; $i++) { $mm = $i < 10 ? "0" . $i : $i; $months[] = (date("Y") - 1) . "-" . $mm; } for ($i = 1; $i <= 12; $i++) { $mm = $i < 10 ? "0" . $i : $i; $months[] = date("Y") . "-" . $mm; } view()->share(compact("months")); return $months; } public function _getMonthData() { $projects = $this->_checkProjects(); $project_id = request()->project_id ?? $projects->first()->id; $project = $projects->keyBy("id")->toArray()["{$project_id}"]; $month = request()->month ?? date("Y-m"); $months = $this->_getMonths(); DB::enableQueryLog(); $paramedics = (new Paramedic())->withoutGlobalScope(AdminProjectScope::class)->where(function ($query) use ($project_id, $month) { $order_item_paramedic_ids = (new OrderItems()) ->whereRaw("(DATE_FORMAT(`service_date`,'%Y-%m') = '{$month}' or DATE_FORMAT(`paid_at`,'%Y-%m') = '{$month}')") ->whereHas("order", function ($query) use ($project_id) { $query->where("project_id", $project_id); })->pluck("paramedic_id")->toArray(); $query->where("project_id", $project_id)->orWhereIn("id", $order_item_paramedic_ids); })->with([ "orderItems" => function ($query) use ($month, $project_id) { $query->whereRaw("(DATE_FORMAT(`service_date`,'%Y-%m') = '{$month}' or DATE_FORMAT(`paid_at`,'%Y-%m') = '{$month}')") ->where("total", ">", 0) ->whereHas("order", function ($query) use ($project_id) { $query->where("project_id", $project_id); }) ->with([ "order", "product" => function ($query) { $query->withoutGlobalScope(AdminProjectScope::class); }, "productItem", "productParamedicLevel", "paramedic" => function ($query) { $query->withoutGlobalScope(AdminProjectScope::class); }, "bed", "room", "building", "area" ]) ->orderBy("id"); } ])->get(); $allItems = collect(); foreach ($paramedics as $paramedic) { foreach ($paramedic->orderItems as $orderItem) { if ($orderItem->paid_at) { $paid_at_this_month = Carbon::parse($orderItem->paid_at)->isSameMonth($month) ? true : false; } else { $paid_at_this_month = false; } if (Carbon::parse($orderItem->service_date)->isSameMonth($month)) { $orderItem->service_date_in_this_month = $orderItem->service_date; } else { $orderItem->service_date_in_this_month = OrderItems::PREV_MONTH; } $orderItem->paid_at_this_month = $paid_at_this_month; $orderItem = $orderItem->calculateFee(); } $paramedic->originalOrderItems = $paramedic->orderItems; $allItems = $allItems->concat($paramedic->orderItems); $paramedic->orderItems = $paramedic->orderItems->groupBy("service_date_in_this_month"); } $days = date("t", strtotime($month)); $dates = []; for ($i = 1; $i <= $days; $i++) { $dd = $i < 10 ? "0" . $i : $i; $dates[] = $dd; } $dates[] = OrderItems::PREV_MONTH; view()->share(compact("projects", "project_id", "month", "months", "dates", "paramedics", "allItems")); return compact("projects", "project_id", "month", "months", "dates", "paramedics", "allItems"); } public function salary(Request $request) { $projects = $this->_checkProjects(); if (!$projects->count()) { return $this->error($this->noProjects); } $this->_getMonthData(); $laravel_duration = microtime(true) - LARAVEL_START; return view($this->urlPrefix . "/salary", compact("laravel_duration")); } public function overview(Request $request) { $projects = $this->_checkProjects(); if (!$projects->count()) { return $this->error($this->noProjects); } $project_id = request()->project_id ?? $projects->first()->id; $project = Project::find($project_id); $month = request()->month ?? date("Y-m"); $months = $this->_getMonths(); $start_timestamp = strtotime($month); $end_timestamp = strtotime("+1 month", strtotime($month)); //根据项目获取相关数据 $prev_month_balance = Balance::whereRaw("UNIX_TIMESTAMP(`created_at`) < " . $start_timestamp) ->whereHas("order", function ($query) use ($project_id) { $query->where("project_id", $project_id); })->sum("money"); $this_month_balance = Balance::whereRaw("UNIX_TIMESTAMP(`created_at`) < " . $end_timestamp) ->whereHas("order", function ($query) use ($project_id) { $query->where("project_id", $project_id); })->sum("money"); $this_month_balances = Balance::whereRaw("UNIX_TIMESTAMP(`created_at`) >= " . $start_timestamp . " and UNIX_TIMESTAMP(`created_at`) < " . $end_timestamp) ->whereHas("order", function ($query) use ($project_id) { $query->where("project_id", $project_id); })->get(); return view($this->urlPrefix . "/overview", compact("project_id", "month", "project", "prev_month_balance", "this_month_balance", "this_month_balances")); } public function syncOrderItems(Request $request) { DB::enableQueryLog(); //采用指定订单号 $model = OrderItems::whereHas("order", function ($query) { $query->whereIn("serial", ["20240101000016", "20240103000044", "20240103000055", "20240103000068", "20240104000010", "20240104000011", "20240104000012", "20240104000035", "20240104000040", "20240105000009", "20240105000042", "20240105000049", "20240105000051", "20240105000063", "20240105000064", "20231212000051", "20240104000023", "20240104000033", "20240104000036", "20240104000049", "20240104000059", "20240104000060", "20240105000043", "20240105000045", "20240105000048", "20240105000065", "20240105000066", "20240101000024", "20240104000007", "20240104000030", "20240104000034", "20240104000044", "20240104000065"]); })->where("factors", "not like", "%所在科室%"); //采用指定订单号结束 if ($request->last_id) { $model = $model->where("id", ">", $request->last_id); } $orderItems = $model->with("order")->limit(50)->get(); if (!$orderItems->count()) { dd("已处理完毕"); } DB::beginTransaction(); try { foreach ($orderItems as $orderItem) { $factors = json_decode($orderItem->factors, true); $parent_factors = json_decode($orderItem->order->factors, true); if ( !in_array("所在科室", collect($factors)->pluck("factor_name")->toArray()) && in_array("所在科室", collect($parent_factors)->pluck("factor_name")->toArray()) ) { $add = collect($parent_factors)->keyBy("factor_name")["所在科室"]; $factors[] = $add; $orderItem->update([ "factors" => json_encode($factors, JSON_UNESCAPED_UNICODE) ]); } } DB::commit(); return $this->success("处理成功一批,正在跳转到下一批!", url($this->urlPrefix . "/salary/sync-order-items?month={$request->month}&last_id=" . $orderItems->last()->id)); } catch (\Exception $exception) { DB::rollBack(); dd($exception->getMessage()); } } public function finance(Request $request) { $projects = $this->_checkProjects(); if (!$projects->count()) { return $this->error($this->noProjects); } $project_id = request()->project_id ?? $projects->first()->id; $project = $projects->keyBy("id")->toArray()["{$project_id}"]; $month = request()->month ?? date("Y-m"); $months = $this->_getMonths(); // 判断是否护士长 $userId = auth()->id(); $roleId = Role::where('name', 'like', '%护士长%')->where('guard_name', 'admin')->value('id'); $hushizhang = DB::table('model_has_roles')->where('role_id', $roleId) ->where('model_type', 'App\Admin') ->where('model_id', $userId) ->count(); // 是否院方管理 $roleId = Role::where('name', 'like', '%院方管理%')->where('guard_name', 'admin')->value('id'); $yuanfang = DB::table('model_has_roles')->where('role_id', $roleId) ->where('model_type', 'App\Admin') ->where('model_id', $userId) ->count(); // 获取这个护士长病区的订单或院方管理楼栋的订单 $user = auth()->user(); $orderIds = []; if ($hushizhang) { $areaId = AdminAreaLink::where('project_id', $project_id)->where('admin_id', $user->id)->pluck('area_id'); if ($areaId->isNotEmpty()) { $bedList = Bed::whereIn('area_id', $areaId)->pluck('id'); if ($bedList->isNotEmpty()) { $orderIds = Orders::whereIn('bed_id', $bedList)->pluck('id'); } } } elseif ($yuanfang) { $buildingId = AdminBuildingLink::where('project_id', $project_id)->where('admin_id', $user->id)->pluck('building_id'); if ($buildingId->isNotEmpty()) { $areaId = Area::whereIn('building_id', $buildingId)->pluck('id'); if ($areaId->isNotEmpty()) { $bedList = Bed::whereIn('area_id', $areaId)->pluck('id'); if ($bedList->isNotEmpty()) { $orderIds = Orders::whereIn('bed_id', $bedList)->pluck('id'); } } } // 如果没有关联数据,$orderIds 保持为空数组,后续查询会返回空结果 } $recharges = Recharge::with(["manager", "order", "patient"]) ->where(function ($query) use ($hushizhang, $yuanfang, $orderIds) { if ($hushizhang || $yuanfang) { if (!empty($orderIds)) { $query->whereIn('order_id', $orderIds); } else { // 如果没有关联数据,返回空结果 $query->whereIn('order_id', []); } } }) ->withCount("refunds") ->whereNotNull("paid_at") ->whereRaw("DATE_FORMAT(`paid_at`,'%Y-%m') = '{$month}'") ->whereHas("order", function ($query) use ($project_id) { $query->where("project_id", $project_id); }) ->get(); $recharges_sum = $recharges->sum('money'); $refunds = Refund::whereNotNull("paid_at") ->where(function ($query) use ($hushizhang, $yuanfang, $orderIds) { if ($hushizhang || $yuanfang) { if (!empty($orderIds)) { $query->whereIn('order_id', $orderIds); } else { // 如果没有关联数据,返回空结果 $query->whereIn('order_id', []); } } }) ->whereRaw("DATE_FORMAT(`paid_at`,'%Y-%m') = '{$month}'") ->whereHas("order", function ($query) use ($project_id) { $query->where("project_id", $project_id); }) ->get(); $refunds_sum = $refunds->sum('money'); return view($this->bladePath . ".finance", compact("recharges_sum", "refunds_sum", "recharges", "refunds", "projects", "project_id", "months", "month")); } public function memberBalanceByDate(Request $request) { $is_export = $request->get('is_export', 0); $projects = $this->_checkProjects(); if (!$projects->count()) { return $this->error($this->noProjects); } $mode = $request->mode ?: 'customer'; $project_id = request()->project_id ?? $projects->first()->id; $project = Project::find($project_id); $before_date = $request->before_date ?: date("Y-m-d"); $before_datetime = strtotime($before_date . " 23:59:59"); $before_datetime_text = date("Y-m-d H:i:s", $before_datetime); DB::enableQueryLog(); $customers = collect(); $orderBalances = collect(); if ($mode == 'order') { $orderBalances = Orders::query() ->withoutGlobalScopes() ->leftJoin("project", "project.id", "=", "orders.project_id") ->leftJoin("customers", "customers.id", "=", "orders.customer_id") ->leftJoin("patient", "patient.id", "=", "orders.patient_id") ->leftJoin("balance", function ($join) use ($before_datetime_text) { $join->on("balance.order_id", "=", "orders.id") ->whereNull("balance.deleted_at") ->where("balance.created_at", "<=", $before_datetime_text); }) ->whereNull("orders.deleted_at") ->where("orders.project_id", $project_id) ->whereExists(function ($query) use ($before_date) { $query->select(DB::raw(1)) ->from('order_items') ->whereColumn('order_items.order_id', 'orders.id') ->whereNull('order_items.deleted_at') ->whereDate('order_items.service_date', $before_date); }) ->groupBy( "orders.id", "orders.serial", "project.name", "orders.from_date", "orders.to_date", "orders.contact", "orders.mobile", "customers.mobile", "patient.name" ) ->orderBy("orders.from_date") ->orderBy("orders.id") ->get([ "orders.id", "orders.serial", "project.name as project_name", "orders.from_date", "orders.to_date", "orders.contact", "orders.mobile as contact_mobile", DB::raw("'" . $before_datetime_text . "' as point_time"), "customers.mobile as customer_mobile", "patient.name as patient_name", DB::raw("COALESCE(SUM(balance.money), 0) as balance"), ]); if ($is_export) { $rows = $orderBalances->toArray(); $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); $sheet->setCellValue('A1', '项目名称'); $sheet->setCellValue('B1', '时点'); $sheet->setCellValue('C1', '订单号'); $sheet->setCellValue('D1', '客户手机号'); $sheet->setCellValue('E1', '联系人'); $sheet->setCellValue('F1', '联系电话'); $sheet->setCellValue('G1', '被陪护人'); $sheet->setCellValue('H1', '服务开始'); $sheet->setCellValue('I1', '服务结束'); $sheet->setCellValue('J1', '时点余额'); $count = count($rows); for ($i = 2; $i <= $count + 1; $i++) { $row = $rows[$i - 2]; $sheet->setCellValue('A' . $i, $row['project_name']); $sheet->setCellValue('B' . $i, $row['point_time']); $sheet->setCellValue('C' . $i, $row['serial']); $sheet->setCellValue('D' . $i, $row['customer_mobile']); $sheet->setCellValue('E' . $i, $row['contact']); $sheet->setCellValue('F' . $i, $row['contact_mobile']); $sheet->setCellValue('G' . $i, $row['patient_name']); $sheet->setCellValue('H' . $i, $row['from_date']); $sheet->setCellValue('I' . $i, $row['to_date']); $sheet->setCellValue('J' . $i, $row['balance']); } header('Content-Type: application/vnd.ms-excel'); header('Content-Disposition: attachment;filename="' . ($project ? $project->name : '项目') . '_订单时点余额_' . date('YmdHis') . '.xlsx"'); header('Cache-Control: max-age=0'); $writer = new Xlsx($spreadsheet); $writer->save('php://output'); exit; } } else { $customers = (new Customer()) ->whereNull("deleted_at") ->with([ "patients" => function ($query) use ($before_datetime) { $query->whereRaw("UNIX_TIMESTAMP(`created_at`) <= {$before_datetime}")->orderBy("id", "desc"); }, ]) ->whereHas("orders", function ($query) use ($before_datetime, $project_id) { $query ->where("project_id", $project_id); }) ->get(); } $laravel_duration = microtime(true) - LARAVEL_START; return view($this->bladePath . ".customer-balance", compact( "customers", "orderBalances", "before_datetime", "before_date", "before_datetime_text", "project_id", "laravel_duration", "mode" )); } public function fixMonthLastDayCheckout(Request $request) { $day = $request->day; if (!$day) { dd("日期不正确"); } DB::enableQueryLog(); $orders = Orders::whereIn("serial", ["20201130000003", "20201130000005", "20201128000004", "20201126000006", "20201127000005", "20201126000003", "20201130000004", "20201127000008", "20201130000001", "20201126000008"])->get(); $orderItems = OrderItems::with(["balance", "order"]) ->whereNotNull("paid_at") ->whereRaw("UNIX_TIMESTAMP(`paid_at`) > " . strtotime("2020-12-01")) ->whereRaw("UNIX_TIMESTAMP(`paid_at`) < " . strtotime("2020-12-04")) ->whereIn("order_id", $orders->pluck("id")->toArray()) ->limit(100)->get(); try { foreach ($orderItems as $orderItem) { $new_paid_at = "{$day} 22:00:01"; $orderItem->update([ "paid_at" => $new_paid_at ]); $orderItem->balance->update([ "created_at" => $new_paid_at, "remark" => "本条经过时间校准处理。原始创建时间为:" . $orderItem->balance->created_at ]); } DB::commit(); dd("处理完毕"); } catch (\Exception $exception) { DB::rollBack(); dd($exception->getMessage()); } } public function fixBalanceOrderId() { $balances = Balance::whereNull("order_id")->with("belongs")->limit("100")->get(); if (!$balances->count()) { return $this->success("处理完毕", url($this->urlPrefix . "/overview")); } foreach ($balances as $balance) { $balance->timestamps = false; $balance->update([ "order_id" => $balance->belongs->order_id ]); } return $this->success("处理完毕" . $balances->count() . "条数据,正在进入下一批数据。", url($this->urlPrefix . "/finance/fix-balance-order-id?timer=" . time())); } public function manualQueryRecharge($id) { $recharge = Recharge::find($id); $res = (new AlipayF2F())->manualQuery($recharge); dd($res); } public function huli(Request $request) { $projects = (new StatisticsController())->_checkProjects(); $defaultProjectsId = ($projects[0]->id) ?? ''; $project_id = $request->get('project_id', $defaultProjectsId); $month = request()->month ?? date("Y-m"); $userId = auth()->id(); // 判断是否护士长 $roleId = Role::where('name', 'like', '%护士长%')->where('guard_name', 'admin')->value('id'); $hushizhang = DB::table('model_has_roles')->where('role_id', $roleId) ->where('model_type', 'App\Admin') ->where('model_id', $userId)->count(); // 是否院方管理 $roleId = Role::where('name', 'like', '%院方管理%')->where('guard_name', 'admin')->value('id'); $yuanfang = DB::table('model_has_roles')->where('role_id', $roleId) ->where('model_type', 'App\Admin') ->where('model_id', $userId)->count(); $areaId = []; $buildingId = []; if ($hushizhang) { $user = auth()->user(); $areaId = AdminAreaLink::where(function ($qeury) use ($project_id) { if ($project_id) { $qeury->where('project_id', $project_id); } })->where('admin_id', $user->id)->pluck('area_id'); } elseif ($yuanfang) { $user = auth()->user(); $buildingId = AdminBuildingLink::where(function ($qeury) use ($project_id) { if ($project_id) { $qeury->where('project_id', $project_id); } })->where('admin_id', $user->id)->pluck('building_id'); } $allAreas = Area::where('project_id', $project_id)->with('project', 'building')->where(function ($query) use ($areaId, $buildingId) { if ($areaId) { $query->whereIn('id', $areaId); } if ($buildingId) { $query->whereIn('building_id', $buildingId); } })->get(); // 病区智能排序:1.数字开头按数字升序 2.中文数字开头转阿拉伯数字后升序 3.其他按myindex+id $sortedAreas = $allAreas->sort(function ($a, $b) { $keyA = $this->_getAreaNameSortKey($a->name ?? '', $a->myindex ?? 0, $a->id); $keyB = $this->_getAreaNameSortKey($b->name ?? '', $b->myindex ?? 0, $b->id); if ($keyA[0] !== $keyB[0]) { return $keyA[0] <=> $keyB[0]; } if ($keyA[1] !== $keyB[1]) { return $keyA[1] <=> $keyB[1]; } return $keyA[2] <=> $keyB[2]; })->values(); $perPage = 40; $currentPage = (int) $request->get('page', 1); $currentPage = max(1, $currentPage); $items = $sortedAreas->forPage($currentPage, $perPage)->values(); $data = new LengthAwarePaginator($items, $sortedAreas->count(), $perPage, $currentPage, [ 'path' => $request->url(), 'query' => $request->query(), ]); $data->appends($request->all())->render(); // ===== 重构:先从 OrderItems 获取真实价格数据,生成列,然后再统计每个病区的数据 ===== // 1. 获取当前分页中所有病区的床位 ID $areaIds = collect($data->items())->pluck('id'); $beds = Bed::whereIn('area_id', $areaIds)->get(); $bedsByArea = $beds->groupBy('area_id'); $allBedIds = $beds->pluck('id'); // 2. 获取这些床位在当月的所有真实子订单(仅统计 total > 0,且属于当前项目) $orderItems = OrderItems::whereIn('bed_id', $allBedIds) ->where('total', '>', 0) ->where('paid_at', 'like', '%' . $month . '%') ->whereHas('order', function ($query) use ($project_id) { $query->where('project_id', $project_id); }) ->get(); // 3. 按「真实价格」去重生成表头列(xx元/天),并取一条样本数据上的因子名称作为小字说明 // 使用 groupBy('total'),避免闭包分组可能导致的 array_key_exists 问题 $columns = $orderItems ->groupBy('total') ->map(function ($group, $total) { /** @var OrderItems $sample */ $sample = $group->first(); $price = (float) $total; $factor_item_name = ''; if ($sample && $sample->factors) { $factors = json_decode($sample->factors, true) ?: []; if (!empty($factors)) { // 取第一条因子作为说明文本(前端展示不变:价格 + 小字) $factor_item_name = $factors[0]['factor_item_name'] ?? ''; } } return [ 'price' => $price, 'name' => $price . '元/天', 'factor_item_name' => $factor_item_name, ]; }) ->sortBy('price') ->values() ->toArray(); // 4. 按病区 + 列价格 统计每个病区在每个价格档位上的总金额 $sumOrderTotal = 0; foreach ($data as $item) { // 当前病区所有床位 ID $bedIds = $bedsByArea->get($item->id, collect())->pluck('id'); // 当前病区相关的所有子订单 $areaOrderItems = $orderItems->whereIn('bed_id', $bedIds->all()); // 病区总收入 $item->order_total = $areaOrderItems->sum('total'); $sumOrderTotal += $item->order_total; // 子项:按表头列(价格)统计该病区在各价格档位上的总金额 $lies = []; foreach ($columns as $col) { $price = (float) $col['price']; $colTotal = $areaOrderItems->where('total', $price)->sum('total'); $lies[] = [ 'name' => $col['name'], 'factor_item_name' => $col['factor_item_name'], 'total_price' => $price, 'total' => $colTotal, ]; } $item->lies = $lies; } // 表头列:使用上面生成的真实价格列(包含价格和 factor_item 名称) $lie = $columns; $months = $this->_getMonths(); return view($this->bladePath . ".huli", compact("sumOrderTotal", "data", "month", "lie", "projects", "project_id")); } /** * 获取病区名称的排序键,用于智能排序 * 规则:1.数字开头->按数字升序 2.中文数字开头->转阿拉伯数字后升序 3.其他->按myindex+id * * @return array [tier, primary_sort, secondary_sort] tier=0有数字 tier=1无数字 */ private function _getAreaNameSortKey($name, $myindex, $id) { $name = trim((string) $name); $myindex = (int) $myindex; $id = (int) $id; // 1. 以阿拉伯数字开头:提取数字 if (preg_match('/^(\d+)/', $name, $m)) { return [0, (int) $m[1], 0]; } // 2. 以中文数字开头:解析并转换 $cnNum = $this->_parseChineseNumber($name); if ($cnNum !== null) { return [0, $cnNum, 0]; } // 3. 都不满足:按 myindex、id return [1, $myindex, $id]; } /** * 解析病区名称开头的连续中文数字,转为阿拉伯数字 * * @return int|null 解析到的数字,若无则 null */ private function _parseChineseNumber($str) { static $digits = [ '〇' => 0, '零' => 0, '一' => 1, '二' => 2, '两' => 2, '三' => 3, '四' => 4, '五' => 5, '六' => 6, '七' => 7, '八' => 8, '九' => 9, '十' => 10, '百' => 100, '千' => 1000, '万' => 10000, ]; $s = preg_replace('/\s+/', '', $str); if ($s === '') { return null; } $len = mb_strlen($s); $i = 0; $result = 0; $temp = 0; // 用于「十」「百」前的累积 while ($i < $len) { $ch = mb_substr($s, $i, 1); if (!isset($digits[$ch])) { break; } $val = $digits[$ch]; if ($val >= 10) { // 十、百、千、万:乘数 if ($temp === 0) { $temp = 1; } $result += $temp * $val; $temp = 0; } else { $temp = $val; } $i++; } $result += $temp; if ($i === 0) { return null; } return $result; } /** * 获取动态列 */ public function getLies($bedIds, $productItem, $factor, $month) { $list = []; // 修复:如果床位ID为空,直接返回空数组,避免 whereIn 空数组导致的SQL错误 if (empty($bedIds)) { return $list; } foreach ($productItem as $item) { foreach ($factor as $factor_item) { $query = OrderItems::where('product_item_id', $item->id) ->whereIn("bed_id", $bedIds) ->where('paid_at', 'like', '%' . $month . '%'); // 使用 MySQL 5.7 的 JSON_SEARCH 精确匹配包含指定 factor_item_id 的子订单 $factorItemId = (int) $factor_item->id; $query->whereRaw("JSON_SEARCH(factors, 'one', ?, NULL, '$[*].factor_item_id') IS NOT NULL", [$factorItemId]); // 1)列对应的真实总收入:该因子 + 产品子项 + 病区 + 月份 下所有子订单的 total 之和 $total = (float) $query->sum('total'); // 2)表头展示的价格:按“公式”计算,保证不是 0(近似真实下单价) // 价格 = 产品子项基础价 + 因子价格 $totalPrice = (float) $item->price + (float) $factor_item->price; $list[] = [ 'name' => $totalPrice . '元/天', 'factor_item_name' => $factor_item->name ?? '', 'total_price' => $totalPrice, 'product_item_id' => $item->id, 'factor_item_id' => $factor_item->id, 'total' => $total ]; } } return $list; } /** * 床位统计 * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function bed() { $is_export = \request('is_export', 0); $projects = $this->_checkProjects(); if (!$projects->count()) { return $this->error($this->noProjects); } $project_id = request()->project_id ?? $projects->first()->id; $project = Project::find($project_id); $month = request()->month ?? date("Y-m"); $months = $this->_getMonths(); // 当月天数 $days = date('t', strtotime($month)); $area = Area::withCount('beds')->where('project_id', $project_id)->get(); $beds = Bed::whereIn('area_id', $area->pluck('id'))->where('project_id', $project_id)->get(); $totalBed = $beds->count(); // 订单总数 $orderTotal = Orders::where('project_id', $project_id) ->where('created_at', 'like', '%' . $month . '%') ->whereIn('bed_id', $beds->pluck('id')) ->count(); foreach ($area as $item) { // 床位占比 $item->bed_rate = 0; if ($totalBed) { $item->bed_rate = round($item->beds_count / $totalBed, 4) * 100; } // 订单数 $bedsIdTemp = Bed::where('area_id', $item->id)->where('project_id', $project_id)->pluck('id'); $item->order_total = OrderItems::where('created_at', 'like', '%' . $month . '%') ->where('total', '>', 0) ->whereIn('bed_id', $bedsIdTemp) ->count(); $item->rate = 0; if ($bedsIdTemp->count()) { // 配比 $item->rate = round($item->order_total / ($days * $bedsIdTemp->count()), 4) * 100; } } // 导出 if ($is_export) { $area = $area->toArray(); $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); $sheet->setCellValue('A1', '病区'); $sheet->setCellValue('B1', '床位数量'); $sheet->setCellValue('C1', '床位占比'); $sheet->setCellValue('D1', '陪护人天'); $sheet->setCellValue('E1', '陪护率'); $count = count($area); //计算有多少条数据 for ($i = 2; $i <= $count + 1; $i++) { $sheet->setCellValue('A' . $i, $area[$i - 2]['name']); $sheet->setCellValue('B' . $i, $area[$i - 2]['beds_count']); $sheet->setCellValue('C' . $i, $area[$i - 2]['bed_rate']); $sheet->setCellValue('D' . $i, $area[$i - 2]['order_total']); $sheet->setCellValue('E' . $i, $area[$i - 2]['rate']); } header('Content-Type: application/vnd.ms-excel'); header('Content-Disposition: attachment;filename="' . $project->name . '_' . date('YmdHis') . '.xlsx"'); header('Cache-Control: max-age=0'); $writer = new Xlsx($spreadsheet); $writer->save('php://output'); exit; } return view($this->bladePath . ".bed", compact("area", "orderTotal", "totalBed", "project", "project_id", "month", "projects")); } /** * 收入统计 * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View */ public function income() { $is_export = \request('is_export', 0); $projects = $this->_checkProjects(); if (!$projects->count()) { return $this->error($this->noProjects); } $project_id = request()->project_id ?? $projects->first()->id; $project = Project::find($project_id); $month = request()->month ?? date("Y-m"); $months = $this->_getMonths(); // 当月天数 $days = date('t', strtotime($month)); $areaList = Area::withCount('beds')->where('project_id', $project_id)->get(); // 合计 $total['order_total'] = $total['shouxufei'] = $total['zengshishui'] = $total['shijishouru'] = $total['guanlifei'] = 0; $area = []; foreach ($areaList as $item) { $beds = Bed::where('area_id', $item->id)->where('project_id', $project_id)->get(); $orderTotal = OrderItems::where('paid_at', 'like', '%' . $month . '%') ->whereIn('bed_id', $beds->pluck('id')) ->sum("total"); $item->order_total = $orderTotal; $item->shouxufei = round($orderTotal * 0.006, 2); $item->zengshishui = round($orderTotal * 0.06, 2); $item->shijishouru = round($orderTotal - $item->shouxufei - $item->zengshishui, 2); $item->guanlifei = round($item->shijishouru * 0.06, 2); if (!empty($item->order_total)) { $area[] = $item; } // 合计 $total['order_total'] += $item->order_total; $total['shouxufei'] += $item->shouxufei; $total['zengshishui'] += $item->zengshishui; $total['shijishouru'] += $item->shijishouru; $total['guanlifei'] += $item->guanlifei; } $refund['order_total'] = abs(Balance::where('created_at', 'like', '%' . $month . '%') ->where('belongs_type', 'App\Models\Refund') ->whereHas("order", function ($query) use ($project_id) { $query->where("project_id", $project_id); })->sum("money")); $refund['shijishouru'] = $refund['order_total']; $refund['guanlifei'] = round($refund['order_total'] * 0.06, 2); // 总计 $zongji['order_total'] = $total['order_total'] - $refund['order_total']; $zongji['shouxufei'] = $total['shouxufei'] * 2; $zongji['zengshishui'] = $total['zengshishui'] * 2; $zongji['shijishouru'] = $total['shijishouru'] - $refund['shijishouru']; $zongji['guanlifei'] = $total['guanlifei'] - $refund['guanlifei']; $admin = Auth::guard("admin")->user(); return view($this->bladePath . ".income", compact("admin", "zongji", "refund", "total", "area", "project", "project_id", "month", "projects")); } }