From cf075469b2c0d46b3de6f31bcd1da7e8ae7323cf Mon Sep 17 00:00:00 2001 From: yanzai Date: Sat, 1 Nov 2025 14:31:25 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=B7=E6=BA=90=E5=88=97=E8=A1=A8=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E3=80=81=E6=8B=86=E5=88=86=E5=AF=BC=E5=87=BA=E6=8A=A5?= =?UTF-8?q?=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Http/Controllers/H5/FenzhenController.php | 6 +- Laravel/app/Services/FenZhenNewService.php | 362 ++++++++++++++++++ admin/src/views/PlanMngr/Plan.vue | 13 +- admin/src/views/ReportForms/TiJianTime.vue | 8 +- 4 files changed, 382 insertions(+), 7 deletions(-) create mode 100644 Laravel/app/Services/FenZhenNewService.php diff --git a/Laravel/app/Http/Controllers/H5/FenzhenController.php b/Laravel/app/Http/Controllers/H5/FenzhenController.php index de35706..e4a8cfb 100644 --- a/Laravel/app/Http/Controllers/H5/FenzhenController.php +++ b/Laravel/app/Http/Controllers/H5/FenzhenController.php @@ -4,6 +4,7 @@ namespace App\Http\Controllers\H5; use App\Http\Controllers\API\PEISApiController; use App\Http\Controllers\Controller; +use App\Services\FenZhenNewService; use App\Services\FenZhenService; use DateInterval; use DatePeriod; @@ -314,6 +315,7 @@ class FenzhenController extends Controller public function export2(){ ini_set('memory_limit', '256M'); $dates=request('dates'); + $table_num=request('table_num'); if(!$dates){ return \Yz::echoError1('请选择日期'); } @@ -321,8 +323,8 @@ class FenzhenController extends Controller if(count($dates)>31){ return \Yz::echoError1('最多只能选择31天'); } - $service=new FenZhenService(); - $res=$service->export($dates); + $service=new FenZhenNewService(); + $res=$service->export($dates,$table_num); return \Yz::Return($res['status'],$res['msg'],['url'=>$res['url']]); } } diff --git a/Laravel/app/Services/FenZhenNewService.php b/Laravel/app/Services/FenZhenNewService.php new file mode 100644 index 0000000..90125db --- /dev/null +++ b/Laravel/app/Services/FenZhenNewService.php @@ -0,0 +1,362 @@ + 'Bearer BD30333C-CBD4-4BA3-A27C-76727FF4D8B1', + 'Content-Type' => 'application/json; charset=utf-8', + ]; + $api_dates=[]; + $promises=[]; + foreach ($dates as $date) { + //遍历缓存,如果没有则请求接口,否则直接读取缓存文件 + $fileFound = $this->findFilesByDate($date); + if ($fileFound !== null) { + $fileContent = Storage::get($fileFound); + $dataArray = json_decode($fileContent, true); + $table_list = array_merge($table_list, $dataArray['data']['table1'] ?? []); + $clinic_list = array_merge($clinic_list, $dataArray['data']['table2'] ?? []); + $table_list3 = array_merge($table_list3, $dataArray['data']['table3'] ?? []); + + }else{ + $api_dates[]=$date; + $promises[]=$client->postAsync($url.'/api/Open/TiJian/export',['headers' => $header, 'json' => ['date'=>$date]]); + } + } + + $all_request_status=true;//所有接口请求状态 + // 等待所有请求完成 + $results = Promise\Utils::settle($promises)->wait(); + foreach ($results as $key => $result) { + if ($result['state'] === 'fulfilled') { + Log::info('请求接口'.$api_dates[$key]); + $response = $result['value']; + $responseBody=(string) $response->getBody(); + //把接口请求成功的缓存到本地txt + $txtName=$api_dates[$key].'created_at'.date('Y-m-d H:m:s'); + $TxtfilePath = 'fenzhen_tongji_temp/'.$txtName.'.txt'; + if($api_dates[$key]getBody() . "\n"; + $table_list = array_merge($table_list, $res['data']['table1'] ?? []); + $clinic_list = array_merge($clinic_list, $res['data']['table2'] ?? []); + $table_list3 = array_merge($table_list3, $res['data']['table3'] ?? []); + }else{ + $all_request_status=false; + Log::info("Request failed with key: $key, reason: " . $result['reason']->getMessage()); + } + } + if($all_request_status===false){ + return ['status'=>false,'msg'=>'部分请求失败,请重新尝试','url'=>'']; + } + foreach ($table_list as $key=> $table_item) { //匹配$table_list3获取体检号 + foreach ($table_list3 as $table_item3) { + if($table_item['name']==$table_item3['name'] and $table_item['phone']==$table_item3['phone']){ + $table_list[$key]['tj_number']=$table_item3['uuid']; + break; + }else{ + $table_list[$key]['tj_number']=""; + } + } + + } + +// foreach ($dates as $date) { +// $res = $fzc->fz('export', [ +// 'date' => $date +// ]); +// +// // 使用 array_merge 逐个追加每日期的数据到总列表中 +// $table_list = array_merge($table_list, $res['data']['table1'] ?? []); +// $clinic_list = array_merge($clinic_list, $res['data']['table2'] ?? []); +// $table_list3 = array_merge($table_list3, $res['data']['table3'] ?? []); +// } + $template_path = Storage::path('public/excel/check_time.xlsx'); + if($table_num==1){ + $template_path = Storage::path('public/excel/check_time_table1.xlsx'); + } + if($table_num==2){ + $template_path = Storage::path('public/excel/check_time_table2.xlsx'); + } + if($table_num==3){ + $template_path = Storage::path('public/excel/check_time_table3.xlsx'); + } + if($table_num==4){ + $template_path = Storage::path('public/excel/check_time_table4.xlsx'); + } + + $spreadsheet = IOFactory::load($template_path); + $worksheet = $spreadsheet->getActiveSheet(); + $styleArray = [ + 'borders' => [ + 'allBorders' => [ + 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN, + 'color' => ['argb' => 'FF000000'], + ], + ], + ]; + + $row = 3; + $col = [ + 'A' => 'date', + 'B' => 'name', + 'C' => 'number', + 'D' => 'tj_number', // 新增列 + 'E' => 'phone', // 原 phone 列往后移动 + 'F' => 'group_name', + 'G' => 'clinic', + 'H' => 'doctor', + 'I' => 'queue', + 'J' => 'calling', + 'K' => 'done', + 'L' => 'clinic_check_time', + 'M' => 'true_check_time', + 'N' => 'timeout_check_time', + 'O' => 'clinic_wait_time', + 'P' => 'true_wait_time', + 'Q' => 'timeout_wait_time', + 'R' => 'clinic_all_time', + 'S' => 'true_all_time', + 'T' => 'timeout_all_time', + ]; + if($table_num==1){ + foreach ($table_list as $table_item) { + foreach ($col as $index => $key) { + $worksheet->setCellValueExplicit($index . $row, $table_item[$key], \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + } + $row++; + } + $worksheet->getStyle('A3:T' . ($row - 1))->applyFromArray($styleArray); + } + + $row = 3; + $col = [ + 'A' => 'group_name', + 'B' => 'clinic', + 'C' => 'doctor', + 'D' => 'check', + 'E' => 'check_out', + 'F' => 'wait', + 'G' => 'wait_out', + ]; + if($table_num==2){ + foreach ($clinic_list as $clinic_item) { + foreach ($col as $index => $key) { + $worksheet->setCellValueExplicit($index . $row, $clinic_item[$key], \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + } + $row++; + } + $worksheet->getStyle('A3:G' . ($row - 1))->applyFromArray($styleArray); + } + + + $row = 3; + $col = [ + 'A' => 'date', + 'B' => 'name', + 'C' => 'number', + 'D' => 'uuid', + 'E' => 'phone', + 'F' => 'combo', + 'G' => 'clinic_time', + 'H' => 'used_time', + 'I' => 'timeout', + ]; + //汇总信息 + $usercount=count($table_list3); + $biaozhun_timecount=0; + $shiji_timecount=0; + $chaoshi_timecount=0; + $weichaoshi_count=0; + $tj_numbers=[]; + + $peis = new PEISApiController(); + if($table_num==3){ + foreach ($table_list3 as $table_list3_i) { + $tj_numbers[]=$table_list3_i['uuid']; + $biaozhun_timecount+=$table_list3_i['clinic_time']; + $shiji_timecount+=$table_list3_i['used_time']; + $chaoshi_timecount+=$table_list3_i['timeout']; + if($table_list3_i['timeout']<=0){ + $weichaoshi_count++; + } + + $data = [ + '电话号码' => "", + '证件号码' => "", + '体检号' => $table_list3_i['uuid'], + '包含内部信息' => true + ]; + $reports = $peis::Post('体检报告查询', 1, $data); + if(isset($reports['data'][0]['套餐名称'])){ + $table_list3_i['combo']=$reports['data'][0]['套餐名称']; + }else{ + $table_list3_i['combo']=''; + } + + foreach ($col as $index => $key) { + $worksheet->setCellValueExplicit($index . $row, $table_list3_i[$key], \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + } + $row++; + } + $zhushilv=0; + if($usercount>0){ + $zhushilv=$weichaoshi_count/$usercount; + } + $worksheet->setCellValueExplicit('A' . $row, '汇总', \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $worksheet->setCellValueExplicit('B' . $row, '客户总数', \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $worksheet->setCellValueExplicit('C' . $row, $usercount, \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $worksheet->setCellValueExplicit('E' . $row, '总用时:', \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $worksheet->setCellValueExplicit('G' . $row, $biaozhun_timecount, \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $worksheet->setCellValueExplicit('H' . $row, $shiji_timecount, \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $worksheet->setCellValueExplicit('I' . $row, $chaoshi_timecount, \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $worksheet->setCellValueExplicit('B' . ($row+1), '未超时总数', \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $worksheet->setCellValueExplicit('C' . ($row+1), $weichaoshi_count, \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $worksheet->setCellValueExplicit('B' . ($row+2), "体检准时率", \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $worksheet->setCellValueExplicit('C' . ($row+2),$zhushilv , \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + + $worksheet->getStyle('A3:I' . ($row +2))->applyFromArray($styleArray); + } + + +//---------------------------vvvvvvvvvvvvvvvvvvvvvvv第四个表格,先隐藏 + /** + //准时到检率 + $jianhou_sign_count=0; + $zhunshi_count=0; + + $tj_numbers_group= array_chunk($tj_numbers, 100); + + $waitGroup=[]; + foreach ($tj_numbers_group as $index => $tj_number) { + $tj_number=implode(",", $tj_number); + $wait=$peis::Get($peis::Api('报告时间计算',$tj_number),'460107000001',"报告时间计算"); + if(isset($wait['Data'])){ + $jianhou_sign_count=$jianhou_sign_count+count($wait['Data']); + $waitGroup=array_merge($waitGroup,$wait['Data']); + } + } + + + + + //dd($wait); + + foreach ($table_list3 as $key=> $fz_value) { + foreach ($waitGroup as $index => $sx_value) { + if($fz_value['uuid']==$sx_value['体检号']){ + if($fz_value['date'].' '.$fz_value['end_time']>$sx_value['检后签到时间']){ + $zhunshi_count++; + } + } + } + } + $daojianlv=0; + if($jianhou_sign_count>0){ + $daojianlv=$zhunshi_count/$jianhou_sign_count; + } + $datesRange=$dates[0].'~'.$dates[count($dates) - 1]; + $worksheet->setCellValueExplicit('AN' . 3,$datesRange, \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $worksheet->setCellValueExplicit('AO' . 3,$zhunshi_count , \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $worksheet->setCellValueExplicit('AP' . 3,$jianhou_sign_count , \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $worksheet->setCellValueExplicit('AQ' . 3,round($daojianlv, 2) , \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $worksheet->getStyle('AN3:AQ' . 3)->applyFromArray($styleArray); + + //预约率 + $yyl_yuyue_count=0;//预约人数 + $yyl_tj_count=0;//体检总人数 + $yuyuelv=0; + $yuyueList=DB::table('orders')->whereIn('appointment_date',$dates)->whereIn('status',[2,4])->whereNotNull(['appointment_number'])->get(); + + $yyl_yuyue_count=count($yuyueList); + $yyl_tj_count=$usercount; + if($yyl_tj_count>0){ + $yuyuelv=$yyl_yuyue_count/$yyl_tj_count; + } + $worksheet->setCellValueExplicit('AN' . 7,$datesRange , \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $worksheet->setCellValueExplicit('AO' . 7,$yyl_yuyue_count , \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $worksheet->setCellValueExplicit('AP' . 7,$yyl_tj_count , \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $worksheet->setCellValueExplicit('AQ' . 7,round($yuyuelv, 2) , \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $worksheet->getStyle('AN7:AQ' . 7)->applyFromArray($styleArray); + + //预约准时率 + $yyzsl_ren_count=0;//预约准时到达人数 + $yyzsl_zong_count=0;//预约总人数 + $yyzsl_zong_count=$yyl_yuyue_count; + foreach ($yuyueList as $key=> $yy_value) { + if($yy_value->appointment_date.' '.$yy_value->appointment_time > $yy_value->check_time){ + $yyzsl_ren_count++; + } + } + $zhunshilv=0; + if($yyzsl_zong_count>0){ + $zhunshilv=$yyzsl_ren_count/$yyzsl_zong_count; + } + $worksheet->setCellValueExplicit('AN' . 11,$datesRange , \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $worksheet->setCellValueExplicit('AO' . 11,$yyzsl_ren_count , \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $worksheet->setCellValueExplicit('AP' . 11,$yyzsl_zong_count , \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $worksheet->setCellValueExplicit('AQ' . 11,round($zhunshilv, 2) , \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING); + $worksheet->getStyle('AN11:AQ' . 11)->applyFromArray($styleArray); +*/ + //-----------------------------------^^^^^^^^ + +//新建Sheet2 +// $worksheet2 = new \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet($spreadsheet, 'Sheet2'); +// $spreadsheet->addSheet($worksheet2); +// $worksheet2->setCellValue('A1', 'Foo'); +// $worksheet2->setCellValue('B1', 'Bar'); + + $file_name = Str::orderedUuid(); + $dir_path = "public/excel/" . date('Ym') . '/' . $file_name; + Storage::makeDirectory($dir_path); + $name_date = date('n.j', strtotime($date . ' 00:00:00')); + $excel_path = $dir_path . "/体检报表-时间监控$name_date.xlsx"; + $writer = new Xlsx($spreadsheet); + $writer->save(Storage::path($excel_path)); + $url = Storage::url($excel_path); + return ['status'=>true,'msg'=>'查询完成','url'=> env('APP_URL').$url]; + } + + function findFilesByDate($datePart, $basePath = 'fenzhen_tongji_temp') + { + // 获取今天的日期格式与文件中的一致 + $todayFormatted = Carbon::today()->format('Y-m-d'); + + // 遍历指定路径下的所有文件 + $files = Storage::files($basePath); + + foreach ($files as $file) { + // 使用 basename 获取文件名 + $fileName = basename($file); + + // 检查文件名是否以前缀 $datePart 开头 + if (strpos($fileName, $datePart) === 0) { + return $file; // 返回找到的文件路径 + } + } + + // 如果没有找到任何符合条件的文件,返回 null 或其他信息 + return null; + } +} diff --git a/admin/src/views/PlanMngr/Plan.vue b/admin/src/views/PlanMngr/Plan.vue index b3b8e18..e730c52 100644 --- a/admin/src/views/PlanMngr/Plan.vue +++ b/admin/src/views/PlanMngr/Plan.vue @@ -19,7 +19,7 @@ -
+
空余
预留
已占用
停用
已经使用:{{used_count}} 剩余:{{unused_count}}
统计全部
+
+ 已勾选:{{selected_count}} +
-
+
VIP @@ -184,8 +187,14 @@ 'status_tingyong':item.status===0, } } + let selected_count=ref(0) const TimeListClick=(item,index)=>{ list.value[index].selected=!list.value[index].selected + if (list.value[index].selected) { + selected_count.value++; + } else { + selected_count.value--; + } } let Info=ref({}); let dialogVisible=ref(false); diff --git a/admin/src/views/ReportForms/TiJianTime.vue b/admin/src/views/ReportForms/TiJianTime.vue index 6dae35a..f614234 100644 --- a/admin/src/views/ReportForms/TiJianTime.vue +++ b/admin/src/views/ReportForms/TiJianTime.vue @@ -8,7 +8,9 @@ - 导出体检报表时间监控 + 导出体检明细表 + 导出体检汇总表1 + 导出体检汇总表2
@@ -26,9 +28,9 @@ } from '@/api/api.js' let loading = ref(false) let dateRange = ref([]); - const ExportFenZhenInfo = () => { + const ExportFenZhenInfo = (num) => { loading.value = true - FenzhenInfoExport2({dates:dateRange.value}).then(res => { + FenzhenInfoExport2({dates:dateRange.value,table_num:num}).then(res => { loading.value = false if (res.status) { const a = document.createElement('a');