个检预约

main
yanzai 6 months ago
parent 83a8ead9ee
commit fe681ec8f8

2
.gitignore vendored

@ -0,0 +1,2 @@
/Laravel/public/uploads
/Laravel/public/health_certificate

@ -8,43 +8,79 @@ use Illuminate\Support\Facades\DB;
class AppointmentController extends Controller
{
//给第三的接口,查询预约记录
public function GetAppointmentRecord(){
date_default_timezone_set('PRC');
$sfz =request('id_card_num');
$org_sn =request('org_sn');
if(!isset($sfz)) return \Yz::echoError1('证件号不能为空');
if(!isset($org_sn)) return \Yz::echoError1('机构code不能为空');
public function GetAppointmentRecord()
{
date_default_timezone_set('PRC');
// $res_sfz = request('id_card_num');
// $org_sn = request('org_sn');
$encrypted_data = request('encrypted_data');
$iv = request('iv');
$encrypt_iv = bin2hex(random_bytes(16 / 2));
if (!isset($iv)) return \Yz::echoError1('加密时使用的iv不能为空');
$encrypted_data = \App\Lib\Tools::AESDecrypt($encrypted_data, config('app.globals.AES_KEY'), $iv);
if (!$encrypted_data) return \Yz::echoError1('encrypted_data解密失败');
$encrypted_data = json_decode($encrypted_data, true);
if (!$encrypted_data) return \Yz::echoError1('encrypted_data解密json串失败');
if (!$encrypted_data['id_card_num']) return \Yz::echoError1('id_card_num不能为空');
if (!$encrypted_data['org_sn']) return \Yz::echoError1('org_sn不能为空');
$res_sfz = $encrypted_data['id_card_num'];
$org_sn = $encrypted_data['org_sn'];
$currentYear = date('Y');
$firstDay = date('Y-01-01', strtotime($currentYear));
$lastDay = date('Y-12-31', strtotime($currentYear));
$currentYear = date('Y');
$firstDay = date('Y-01-01', strtotime($currentYear));
$lastDay = date('Y-12-31', strtotime($currentYear));
$HSM = \App\Lib\HSM::HsmEncrypt($res_sfz);
if ($HSM['status'] != true) {
return \Yz::echoError1('调用HSM加密失败');
}
$sfz = $HSM['data'];
$info_data = [];
if (isset($sfz)) {
$info = DB::table('appointment_record as a')
->select('a.id', 'a.name', 'a.sex', 'a.tel', 'a.id_card_num', 'a.date', 'a.time', 'a.type', 'a.fee_type as free_type', 'a.doc_type_id', 'a.org_code as org_sn', 'a.org_name', 'a.doc_type_name', 'a.created_at', 'b.org_name')
->join('medical_institution as b', 'a.org_code', '=', 'b.sn')
->where(['a.id_card_num' => $sfz, 'a.is_del' => 0, 'a.org_code' => $org_sn])
->whereBetween('a.created_at', [$firstDay, $lastDay])->orderBy('a.id', 'desc')->first();
$HSM=\App\Lib\HSM::HsmEncrypt($sfz);
if($HSM['status']!=true){
return \Yz::echoError1('调用HSM加密失败');
}
$sfz=$HSM['data'];
$infos=[];
if(isset($sfz)){
$info=DB::table('appointment_record as a')
->select('a.id','a.name','a.sex','a.tel','a.id_card_num','a.date','a.time','a.type','a.fee_type as free_type','a.doc_type_id','a.org_code as org_sn','a.org_name','a.doc_type_name','a.created_at','b.org_name')
->join('medical_institution as b','a.org_code','=','b.sn')
->where(['a.id_card_num'=>$sfz,'a.is_del'=>0,'a.org_code'=>$org_sn])
->whereBetween('a.created_at',[$firstDay,$lastDay])->orderBy('a.id','desc')->first();
if (!!$info) {
//查询相关图片
$imgs = [];
$imgs = DB::table('appointment_img')
->select('type', 'imgurl')
->where(['appointment_record_id' => $info->id])->get();
foreach ($imgs as $key => $item) {
//此处应该 把完整的url 拼接上
$imgs[$key]->imgurl = env('ZHUAN_WANG').$imgs[$key]->imgurl;
}
$info->files = $imgs;
$info->id_card_num = $sfz;
// $infos= $info;
$info_data = [
'type' => $info->type,
'name' => $info->name,
'id_card_num' => $info->id_card_num,
'sex' => $info->sex,
'tel' => $info->tel,
'date' => $info->date,
'time' => $info->time,
'free_type' => $info->free_type,
'doc_type_id' => $info->doc_type_id,
'doc_type_name' => $info->doc_type_name,
'org_sn' => $info->org_sn,
'org_name' => $info->org_name,
'files' => $info->files,
];
}
$info_data = json_encode($info_data, JSON_UNESCAPED_UNICODE);
return \Yz::Return(true, '查完完成', ['info' =>$this->AESEncrypt($info_data, $encrypt_iv) , 'iv' => $encrypt_iv]);
}
}
if(!!$info){
//查询相关图片
$imgs=[];
$imgs=DB::table('appointment_img')->where(['appointment_record_id'=>$info->id])->get();
foreach ($imgs as $key=>$item){
$imgs[$key]->imgurl=env('APP_URL').$item->imgurl;
}
$info->files=$imgs;
$info->id_card_num=request('id_card_num');
$infos[]=$info;
}
return \Yz::Return(true,'查完完成',$infos);
}
}
function AESEncrypt($data, $encrypt_iv)
{
// return $data;
return \App\Lib\Tools::AESEncrypt($data, config('app.globals.AES_KEY'), $encrypt_iv);
}
}

@ -13,9 +13,18 @@ use Illuminate\Support\Facades\Validator;
class CheckUpController extends Controller
{
//给第三的接口,创建体检记录
public function CreateCheckupRecord(Request $request){
public function CreateCheckupRecord(Request $request)
{
// 验证请求数据
$validator = Validator::make($request->all(), [
$encrypted_data = request('encrypted_data');
$iv = request('iv');
$encrypt_iv = bin2hex(random_bytes(16 / 2));
if (!isset($iv)) return \Yz::echoError1('加密时使用的iv不能为空');
$encrypted_data = \App\Lib\Tools::AESDecrypt($encrypted_data, config('app.globals.AES_KEY'), $iv);
if (!$encrypted_data) return \Yz::echoError1('encrypted_data解密失败');
$encrypted_data = json_decode($encrypted_data, true);
$validator = Validator::make($encrypted_data, [
'checkup_info.type' => 'required|integer',
'checkup_info.free_type' => 'required|integer',
'checkup_info.name' => 'required|string',
@ -40,68 +49,146 @@ class CheckUpController extends Controller
]);
if ($validator->fails()) {
return \Yz::echoError1( $validator->errors());
return \Yz::echoError1($validator->errors());
}
$checkupInfo = $encrypted_data['checkup_info'];
$checkupInfo['institution_sn'] = $checkupInfo['org_sn'];
$checkupInfo['industry_type'] = $checkupInfo['doc_type_name'];
$checkupInfo['register_time'] = $checkupInfo['tijian_time'];
$checkupInfo['issue_time'] = null;
$checkupInfo['expire_time'] = null;
$checkupInfo['is_sanfang'] = 1;
$s = app()->make(HealthCheckupService::class);
$res = $s->CreateRecord($checkupInfo);
if ($res['status'] !== true) {
return \Yz::echoError1($res['msg']);
} else {
$msg = "记录完成";
if ($checkupInfo['type'] == 1 and $checkupInfo['free_type'] == 0) {
$msg = $msg . ",免费用户请调用上传资料接口上传相关证明文件,否则无效。";
}
$send_data = ["tijian_num" => $checkupInfo['tijian_num']];
$send_data = json_encode($send_data, JSON_UNESCAPED_UNICODE);
return \Yz::Return(true, $msg, ['info' => $this->AESEncrypt($send_data, $encrypt_iv), 'iv' => $encrypt_iv]);
}
$checkupInfo = $request->input('checkup_info');
$checkupInfo['institution_sn']=$checkupInfo['org_sn'];
$checkupInfo['industry_type']=$checkupInfo['doc_type_name'];
$checkupInfo['register_time']=$checkupInfo['tijian_time'];
$checkupInfo['issue_time']=null;
$checkupInfo['expire_time']=null;
$s=app()->make(HealthCheckupService::class);
return $s->CreateRecord($checkupInfo);
}
//给第三的接口上传体检结果pdf文档
public function UploadPdf(Request $request){
public function UploadPdf(Request $request)
{
$encrypted_data = request('encrypted_data');
$iv = request('iv');
$encrypt_iv = bin2hex(random_bytes(16 / 2));
if (!isset($iv)) return \Yz::echoError1('加密时使用的iv不能为空');
$encrypted_data = \App\Lib\Tools::AESDecrypt($encrypted_data, config('app.globals.AES_KEY'), $iv);
if (!$encrypted_data) return \Yz::echoError1('encrypted_data解密失败');
$decrypted_data = json_decode($encrypted_data, true);
//dd($decrypted_data);
// 验证请求数据
$validator = Validator::make($request->all(), [
$validator = Validator::make($decrypted_data, [
'type' => 'required|integer', //1证明材料2报告材料pdf
'tijian_num' => 'required|string',
'org_sn' => 'required|string',
'files' => 'required|array',
'files.*' => 'required|file|mimes:pdf|max:2048',// 每个文件必须是PDF格式且大小不超过2MB
// 'files.*' => 'required|file|mimes:pdf,jpg,png,webp|max:2048',// 每个文件必须是PDF格式且大小不超过2MB
]);
if ($validator->fails()) {
return \Yz::echoError1( $validator->errors());
return \Yz::echoError1($validator->errors());
}
$type = $decrypted_data['type'];
//查询体检号是否存在
$service=new OrgService();
$res=$service->GetOrgInfo($request->input('org_sn'));
if($res['status']!==true){
$service = new OrgService();
$res = $service->GetOrgInfo($decrypted_data['org_sn']);
if ($res['status'] !== true) {
return \Yz::echoError1($res['msg']);
}
//查询体检号是否存在
$checkupInfo=DB::table('examination_records')
$checkupInfo = DB::table('examination_records')
->where([
'tijian_num'=>$request->input('tijian_num'),
'institution_id'=>$res['data']->id,
])->orderBy('id','desc')->first();
if(!$checkupInfo){
'tijian_num' => $decrypted_data['tijian_num'],
'institution_id' => $res['data']->id,
])->orderBy('id', 'desc')->first();
if (!$checkupInfo) {
return \Yz::echoError1("体检号不存在");
}
if ($request->hasFile('files') && $request->file('files')) {
$filesUrls=[];
foreach ($request->file('files') as $file) {
// 检查文件是否有效
if ($file->isValid()) {
// 定义存储路径
$path = 'uploads/pdfs/' . date('Ymd'); // 根据当前日期创建子目录
// if ($request->hasFile('files') && $request->file('files')) {
if (count($decrypted_data['files']) > 0) {
$filesUrls = [];
if ($type == 1) {
$path = 'uploads/sanfang_img/' . date('Ymd'); // 根据当前日期创建子目录
}
if ($type == 2) {
$path = 'uploads/pdfs/' . date('Ymd'); // 根据当前日期创建子目录
}
$mimeTypeToExtension = [
'image/png' => 'png',
'image/jpeg' => 'jpg',
'application/pdf' => 'pdf',
];
foreach ($decrypted_data['files'] as $file) {
// 保存文件到磁盘
$fullPath = public_path($path);
if (!is_dir($fullPath)) {
mkdir($fullPath, 0777, true); // 创建目录,包括必要的父目录
}
$file_data = \App\Lib\Tools::AESDecrypt($file, config('app.globals.AES_KEY'), $iv);
// 检查文件大小是否超过2MB
$fileSize = strlen($file_data); // 获取文件数据的长度(字节数)
if ($fileSize > 2 * 1024 * 1024) { // 如果文件大小超过2MB
return \Yz::echoError1("文件大小超过2MB上传被拒绝。");
}
$finfo = finfo_open();
// 根据文件内容获取其MIME类型
$mimeType = finfo_buffer($finfo, $file_data, FILEINFO_MIME_TYPE);
// 关闭finfo资源
finfo_close($finfo);
// dd($mimeType);
if (array_key_exists($mimeType, $mimeTypeToExtension)) {
$file_extension = $mimeTypeToExtension[$mimeType];
} else {
return \Yz::echoError1("获取文件格式失败");
}
$filename = uniqid() . '_' . mt_rand(0, 999999) . '.' . $file_extension;
// 定义存储路径
file_put_contents($fullPath . '/' . $filename, $file_data);
// $file->storeAs($path, $filename, 'public'); // 使用 'public' 磁盘
$filesUrls[] = '/storage/' . $path . '/' . $filename;
// 保存文件到磁盘
$filename = uniqid() . '_' . $file->getClientOriginalName();
$file->storeAs($path, $filename, 'public'); // 使用 'public' 磁盘
$filesUrls[]=env('APP_URL').'/storage/'.$path.'/'.$filename;
}
if ($type == 1) {
foreach ($filesUrls as $fileUrl) {
$insert_img = DB::table('appointment_img')->insert([
'type' => 9,//通用证明材料
'imgurl' => $fileUrl,
'examination_records_id' => $checkupInfo->id,
]);
}
if ($insert_img) {
$u = DB::table('examination_records')->where('id', $checkupInfo->id)->update(['is_has_file' => 1, 'updated_at' => date('Y-m-d H:i:s')]);
}
}
$u=DB::table('examination_records')->where('id',$checkupInfo->id)->update(['pdfs'=>json_encode($filesUrls,JSON_UNESCAPED_UNICODE)]);
if(!$u){
if ($type == 2) {
$u = DB::table('examination_records')->where('id', $checkupInfo->id)->update(['pdfs' => json_encode($filesUrls, JSON_UNESCAPED_UNICODE), 'updated_at' => date('Y-m-d H:i:s')]);
}
if (!$u) {
return \Yz::echoError1("上传文件失败");
}
return \Yz::Return(true,'上传成功',[]);
$send_data = ["tijian_num" => $checkupInfo->tijian_num];
$send_data = json_encode($send_data, JSON_UNESCAPED_UNICODE);
return \Yz::Return(true, '上传成功', ['info' => $this->AESEncrypt($send_data, $encrypt_iv), 'iv' => $encrypt_iv]);
}
return \Yz::echoError1("上传文件失败");
}
function AESEncrypt($data, $encrypt_iv)
{
// return $data;
return \App\Lib\Tools::AESEncrypt($data, config('app.globals.AES_KEY'), $encrypt_iv);
}
}

@ -29,7 +29,7 @@ class OrganizationController extends Controller
$group = $request->get('role');//中间件产生的参数
$subinfo=request('subinfo');
if(isset($openid) and isset($subinfo)){
foreach ($subinfo as $info){
foreach ($subinfo as $key=> $info){
if(!isset($info)) return \Yz::echoError1("部分参数不完整");
}

@ -55,10 +55,8 @@ class Tools{
if (strlen($idCard) != 18) {
return null;
}
// 获取身份证号的第17位
$genderBit = intval($idCard[16]);
// 判断性别
if ($genderBit % 2 == 0) {
return 0;
@ -66,4 +64,31 @@ class Tools{
return 1;
}
}
//AES加密
public static function AESEncrypt($data, $key,$iv){
// 使用openssl_encrypt进行加密
$encryptedData = openssl_encrypt(
$data,
'AES-256-CBC',
$key,
OPENSSL_RAW_DATA,
$iv
);
// 返回包含IV的加密数据通常会将IV放在加密数据之前
return base64_encode( $encryptedData);
}
//AES解密
public static function AESDecrypt($data, $key,$iv){
// 解码base64编码的数据
$data = base64_decode($data);
$encryptedData = $data;
// 使用openssl_decrypt进行解密
return openssl_decrypt(
$encryptedData,
'AES-256-CBC',
$key,
OPENSSL_RAW_DATA,
$iv
);
}
}

@ -22,7 +22,8 @@ class HealthCheckupService
//HSM加密
$HSM_sfz =\App\Lib\HSM::HsmEncrypt($CheckupInfo['id_card_num']);
if($HSM_sfz['status']!=true){
return \Yz::echoError1('调用HSM加密失败');
//return \Yz::echoError1('调用HSM加密失败');
return ['status'=>false,'msg'=>'调用HSM加密失败'];
}
$CheckupInfo['id_card_num']=$HSM_sfz['data'];
@ -35,12 +36,12 @@ class HealthCheckupService
// }
$org_id=DB::select("select id from medical_institution where sn=?",[$CheckupInfo['institution_sn']]);
if(count($org_id)!=1) return \Yz::echoError1('机构码不存在');
if(count($org_id)!=1) return ['status'=>false,'msg'=>'机构码不存在'];
$status=false;
//检查体检流水号是否存在,存在禁止再次插入。
$check_cunzai=DB::table('examination_records')->where(['tijian_num'=>$CheckupInfo['tijian_num'],'institution_id'=>$org_id[0]->id])->get();
if(count($check_cunzai)>0) return \Yz::echoError1('此体检号已经存在,禁止创建');
if(count($check_cunzai)>0) return ['status'=>false,'msg'=>'此体检号已经存在,禁止创建'];
DB::beginTransaction(); // 开始事务
try {
@ -74,13 +75,16 @@ class HealthCheckupService
if(isset($CheckupInfo['tel'])){
$HSM_tel =\App\Lib\HSM::HsmEncrypt($CheckupInfo['tel']);
if($HSM_tel['status']!=true){
return \Yz::echoError1('调用HSM加密失败');
// return \Yz::echoError1('调用HSM加密失败');
return ['status'=>false,'msg'=>'调用HSM加密失败'];
}
$CheckupInfo['tel']=$HSM_tel['data'];
}
$Hmac=\App\Lib\HSM::Hmac($CheckupInfo['name'].$CheckupInfo['id_card_num'].$CheckupInfo['tel'].$CheckupInfo['result_status']);
if($Hmac['status']!=true){
return \Yz::echoError1('HMAC摘要失败');
// return \Yz::echoError1('HMAC摘要失败');
return ['status'=>false,'msg'=>'HMAC摘要失败'];
}
$u2=DB::table('examination_records')->insertGetId([
@ -104,6 +108,7 @@ class HealthCheckupService
"expire_time"=>$CheckupInfo['expire_time'],
"pdfs"=>isset($CheckupInfo['pdfs'])?json_encode($CheckupInfo['pdfs']):'',
'hmac'=>$Hmac['data'],
'is_sanfang'=>isset($CheckupInfo['is_sanfang'])?$CheckupInfo['is_sanfang']:0,
]);
@ -135,9 +140,9 @@ class HealthCheckupService
}
if($status){
return \Yz::Return(true,'记录完成',["num"=>$CheckupInfo['tijian_num']]);
return ['status'=>true,'msg'=>'记录完成','data'=>["num"=>$CheckupInfo['tijian_num']]];
}else{
return \Yz::echoError1("操作失败");
return ['status'=>false,'msg'=>'操作失败'];
}
}

@ -82,38 +82,46 @@ class OrganizationService
$currentYear = date('Y');
$firstDay = date('Y-01-01', strtotime($currentYear));
$lastDay = date('Y-12-31', strtotime($currentYear));
if($type==1){
$month=config('app.globals.HealthyCardTimeRange');
//如果是健康证体检,则先查寻是否有体检记录
$cha_jkz=DB::table('examination_records')->where(['id_card_num'=>$cha_info[0]->id_card_num])->orderBy('id','desc')->first();
//,如果有判断是否快到期(先不判断是否体检通过),能否继续预约
if(!!$cha_jkz){
$date = new DateTime($cha_jkz->created_at);
$date->modify('+'.$month.' months');
$now = new DateTime();
if ($date > $now) {
return \Yz::Return(false,'本年度已经体检过,请于:'. $date->format('Y-m-d H:i:s').'后再进行预约');
$free_type=0;
if(isset($info['is_zifei']) and $info['is_zifei']=='zifei'){
//自费忽略判断资格,多少次都行
$free_type=1;
}else{
//如果是免费体检判断资格
if($type==1){
$month=config('app.globals.HealthyCardTimeRange');
//如果是健康证体检,则先查寻是否有体检记录
$cha_jkz=DB::table('examination_records')->where(['id_card_num'=>$cha_info[0]->id_card_num,'fee_type'=>0,'is_del'=>0])->orderBy('id','desc')->first();
//,如果有判断是否快到期(先不判断是否体检通过),能否继续预约
if(!!$cha_jkz){
$date = new DateTime($cha_jkz->created_at);
$date->modify('+'.$month.' months');
$now = new DateTime();
if ($date > $now) {
return \Yz::Return(false,'本年度已经体检过,请于:'. $date->format('Y-m-d H:i:s').'后再进行预约');
}
}
//查询是否有预约记录
$currentDate = date('Y-m-d');
$firstDay = date('Y-m-d', strtotime('-'.$month.' months', strtotime($currentDate)));
// $firstDay = date('Y-01-01', strtotime($currentYear));
$lastDay = date('Y-12-31', strtotime($currentYear));
}
//查询是否有预约记录
$currentDate = date('Y-m-d');
$firstDay = date('Y-m-d', strtotime('-'.$month.' months', strtotime($currentDate)));
// $firstDay = date('Y-01-01', strtotime($currentYear));
$lastDay = date('Y-12-31', strtotime($currentYear));
}
$cha=DB::table('appointment_record')->where([['id_card_num','=',$cha_info[0]->id_card_num],['is_del','=','0'],['created_at','>',$firstDay],['created_at','<',$lastDay],'fee_type'=>0])->whereIn('status',[1,2])->get();
if(count($cha)) {
return \Yz::Return(false,'本年度已经预约过,无法继续预约');
}
//判断是否免费体检过
$s=app()->make(PersonService::class);
$char=$s->GetPersonRecode(['openid'=>$openid,'group'=>$group]);
$cha=DB::table('appointment_record')->where([['id_card_num','=',$cha_info[0]->id_card_num],['is_del','=','0'],['created_at','>',$firstDay],['created_at','<',$lastDay]])->whereIn('status',[1,2])->get();
if(count($cha)) {
return \Yz::Return(false,'本年度已经预约过,无法继续预约');
if(!$char['status']){
return \Yz::Return(false,$char['msg']);
}
}
//判断是否免费体检过
$s=app()->make(PersonService::class);
$char=$s->GetPersonRecode(['openid'=>$openid,'group'=>$group]);
if(!$char['status']){
return \Yz::Return(false,$char['msg']);
}
//判断预约的时间是否可行
$q_date=DB::table('institutional_calendar')->select(['date','time','count'])->where(['id'=>$info['calendar_id'],'status'=>1])->where('end_time','>',$nowtime)->get();
if(!count($q_date)){
@ -151,7 +159,7 @@ class OrganizationService
'openid'=>$openid,
'date'=>$q_date[0]->date,
'time'=>$q_date[0]->time,
'fee_type'=>0,
'fee_type'=>$free_type,
'doc_type_id'=>$info['doc_id'],
'doc_type_name'=>$info['doc_name'],
'org_id'=>$info['org_id'],
@ -176,7 +184,7 @@ class OrganizationService
'openid'=>$openid,
'date'=>$q_date[0]->date,
'time'=>$q_date[0]->time,
'fee_type'=>0,
'fee_type'=>$free_type,
'org_id'=>$info['org_id'],
'org_code'=>$jgINfo->sn,
'status'=>1,

@ -85,7 +85,7 @@ class PersonService
//查询体检记录表 免费体检记录
$c=DB::table('examination_records as a') ->join('medical_institution as b', 'a.institution_id', '=', 'b.id')
->select(['a.id','a.institution_id','a.id_card_num','a.tijian_num','a.tijian_time','a.created_at as insertime','b.org_name'])->where([['a.id_card_num','=',$id_num],['a.created_at','>=',$firstDay],['a.created_at','<=',$lastDay]])->get();
->select(['a.id','a.institution_id','a.id_card_num','a.tijian_num','a.tijian_time','a.created_at as insertime','b.org_name'])->where([['a.id_card_num','=',$id_num],['a.created_at','>=',$firstDay],['a.created_at','<=',$lastDay],'a.fee_type'=>0])->get();
if(count($c)>0){
$result['status']=false;
$result['msg']='已体检过';

@ -15,6 +15,7 @@ return [
'GongWeiBaseUrl'=>'http://114.242.58.53:8082/jkdacp/webservice/DPService?wsdl', //公卫接口地址,外网测试地址
'HealthyCardTimeRange'=>11,//健康证过期时间跨度 单位 月
'AES_KEY'=>'5Kj9P1pL0f8e7Vw3I2qX4mT6zJ1OxWcQ',//AES加密秘钥
],

Loading…
Cancel
Save