From 01bac4f4a4ff7d0cc0fe5681e0ac77402410f41d Mon Sep 17 00:00:00 2001 From: weiz Date: Sat, 4 Nov 2023 16:28:09 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=90=88=E5=90=8C=E7=AE=A1?= =?UTF-8?q?=E7=90=86=E4=B9=8B=E4=B8=89=E8=BD=AE=E8=BD=A6=E5=90=88=E5=90=8C?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/adminapi/controller/UploadController.php | 21 +- .../contract/VehicleContractController.php | 301 ++++++++++ app/api/controller/HeTongController.php | 92 ++++ app/api/controller/NotifyController.php | 516 ++++++++++++++++++ app/api/service/ApiSignService.php | 2 +- app/common.php | 32 ++ app/common/controller/JunziqianController.php | 490 +++++++++++++++++ app/common/enum/notice/NoticeEnum.php | 17 + app/common/model/company/Company.php | 68 +++ app/common/model/contract/Contract.php | 11 + app/common/model/contract/VehicleContract.php | 11 + app/common/model/vehicle/VehicleBuyRecord.php | 11 + app/common/model/vehicle/VehicleRent.php | 11 + app/common/service/UploadService.php | 121 +++- app/common/service/storage/engine/Server.php | 2 +- composer.json | 3 +- config/database.php | 8 +- config/project.php | 5 + 18 files changed, 1688 insertions(+), 34 deletions(-) create mode 100644 app/adminapi/controller/contract/VehicleContractController.php create mode 100644 app/api/controller/HeTongController.php create mode 100644 app/api/controller/NotifyController.php create mode 100644 app/common/controller/JunziqianController.php create mode 100644 app/common/model/company/Company.php create mode 100644 app/common/model/contract/Contract.php create mode 100644 app/common/model/contract/VehicleContract.php create mode 100644 app/common/model/vehicle/VehicleBuyRecord.php create mode 100644 app/common/model/vehicle/VehicleRent.php diff --git a/app/adminapi/controller/UploadController.php b/app/adminapi/controller/UploadController.php index 1bee7dd3..cb1999bb 100644 --- a/app/adminapi/controller/UploadController.php +++ b/app/adminapi/controller/UploadController.php @@ -32,7 +32,7 @@ class UploadController extends BaseAdminController * @author 段誉 * @date 2021/12/29 16:27 */ - public function image() + public function image(): Json { try { $cid = $this->request->post('cid', 0); @@ -49,7 +49,7 @@ class UploadController extends BaseAdminController * @author 段誉 * @date 2021/12/29 16:27 */ - public function video() + public function video(): Json { try { $cid = $this->request->post('cid', 0); @@ -59,5 +59,22 @@ class UploadController extends BaseAdminController return $this->fail($e->getMessage()); } } + + /** + * @notes 上传文件 + * @return Json + * @author 段誉 + * @date 2021/12/29 16:27 + */ + public function file(): Json + { + try { + $cid = $this->request->post('cid', 0); + $result = UploadService::file($cid); + return $this->success('上传成功', $result); + } catch (Exception $e) { + return $this->fail($e->getMessage()); + } + } } \ No newline at end of file diff --git a/app/adminapi/controller/contract/VehicleContractController.php b/app/adminapi/controller/contract/VehicleContractController.php new file mode 100644 index 00000000..d1672daa --- /dev/null +++ b/app/adminapi/controller/contract/VehicleContractController.php @@ -0,0 +1,301 @@ +request->post(['id','file','cars']); + if(empty($params['id']) || empty($params['file'])){ + return $this->fail('缺少必要参数'); + } + //获取合同信息 + $vehicle_contract = VehicleContract::where('id',$params['id'])->findOrEmpty(); + if($vehicle_contract->isEmpty()){ + return $this->fail('合同信息错误'); + } + if($vehicle_contract['type']==0 && $vehicle_contract['contract_logistic_id'] != 0){ + if(empty($params['cars'])){ + return $this->fail('缺少必要参数cars'); + } + $cars = json_decode($params['cars'],true); + if(empty($cars)){ + return $this->fail('参数cars无效'); + } + } + if($vehicle_contract['status'] != 0){ + return $this->fail('合同状态错误'); + } + //更新本地 + try { + $data = [ + 'id' => $vehicle_contract['contract_logistic_id'], + 'file' => $params['file'], + 'status' => 1, + ]; + //判断合同类型 + if($vehicle_contract['type'] == 0 && $vehicle_contract['contract_logistic_id'] != 0){ + $data['cars_info'] = $params['cars']; + } + if(!empty($vehicle_contract['contract_logistic_id'])){ + //更新物流系统 + curl_post(env('project.logistic_domain').'/api/contractUpdate',$data); + } + unset($data['id']); + VehicleContract::where('id', $params['id'])->update($data); + + }catch (\Exception $e){ + return $this->fail($e->getMessage()); + } + return $this->success('上传成功', [], 1, 1); + } + + //风控中心发起合同 + public function initiatingRentCarContract(): Json + { + //获取参数 + $params = $this->request->post(['id']); + if(empty($params['id'])){ + return $this->fail('缺少必要参数'); + } + //获取数据 + $contract = VehicleContract::where('id',$params['id'])->findOrEmpty(); + if($contract->isEmpty()){ + return $this->fail('数据不存在'); + } + if(!($contract['status'] == 1 || ($contract['status'] == 2 && $contract['signing_timer'] != 2))){ + return $this->fail('合同状态错误'); + } + $signData = [ + 'name' => $contract['company_a_name'] . '的合同', + 'signatories' => [ + ['fullName' => $contract['company_a_name'], 'identityType' => 12, 'identityCard' => $contract['company_a_code'], 'email' => $contract['company_a_email'], 'noNeedVerify' => 1, 'signLevel' => 1], + ['fullName' => $contract['company_b_name'], 'identityType' => 12, 'identityCard' => $contract['company_b_code'], 'email' => $contract['company_b_email'], 'noNeedVerify' => 1, 'signLevel' => 1] + ], + 'url' => $contract['file'] + ]; + $notify_url = ''; + if($contract['type'] == 0){ + $smsTitle = '《租赁合同》'; + if(empty($contract['contract_logistic_id'])){ + $notify_url = env('project.website_domain').'/api/notify/systemCarRent'; + }else{ + $notify_url = env('project.website_domain').'/api/notify/townCarRent'; + } + }elseif($contract['type'] == 1){ + $smsTitle = '《自有车辆上传合同》'; + $notify_url = env('project.website_domain').'/api/notify/selfCarRent'; + }elseif($contract['type'] == 2){ + $smsTitle = '《解约合同》'; + $notify_url = env('project.website_domain').'/api/notify/cancelRent'; + }elseif($contract['type'] == 3){ + $smsTitle = '《购买合同》'; + $notify_url = env('project.website_domain').'/api/notify/buyCar'; + } + $signRes = app(JunziqianController::class)->VehicleRentSigning($signData, $params['id'],$notify_url); + if ($signRes->success) { + $contract->save([ + 'id' => $contract['id'], + 'contract_no' => $signRes->data, + 'status' => 2, + 'signing_timer' => 0 + ]); + if(!empty($contract['contract_logistic_id'])){ + curl_post(env('project.logistic_domain').'/api/contractUpdate',[],[ + 'id' => $contract['contract_logistic_id'], + 'contract_no' => $signRes->data, + 'status' => 2, + 'signing_timer' => 0 + ]); + } + $this->sendSms($params['id'],$smsTitle); + return $this->success('合同发送成功'); + } else { + return $this->fail($signRes->msg); + } + } + + public function sendSmsAgain(): Json + { + //获取参数 + $id = $this->request->post('id'); + if(empty($id)){ + return $this->fail('参数错误'); + } + //获取数据 + $contract = VehicleContract::where('id',$id)->find(); + if(empty($contract)){ + return $this->fail('数据错误'); + } + if($contract['type'] == 0){ + $smsTitle = '《租赁合同》'; + }elseif($contract['type'] == 1){ + $smsTitle = '《自有车辆上传合同》'; + }elseif($contract['type'] == 2){ + $smsTitle = '《解约合同》'; + }else{ + $smsTitle = '《购买合同》'; + } + $this->sendSms($id,$smsTitle); + return $this->success('发送成功'); + } + + public function sendSms($id,$title): bool{ + //获取合同数据 + $contract = VehicleContract::where('id',$id)->findOrEmpty(); + if (!$contract->isEmpty() && $contract['file'] != '') { + //发送短信 + $data = [ + //甲方 + [ + "applyNo" => $contract['contract_no'], + "fullName" => $contract['company_a_name'], + "identityCard" => $contract['company_a_code'], + "identityType" => 12, + "master_phone" => $contract['company_a_phone'], + "type"=>"party_a" + ], + //乙方 + [ + "applyNo" => $contract['contract_no'], + "fullName" => $contract['company_b_name'], + "identityCard" => $contract['company_b_code'], + "identityType" => 12, + "master_phone" => $contract['company_b_phone'], + "type"=>"party_b" + + ], + ]; + + $url = []; + foreach ($data as $v) { + $res = app(JunziqianController::class)->SigningLink($v); + if (!$res->success) { + return false; + } + if ($v['type'] == 'party_a') { + $url['party_a'] =$res->data; + } else { + $url['party_b'] =$res->data; + } + //发送短信 + $sms = [ + 'mobile' => $v['master_phone'], + 'name' => $v['fullName'], + 'type' => $title, + 'code' => 'api/HeTong/info?id='.$id.'&type='.$v['type'], + 'scene' => 'WQ' + ]; + $scene = NoticeEnum::getSceneByTag($sms['scene']); + if (empty($scene)) { + throw new \Exception('场景值异常'); + } + //发送短信 + event('Notice', [ + 'scene_id' => $scene, + 'params' => $sms + ]); + } + VehicleContract::where('id', $id)->update(['url' => json_encode($url)]); + return true; + }else{ + return false; + } + } + + public function lists(): Json + { + $param = $this->request->get(); + $where = []; + if(isset($param['company_name'])){ + $where[] = ['company_b_name','like','%'.$param['company_name'].'%']; + } + if(isset($param['contract_no'])){ + $where[] = ['contract_no','like','%'.$param['contract_no'].'%']; + } + if(isset($param['status']) && in_array($param['status'],[0,1])){ + if($param['status'] == 1){ + $where[] = ['status','in', '1,2,3']; + }else{ + $where[] = ['status','=', $param['status']]; + } + }else{ + $where[] = ['status','in', '0,1,2,3']; + } + $pageNo = !empty($param['page_no']) ? $param['page_no'] : 1; + $pageSize = !empty($param['page_size']) ? $param['page_size'] : 15; + $data = VehicleContract::where($where) + ->page($pageNo, $pageSize) + ->order('create_time desc') + ->select()->each(function($item){ + $item['cars_info'] = json_decode($item['cars_info'],true); + }); + return $this->success('success',['lists'=>$data->toArray(),'page_no'=>$pageNo,'page_size'=>$pageSize,'count'=>$data->count()]); + } + + public function detail(): Json + { + $id = $this->request->get('id'); + if(empty($id)){ + $this->fail('参数错误'); + } + $data = VehicleContract::where('id',$id)->findOrEmpty(); + if($data->isEmpty()){ + return $this->fail('未查找到数据'); + } + $cars = json_decode($data['cars_info'],true); + //判断合同类型 + if(!empty($data['contract_logistic_id']) && $data['type'] == 0){ + $carList = curl_get(env('project.logistic_domain').'/api/getAvailableVehicles'); + $data['car_list'] = $carList&&$carList['code']==1 ? $carList['data'] : []; + } + if(!empty($cars)){ + foreach ($cars as $k=>$v) { + if($data['type'] == 0){ + $cars[$k]['type'] = 0; + } + if($data['type'] == 1){ + if(empty($v['id'])){ + $cars[$k]['type'] = 1; + }else{ + $rentInfo = VehicleRent::where('car_id',$v['id'])->findOrEmpty(); + if($rentInfo->isEmpty()){ + $cars[$k]['type'] = 0; + }else{ + $cars[$k]['type'] = $rentInfo['type']; + } + } + } + if($data['type'] == 2){ + $rentInfo = VehicleRent::where('car_id',$v['id'])->findOrEmpty(); + if($rentInfo->isEmpty()){ + $cars[$k]['type'] = 0; + }else{ + $cars[$k]['type'] = $rentInfo['type']; + } + } + if($data['type'] == 3){ + $rentInfo = VehicleRent::where('car_id',$v['id'])->findOrEmpty(); + if($rentInfo->isEmpty()){ + $cars[$k]['type'] = 2; + }else{ + $cars[$k]['type'] = $rentInfo['type']; + } + } + $cars[$k]['rent_time'] = $data['update_time']; + } + } + $data['cars_info'] = $cars; + return $this->success('success',$data->toArray()); + } + } \ No newline at end of file diff --git a/app/api/controller/HeTongController.php b/app/api/controller/HeTongController.php new file mode 100644 index 00000000..638bd2ee --- /dev/null +++ b/app/api/controller/HeTongController.php @@ -0,0 +1,92 @@ +get('id'); + $type = Request()->get('type'); + $params = Request()->param(); + $msg='合同不存在'; + if(empty($type)){ + $msg='参数错误'; + } + if (isset($params['t']) && $params['t'] == 1) { + $find = Db::name('shop_contract')->where('id', $id)->find(); + if ($find && $find['url']) { + $url = json_decode($find['url'], true); + if(isset($url[$type])){ + return redirect($url[$type]); + } + } + } + if ($id && $type) { + $find = Db::name('contract')->where('id', $id)->find(); + if ($find && $find['url']) { + $url = json_decode($find['url'], true); + if(isset($url[$type])){ + return redirect($url[$type]); + } + } + } + return '

:)

'.$msg.'

'; + } + + public function info(){ + $params = $this->request->get(['id','type']); + if(empty($params['id']) || empty($params['type'])){ + return $this->fail('缺少必要参数'); + } + $find = VehicleContract::where('id', $params['id'])->find(); + if (!empty($find) && $find['url']) { + $url = json_decode($find['url'], true); + if(isset($url[$params['type']])){ + return redirect($url[$params['type']]); + } + } + return '

:)

'; + } + + // 用户做人脸识别时,作跳板的短信链接 + public function toFaceCreate(): string|\think\response\Redirect + { + $id = Request()->get('id'); + $msg='地址不存在'; + if ($id) { + $find = Db::name('company')->where('id', $id)->find(); + if ($find && $find['face_create_url']) { + return redirect($find['face_create_url']); + } else { + $msg='参数错误'; + } + } + return '

:)

'.$msg.'

'; + } + + public function notifyOrganizationFaceCreate(): string + { + $parmas = Request()->param(); + Log::info(['人脸识别采集校验回调:',$parmas]); + $result = json_decode($parmas['data'], true); + $msg = '人脸采集成功'; + if (isset($result['status']) && $result['status'] == 1) { + // 修改人脸采集状态 + Company::where(['organization_code'=>$result['organizationRegNo']])->update(['face_create_status'=>1]); + } else { + $msg = '采集失败,原因:'.$result['msg']; + // 记录错误日志 + Db::name('company_authentication_fail_log')->insert(['company_id'=>$result['orderNo'], 'log_type'=>2,'fail_reason'=>$msg, 'create_time'=>time()]); + } + return '

:)

'.$msg.'

'; + } + } \ No newline at end of file diff --git a/app/api/controller/NotifyController.php b/app/api/controller/NotifyController.php new file mode 100644 index 00000000..58240b67 --- /dev/null +++ b/app/api/controller/NotifyController.php @@ -0,0 +1,516 @@ +get('id'); + if(empty($id)){ + return json(['success' => false, 'msg' => '缺少参数']); + } + //获取合同数据 + $contract = VehicleContract::where('id', $id)->find(); + if (empty($contract)) { + return json(['success' => false, 'msg' => '获取数据失败']); + } + if($contract['status'] != 2){ + return json(['success' => false, 'msg' => '合同状态错误']); + } + if ($contract['signing_timer'] == 0) { + //更新本地合同状态 + $updateLocalRes = VehicleContract::where('id',$contract['id'])->update(['signing_timer'=>1]); + //更新远程 + $updateSverRes =curl_post(env('project.logistic_domain').'/api/contractUpdate',[],[ + 'id' => $contract['contract_logistic_id'], + 'signing_timer' => 1, + ]); + if(!$updateLocalRes || $updateSverRes['code']==0){ + return json(['success' => false, 'msg' => '更新失败']); + } + return json(['success' => true, 'msg' => '成功']); + }else if($contract['signing_timer'] == 1){ + //获取签约后的合同 + $signContractFile = app(JunziqianController::class)->downloadVehicleContractFile($contract['contract_no']); + $signContractFile = $signContractFile ?? ''; + //获取签约后的证据 + $signContractEvidenceToPartyA = app(JunziqianController::class)->downloadVehicleContractEvidence($contract['contract_no'],$contract['company_a_name'],$contract['company_a_code']); + $signContractEvidenceToPartyA = $signContractEvidenceToPartyA ?? ''; + $signContractEvidenceToPartyB = app(JunziqianController::class)->downloadVehicleContractEvidence($contract['contract_no'],$contract['company_b_name'],$contract['company_b_code']); + $signContractEvidenceToPartyB = $signContractEvidenceToPartyB ?? ''; + $contractEvidence = json_encode([ + 'party_a' => $signContractEvidenceToPartyA, + 'party_b' => $signContractEvidenceToPartyB + ]); + //更新本地合同状态 + $updateLocalRes = VehicleContract::where('id',$contract['id'])->update(['signing_timer'=>2,'status' => 3,'contract_url'=>$signContractFile,'contract_evidence'=>$contractEvidence]); + //将车辆加入到本地租赁列表 + $cars = json_decode($contract['cars_info'], true); + $data = []; + foreach ($cars as $k => $v) { + $hasCar = VehicleRent::where('car_id',$v['id'])->findOrEmpty(); + if($hasCar->isEmpty()){ + $data[$k]['contract_id'] = $contract['id']; + $data[$k]['company_id'] = $contract['company_b_id']; + $data[$k]['car_id'] = $v['id']; + $data[$k]['car_license'] = $v['license']; + $data[$k]['type'] = 0; + $data[$k]['status'] = 0; + $data[$k]['rent_contract_id'] = 0; + $data[$k]['rent_company_id'] = 0; + $data[$k]['rent_time'] = 0; + $data[$k]['create_time'] = strtotime($contract['create_time']); + } + } + $vehicleRent = new VehicleRent(); + $vehicleRent->saveAll($data); + //更新远程 + $updateSverRes = curl_post(env('project.logistic_domain').'/api/contractUpdate',[],[ + 'id' => $contract['contract_logistic_id'], + 'signing_timer' => 2, + 'status' => 3, + 'contract_url'=>$signContractFile, + 'contract_evidence'=>$contractEvidence + ]); + if(!$updateLocalRes || $updateSverRes['code']==0){ + return json(['success' => false, 'msg' => '更新失败']); + }else{ + return json(['success' => true, 'msg' => '更新成功']); + } + } + return json(['success' => true, 'msg' => '更新成功@']); + } + + //系统车辆租赁回来 + public function systemCarRent(): Json + { + //获取参数 + $id = $this->request->get('id'); + if (empty($id)) { + return json(['success' => false, 'msg' => '失败1.1']); + } + //获取合同数据 + $contract = VehicleContract::where('id', $id)->find(); + if (empty($contract)) { + return json(['success' => false, 'msg' => '失败1.2']); + } + if ($contract['type'] != 0) { + return json(['success' => false, 'msg' => '失败1.3']); + } + if ($contract['status'] != 2) { + return json(['success' => false, 'msg' => '失败1.4']); + } + //判断签约方 + if ($contract['signing_timer'] == 0) { + //更新合同的签约次数 + $res = VehicleContract::where('id', $id)->update(['signing_timer' => 1]); + if (!$res) { + return json(['success' => false, 'msg' => '失败1.5']); + } + return json(['success' => true, 'msg' => '成功']); + } else if ($contract['signing_timer'] == 1) { + //获取签约后的合同 + $signContractFile = app(JunziqianController::class)->downloadVehicleContractFile($contract['contract_no']); + $signContractFile = $signContractFile ?? ''; + //获取签约后的证据 + $signContractEvidenceToPartyA = app(JunziqianController::class)->downloadVehicleContractEvidence($contract['contract_no'],$contract['company_a_name'],$contract['company_a_code']); + $signContractEvidenceToPartyA = $signContractEvidenceToPartyA ?? ''; + $signContractEvidenceToPartyB = app(JunziqianController::class)->downloadVehicleContractEvidence($contract['contract_no'],$contract['company_b_name'],$contract['company_b_code']); + $signContractEvidenceToPartyB = $signContractEvidenceToPartyB ?? ''; + $contractEvidence = json_encode([ + 'party_a' => $signContractEvidenceToPartyA, + 'party_b' => $signContractEvidenceToPartyB + ]); + //更改合同状态 + VehicleContract::where('id', $id)->update(['signing_timer' => 2, 'status' => 3,'contract_url'=>$signContractFile,'contract_evidence'=>$contractEvidence]); + //添加车辆到租赁列表 + $vehicle = json_decode($contract['cars_info'], true); + VehicleRent::where('car_id', $vehicle[0]['id'])->update([ + 'status' => 2, + 'rent_contract_id' => $contract['id'], + 'rent_company_id' => $contract['company_b_id'], + 'rent_time' => time(), + ]); + $party_b = Company::where('id', $contract['company_b_id'])->find(); + //通知物流系统跟新 + curl_post(env('project.logistic_domain').'/api/updateVehicleRent', [], [ + 'car_id' => $vehicle[0]['id'], + 'use_user_id' => $party_b['user_id'], + 'use_user_name' => $party_b['master_name'], + 'use_user_phone' => $party_b['master_phone'] + ]); + return json(['success' => true, 'msg' => '成功']); + } else { + return json(['success' => true, 'msg' => '成功']); + } + } + + //自有车辆租赁回答 + public function selfCarRent(): Json + { + //获取参数 + $id = $this->request->get('id'); + if (empty($id)) { + return json(['success' => false, 'msg' => '失败2.1']); + } + //获取合同数据 + $contract = VehicleContract::where('id', $id)->find(); + if (empty($contract)) { + return json(['success' => false, 'msg' => '失败2.2']); + } + if ($contract['type'] != 1) { + return json(['success' => false, 'msg' => '失败2.3']); + } + if ($contract['status'] != 2) { + return json(['success' => false, 'msg' => '失败2.4']); + } + //判断签约方 + if ($contract['signing_timer'] == 0) { + $res = VehicleContract::where('id', $id)->update(['signing_timer' => 1]); + if (!$res) { + return json(['success' => false, 'msg' => '失败2.5']); + } + return json(['success' => true, 'msg' => '成功']); + } else if ($contract['signing_timer'] == 1) { + //添加车辆到物流系统 + $vehicle = json_decode($contract['cars_info'], true); + $curl_res = curl_post(env('project.logistic_domain').'/api/addSelfCar', [], [ + 'license' => $vehicle[0]['license'], + 'pic' => $vehicle[0]['pic'], + 'company_id' => $contract['company_a_id'], + 'company_name' => $contract['company_a_name'], + 'company_user' => $contract['company_a_user'], + 'company_phone' => $contract['company_a_phone'], + ]); + if (!$curl_res || $curl_res['code'] == 0) { + return json(['success' => false, 'msg' => '失败2.6']); + } + $cars_info = json_encode([['id' => $curl_res['data']['car_id'], 'license' => $vehicle[0]['license']]]); + //获取签约后的合同 + $signContractFile = app(JunziqianController::class)->downloadVehicleContractFile($contract['contract_no']); + $signContractFile = $signContractFile ?? ''; + //获取签约后的证据 + $signContractEvidenceToPartyA = app(JunziqianController::class)->downloadVehicleContractEvidence($contract['contract_no'],$contract['company_a_name'],$contract['company_a_code']); + $signContractEvidenceToPartyA = $signContractEvidenceToPartyA ?? ''; + $signContractEvidenceToPartyB = app(JunziqianController::class)->downloadVehicleContractEvidence($contract['contract_no'],$contract['company_b_name'],$contract['company_b_code']); + $signContractEvidenceToPartyB = $signContractEvidenceToPartyB ?? ''; + $contractEvidence = json_encode([ + 'party_a' => $signContractEvidenceToPartyA, + 'party_b' => $signContractEvidenceToPartyB + ]); + VehicleContract::where('id', $id)->update(['cars_info'=>$cars_info,'update_time'=>time(),'signing_timer'=>2,'status'=>3,'contract_url'=>$signContractFile,'contract_evidence'=>$contractEvidence]); + VehicleRent::create([ + 'car_id' => $curl_res['data']['car_id'], + 'contract_id' => $contract['id'], + 'company_id' => $contract['company_a_id'], + 'car_license' => $vehicle[0]['license'], + 'status' => 2, + 'rent_time' => time(), + 'rent_contract_id' => $contract['id'], + 'rent_company_id' => $contract['company_b_id'], + 'create_time' => time(), + 'type' => 1 + ]); + $car_id = $curl_res['data']['car_id']; + $party_b = Company::where('id', $contract['company_b_id'])->find(); + //通知物流系统跟新 + curl_post(env('project.logistic_domain').'/api/updateVehicleRent', [], [ + 'car_id' => $car_id, + 'use_user_id' => $party_b['user_id'], + 'use_user_name' => $party_b['master_name'], + 'use_user_phone' => $party_b['master_phone'] + ]); + return json(['success' => true, 'msg' => '成功']); + } else { + return json(['success' => true, 'msg' => '成功']); + } + } + + //解除合同回调 + public function cancelRent() + { + //获取参数 + $id = $this->request->get('id'); + if (empty($id)) { + return json(['success' => false, 'msg' => '失败3.1']); + } + //获取合同数据 + $contract = VehicleContract::where('id', $id)->find(); + if (empty($contract)) { + return json(['success' => false, 'msg' => '失败3.2']); + } + if ($contract['type'] != 2) { + return json(['success' => false, 'msg' => '失败3.3']); + } + if ($contract['status'] != 2) { + return json(['success' => false, 'msg' => '失败3.4']); + } + if ($contract['signing_timer'] == 0) { + $res = VehicleContract::where('id', $id)->update(['signing_timer' => 1]); + if (!$res) { + return json(['success' => false, 'msg' => '失败3.5']); + } + return json(['success' => true, 'msg' => '成功']); + } else if ($contract['signing_timer'] == 1) { + //获取签约后的合同 + $signContractFile = app(JunziqianController::class)->downloadVehicleContractFile($contract['contract_no']); + $signContractFile = $signContractFile ?? ''; + //获取签约后的证据 + $signContractEvidenceToPartyA = app(JunziqianController::class)->downloadVehicleContractEvidence($contract['contract_no'],$contract['company_a_name'],$contract['company_a_code']); + $signContractEvidenceToPartyA = $signContractEvidenceToPartyA ?? ''; + $signContractEvidenceToPartyB = app(JunziqianController::class)->downloadVehicleContractEvidence($contract['contract_no'],$contract['company_b_name'],$contract['company_b_code']); + $signContractEvidenceToPartyB = $signContractEvidenceToPartyB ?? ''; + $contractEvidence = json_encode([ + 'party_a' => $signContractEvidenceToPartyA, + 'party_b' => $signContractEvidenceToPartyB + ]); + $cars = json_decode($contract['cars_info'],true); + $cars_ids = array_column($cars,'id'); + //更改合同状态 + VehicleContract::where('id', $id)->update(['signing_timer'=>2,'status'=>3,'contract_url'=>$signContractFile,'contract_evidence'=>$contractEvidence]); + if(!empty($contract['contract_logistic_id'])){ + curl_post(env('project.logistic_domain').'/api/contractUpdate',[],[ + 'id' => $contract['contract_logistic_id'], + 'signing_timer' => 2, + 'status' => 3, + 'contract_url'=>$signContractFile, + 'contract_evidence'=>$contractEvidence, + ]); + } + //判断合同是否存在购买记录表中 + $vehicleBuyRecord = VehicleBuyRecord::where('contract_id',$contract['id'])->findOrEmpty(); + if(!$vehicleBuyRecord->isEmpty()){ + //小组公司与镇街公司解约 + if($vehicleBuyRecord['status'] == 1){ + //获取租赁车辆信息 + $rentCarsInfo = VehicleRent::where('car_id',$cars_ids[0])->findOrEmpty(); + if($rentCarsInfo['type'] == 0){ + //修改租赁车俩状态 + VehicleRent::where('id',$rentCarsInfo['id'])->update(['status'=>0,'rent_company_id'=>0,'rent_contract_id'=>0,'rent_time'=>0]); + } + if($rentCarsInfo['type'] == 1){ + //修改租赁车俩状态 + VehicleRent::where('id',$rentCarsInfo['id'])->delete(); + } + //删除原合同 + VehicleContract::where('id',$rentCarsInfo['rent_contract_id'])->delete(); + //修改物流系统车辆租赁信息 + curl_post(env('project.logistic_domain').'/api/Vehicle/delRentUseInfo', [], [ + 'car_id' => $cars_ids[0] + ]); + //发送购买合同给物流系统 + $curl_result = curl_post(env('project.logistic_domain').'/api/signContract',[],[ + 'num' => $vehicleBuyRecord['num'], + 'company_id' => $vehicleBuyRecord['company_id'], + 'company_name' => $vehicleBuyRecord['company_name'], + 'company_code' => $vehicleBuyRecord['company_code'], + 'company_user' => $vehicleBuyRecord['company_user'], + 'company_phone' => $vehicleBuyRecord['company_phone'], + 'company_email' => $vehicleBuyRecord['company_email'], + 'cars_info' => $vehicleBuyRecord['cars_info'], + 'type' => 3 + ]); + if(empty($curl_result)){ + return $this->fail('null return from logistic'); + } + if($curl_result['code'] == 0){ + return $this->fail($curl_result['msg'].' from logistic'); + } + //生成本地合同 + VehicleContract::create($curl_result['data']); + VehicleBuyRecord::where('id',$vehicleBuyRecord['id'])->update(['status'=>4]); + return json(['success' => true, 'msg' => '成功']); + } + //小组公司与镇街公司解约,然后镇街公司与平台公司解约 + if($vehicleBuyRecord['status'] == 2){ + //获取租赁车辆信息 + $rentCarsInfo = VehicleRent::where('car_id',$cars_ids[0])->findOrEmpty(); + if($rentCarsInfo['type'] == 0){ + //修改租赁车俩状态 + VehicleRent::where('id',$rentCarsInfo['id'])->update(['status'=>0,'rent_company_id'=>0,'rent_contract_id'=>0,'rent_time'=>0]); + } + if($rentCarsInfo['type'] == 1){ + //修改租赁车俩状态 + VehicleRent::where('id',$rentCarsInfo['id'])->delete(); + } + //删除原合同 + VehicleContract::where('id',$rentCarsInfo['rent_contract_id'])->delete(); + //修改物流系统车辆租赁信息 + curl_post(env('project.logistic_domain').'/api/Vehicle/delRentUseInfo', [], [ + 'car_id' => $cars_ids[0] + ]); + //获取镇街公司信息 + $zjCompany = Company::where('id',$rentCarsInfo['company_id'])->findOrEmpty(); + //判断购买车辆中是否包含镇街公司租赁的车辆 + $car_ids = array_column(json_decode($vehicleBuyRecord['cars_info'],true),'id'); + $zjRentCars = VehicleRent::field('car_id as id,car_license as license')->where('company_id',$zjCompany['id'])->where('car_id','in',$car_ids)->where('status',0)->where('type',0)->select(); + //发送镇公司与平台公司的解约合同 + $curl_result = curl_post(env('project.logistic_domain').'/api/signContract',[],[ + 'num' => count($zjRentCars), + 'company_id' => $zjCompany['id'], + 'company_name' => $zjCompany['company_name'], + 'company_code' => $zjCompany['organization_code'], + 'company_user' => $zjCompany['master_name'], + 'company_phone' => $zjCompany['master_phone'], + 'company_email' => $zjCompany['master_email'], + 'cars_info' => json_encode($zjRentCars), + 'type' => 2 + ]); + if(empty($curl_result)){ + return $this->fail('null return from logistic'); + } + if($curl_result['code'] == 0){ + return $this->fail($curl_result['msg'].' from logistic'); + } + //生成本地合同 + $res = VehicleContract::create($curl_result['data']); + VehicleBuyRecord::where('id',$vehicleBuyRecord['id'])->update(['status'=>3,'contract_id'=>$res->id]); + return json(['success' => true, 'msg' => '成功']); + } + //镇街公司与平台公司解约 + if($vehicleBuyRecord['status'] == 3){ + //删除本地租赁信息 + VehicleRent::where('car_id','in',$cars_ids)->delete(); + //删除物流系统租赁信息 + curl_post(env('project.logistic_domain').'/api/cancelRent', [], [ + 'car_ids' => implode(',',$cars_ids) + ]); + //发送购买合同给物流系统 + $curl_result = curl_post(env('project.logistic_domain').'/api/signContract',[],[ + 'num' => $vehicleBuyRecord['num'], + 'company_id' => $vehicleBuyRecord['company_id'], + 'company_name' => $vehicleBuyRecord['company_name'], + 'company_code' => $vehicleBuyRecord['company_code'], + 'company_user' => $vehicleBuyRecord['company_user'], + 'company_phone' => $vehicleBuyRecord['company_phone'], + 'company_email' => $vehicleBuyRecord['company_email'], + 'cars_info' => $vehicleBuyRecord['cars_info'], + 'type' => 3 + ]); + if(empty($curl_result)){ + return $this->fail('null return from logistic'); + } + if($curl_result['code'] == 0){ + return $this->fail($curl_result['msg'].' from logistic'); + } + //生成本地合同 + VehicleContract::create($curl_result['data']); + VehicleBuyRecord::where('id',$vehicleBuyRecord['id'])->update(['status'=>4]); + return json(['success' => true, 'msg' => '成功']); + } + }else{ + //更改租赁列表车辆状态 + $vehicle = json_decode($contract['cars_info'], true); + //获取租赁车辆信息 + $vehicleRentInfo = VehicleRent::where('car_id', $vehicle[0]['id'])->find(); + //更新原始合同类型 + VehicleContract::where('id', $vehicleRentInfo['rent_contract_id'])->delete(); + VehicleRent::where('car_id', $vehicle[0]['id'])->delete(); + //通知物流系统跟新 + curl_post(env('project.logistic_domain').'/api/Vehicle/delRentUseInfo', [], [ + 'car_id' => $vehicle[0]['id'] + ]); + return json(['success' => true, 'msg' => '成功']); + } + } else { + return json(['success' => true, 'msg' => '成功']); + } + } + + //购买合同回调 + public function buyCar(): Json + { + //获取参数 + $id = $this->request->get('id'); + if (empty($id)) { + return json(['success' => false, 'msg' => '失败4.1']); + } + //获取合同数据 + $contract = VehicleContract::where('id', $id)->find(); + if (empty($contract)) { + return json(['success' => false, 'msg' => '失败4.2']); + } + if ($contract['type'] != 3) { + return json(['success' => false, 'msg' => '失败4.3']); + } + if ($contract['status'] != 2) { + return json(['success' => false, 'msg' => '失败4.4']); + } + if ($contract['signing_timer'] == 0) { + $res = VehicleContract::where('id', $id)->update(['signing_timer' => 1]); + if (!$res) { + return json(['success' => false, 'msg' => '失败4.5']); + } + return json(['success' => true, 'msg' => '成功']); + }else if ($contract['signing_timer'] == 1) { + //获取签约后的合同 + $signContractFile = app(JunziqianController::class)->downloadVehicleContractFile($contract['contract_no']); + $signContractFile = $signContractFile ?? ''; + //获取签约后的证据 + $signContractEvidenceToPartyA = app(JunziqianController::class)->downloadVehicleContractEvidence($contract['contract_no'],$contract['company_a_name'],$contract['company_a_code']); + $signContractEvidenceToPartyA = $signContractEvidenceToPartyA ?? ''; + $signContractEvidenceToPartyB = app(JunziqianController::class)->downloadVehicleContractEvidence($contract['contract_no'],$contract['company_b_name'],$contract['company_b_code']); + $signContractEvidenceToPartyB = $signContractEvidenceToPartyB ?? ''; + $contractEvidence = json_encode([ + 'party_a' => $signContractEvidenceToPartyA, + 'party_b' => $signContractEvidenceToPartyB + ]); + //更新本地合同状态 + $updateLocalRes = VehicleContract::where('id',$contract['id'])->update(['signing_timer'=>2,'status' => 3,'contract_url'=>$signContractFile,'contract_evidence'=>$contractEvidence]); + //判断是否有监管车辆 + $jgCars = VehicleRent::where('rent_company_id',$contract['company_b_id'])->where('status',2)->where('type',2)->findOrEmpty(); + if($jgCars->isEmpty()){ + //获取镇街公司信息 + $zjCompany = Contract::field('party_a')->where('party_b',$contract['company_b_id'])->where('signing_timer',2)->findOrEmpty(); + //将车辆加入到本地租赁列表 + $cars = json_decode($contract['cars_info'], true); + //写入数据 + $data = [ + 'car_id' => $cars[0]['id'], + 'car_license' => $cars[0]['license'], + 'type' => 2, + 'status' => 2, + 'company_id' => $zjCompany['party_a'], + 'rent_time' => time(), + 'rent_company_id' => $contract['company_b_id'], + 'contract_id' => $contract['id'], + 'create_time' => time() + ]; + $vehicleRent = new VehicleRent(); + $vehicleRent->save($data); + } + //获取签约公司信息 + $compay = Company::where('id',$contract['company_b_id'])->findOrEmpty(); + //更新远程 + $updateSverRes = curl_post(env('project.logistic_domain').'/api/contractUpdate',[],[ + 'id' => $contract['contract_logistic_id'], + 'signing_timer' => 2, + 'status' => 3, + 'contract_url'=>$signContractFile, + 'contract_evidence'=>$contractEvidence, + 'use_user_id' =>$compay['user_id'], + 'use_user_name' =>$compay['master_name'], + 'use_user_phone' =>$compay['master_phone'], + ]); + if(!$updateLocalRes || $updateSverRes['code']==0){ + return json(['success' => false, 'msg' => '更新失败']); + }else{ + return json(['success' => true, 'msg' => '更新成功']); + } + }else{ + return json(['success' => true, 'msg' => '成功']); + } + } + } \ No newline at end of file diff --git a/app/api/service/ApiSignService.php b/app/api/service/ApiSignService.php index a34ca5ca..4645f0cb 100644 --- a/app/api/service/ApiSignService.php +++ b/app/api/service/ApiSignService.php @@ -17,7 +17,7 @@ class ApiSignService public static function verifySign($data,$appKey): array { // 验证请求, 2分钟失效 - if (time() - $data['timestamp'] > 120) { + if (time() - intval($data['timestamp'] / 1000) > 120) { return ['code' => 0, 'msg' => '签名已失效']; } //比对签名 diff --git a/app/common.php b/app/common.php index 7e9a670f..5cdbfadc 100644 --- a/app/common.php +++ b/app/common.php @@ -322,3 +322,35 @@ function format_amount($float) } return $float; } + +function curl_post($url,$data,$headers=[]) { + //初始化curl + $ch = curl_init(); + curl_setopt($ch,CURLOPT_URL,$url); + //设置获取的信息以文件流的形式返回,而不是直接输出。 + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + //设置头文件的信息作为数据流输出 + curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120); + curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, FALSE); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); + //设置为post方式请求 + curl_setopt($ch, CURLOPT_POST, 1); + //添加参数 + curl_setopt($ch, CURLOPT_POSTFIELDS, $data); + //设置header + curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); + //关闭请求资源 + $output = curl_exec($ch); + curl_close($ch); + return json_decode($output,true); +} + +function curl_get($url){ + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + $output = curl_exec($ch); + curl_close($ch); + return json_decode($output,true); +} diff --git a/app/common/controller/JunziqianController.php b/app/common/controller/JunziqianController.php new file mode 100644 index 00000000..f196aab3 --- /dev/null +++ b/app/common/controller/JunziqianController.php @@ -0,0 +1,490 @@ +serviceUrl=env('junzi.url_prefix'); + $this->appkey=env('junzi.app_key'); + $this->appSecret=env('junzi.app_secret'); + + parent::initialize(); + + } + /**请求地址*/ + // private $serviceUrl = 'https://api.junziqian.com'; + // /**appkey*/ + // private $appkey = '62dc4ab579153712'; + // /**secret*/ + // private $appSecret = 'b7f65acc62dc4ab579153712fc9ebfc5'; + /**默认加密方式:不输入使用sha256,其它可选择项md5,sha1,sha3-256*/ + private $encryMethod; + /**默认ts单位:1毫秒,2秒*/ + private $tsType; + /** + * 填充签名数据 + * @param $req array + */ + public function fillSign($req) + { + /**默认加密方式:不输入使用sha256,其它可选择项md5,sha1,sha3-256*/ + $ts = time(); + if ($this->tsType == 1) { + $ts = $ts * 1000; + } + $sign = null; + $nonce = md5($ts . ""); + $signSrc = "nonce" . $nonce . "ts" . $ts . "app_key" . $this->appkey . "app_secret" . $this->appSecret; + if ($this->encryMethod == null || $this->encryMethod == "sha256") { + $sign = ShaUtils::getSha256($signSrc); + } else if ($this->encryMethod == "sha1") { + $sign = ShaUtils::getSha1($signSrc); + } else if ($this->encryMethod == "md5") { + $sign = md5($signSrc); + } else { + throw new ResultInfoException($this->encryMethod . ",必须为md5,sha1,sha256之一", "PARAM_ERROR"); + } + $req['ts'] = $ts; + $req['app_key'] = $this->appkey; + $req['sign'] = $sign; + $req['nonce'] = $nonce; //这只是为了生成一个随机值 + if ($this->encryMethod != null) { + $req['encry_method'] = $this->encryMethod; //为''也不能传 + } + return $req; + } + + //企业实名认证上传 + + public function EnterpriseCertification($data) + { + $requestUtils = new RequestUtils($this->serviceUrl, $this->appkey, $this->appSecret); + $request = new OrganizationCreateReq(); + $request->name = $data['name']; + $request->identificationType = 1; //证件类型:0多证,1多证合一 + $request->organizationType = 0; //组织类型 0企业,1事业单位 + $request->organizationRegNo = $data['organization_code']; + $request->organizationRegImg = $data['business_license']; //new CURLFile('D:/tmp/test.png',null,"test.png"); + $request->legalName = $data["master_name"]; //法人 + // $request->legalIdentityCard = $data["master_id_card"]; // 法人身份证 签约时人脸识别需要 + // $request->legalMobile = $data["master_phone"]; // 法人手机号 预留 签约时短信验证需要 + + if (isset($data['master_email'])) { + $request->emailOrMobile = $data['master_email']; //邮箱 + } + // $request->notifyUrl = env('url.url_prefix').'/notifyAuthentication?ids=22222'; + $request->notifyUrl = env('url.url_prefix') . '/notifyAuthentication?id=' . $data['id']; + // halt($request); + //发起创建企业请求 + $response = $requestUtils->doPost("/v2/user/organizationCreate", $request); + return $response; + } + + /** + * @param $data + * @return object + * 商城商户入驻,实名认证 + */ + public function ShopMerchantCertification($data) + { + $requestUtils = new RequestUtils($this->serviceUrl, $this->appkey, $this->appSecret); + $request = new OrganizationCreateReq(); + $request->name = $data['name']; + $request->identificationType = 1; //证件类型:0多证,1多证合一 + $request->organizationType = 0; //组织类型 0企业,1事业单位 + $request->organizationRegNo = $data['organization_code']; + $request->organizationRegImg = $data['business_license']; + $request->legalName = $data["master_name"]; //法人 + if (isset($data['master_email'])) { + $request->emailOrMobile = $data['master_email']; //邮箱 + } + $request->notifyUrl = env('url.url_prefix') . '/notifyAuthentication?id=' . $data['id'].'&type=shop_merchant'; // 回调增加type参数,用于回调是辨别是商户认证会带 + //发起创建企业请求 + $response = $requestUtils->doPost("/v2/user/organizationCreate", $request); + return $response; + } + + //重新提交企业实名认证 + public function organizationReapply($data) + { + $requestUtils = new RequestUtils($this->serviceUrl, $this->appkey, $this->appSecret); + $request = new OrganizationCreateReq(); + $request->name = $data['name']; + $request->identificationType = 1; //证件类型:0多证,1多证合一 + $request->organizationType = 0; //组织类型 0企业,1事业单位 + $request->organizationRegNo = $data['organization_code']; + $request->organizationRegImg = $data['business_license']; //new CURLFile('D:/tmp/test.png',null,"test.png"); + $request->legalName = $data["master_name"]; //法人 + // $request->legalIdentityCard = $data["master_id_card"]; // 法人身份证 签约时人脸识别需要 + // $request->legalMobile = $data["master_phone"]; // 法人手机号 预留 短信验证需要 + $request->emailOrMobile = $data['master_email']; //邮箱 + //发起创建企业请求 + $response = $requestUtils->doPost("/v2/user/organizationReapply", $request); + return $response; + // return $this->success('', (array)$response); + } + + //企业实名认证状态查询 + public function StatusQuery() + { + $param = Request()->param(); + $requestUtils = new RequestUtils($this->serviceUrl, $this->appkey, $this->appSecret); + //初始化合同参数 + $request = array( + "emailOrMobile" => $param['master_email'], //TODO * + ); + //发起请求 + $response = $requestUtils->doPost("/v2/user/organizationAuditStatus", $request); + return $response; + } + + public function shopMerchantStatusQuery($email) + { + $param = Request()->param(); + $requestUtils = new RequestUtils($this->serviceUrl, $this->appkey, $this->appSecret); + //初始化合同参数 + $request = array( + "emailOrMobile" => $email, //TODO * + ); + //发起请求 + $response = $requestUtils->doPost("/v2/user/organizationAuditStatus", $request); + return $response; + } + + //企业自定义公章 + public function Custom_seal() + { + $requestUtils = new RequestUtils($this->serviceUrl, $this->appkey, $this->appSecret); + //初始化合同参数 + $request = array( + "signName" => "500XXXXXXXXXXXX", //TODO * + "email" => "500XXXXXXXXXXXX", //TODO 不传则保存在商户下,传入注册的邮箱则上传到指定邮箱企业名下 + "signImgFile" => new CURLFile('D:/tmp/test.png', null, "test.png"), + ); + $response = $requestUtils->doPost("/v2/user/uploadEntSign", $request); + return $this->success('', (array)$response); + } + //签约 + public function Signing($data, $id, $notify = '') + { + if ($notify == '') { + $notify = env('url.url_prefix') . '/notify_url'; + } + $requestUtils = new RequestUtils($this->serviceUrl, $this->appkey, $this->appSecret); + $request = new ApplySignReq(); + $request->contractName = $data['name']; + $request->signatories = $data['signatories']; //签约方 + // $request->faceThreshold = 79; // 人脸识别阀值:默认等级(1-100之间整数),建议范围(60-79) + $request->serverCa = 1; //是否需要服务端云证书 + $request->fileType = 1; //合同上传方式 url + $request->url = $data['url']; + $request->notifyUrl = $notify . '?id=' . $id; + $request->needQifengSign = 1; + //发起PING请求 + // halt($request); + $response = $requestUtils->doPost("/v2/sign/applySign", $request); + return $response; + } + public function shopContractSigning($data, $id, $notify = '') + { + if ($notify == '') { + $notify = env('url.url_prefix') . '/shop_contract_notify_url'; + } + $requestUtils = new RequestUtils($this->serviceUrl, $this->appkey, $this->appSecret); + $request = new ApplySignReq(); + $request->contractName = $data['name']; + $request->signatories = $data['signatories']; //签约方 + // $request->faceThreshold = 79; // 人脸识别阀值:默认等级(1-100之间整数),建议范围(60-79) + $request->serverCa = 1; //是否需要服务端云证书 + $request->fileType = 1; //合同上传方式 url + $request->url = $data['url']; + $request->notifyUrl = $notify . '?id=' . $id; + $request->needQifengSign = 1; + //发起PING请求 + // halt($request); + $response = $requestUtils->doPost("/v2/sign/applySign", $request); + return $response; + } + + // 企业人脸校验上传 + public function OrganizationFaceCreate($data) + { + $requestUtils = new RequestUtils($this->serviceUrl, $this->appkey, $this->appSecret); + $request = new OrganizationFaceCreateReq(); + $request->orderNo = $data['id']; + $request->email = $data['master_email']; + $request->enterpriseName = $data['company_name']; + $request->identityNo = $data['organization_code']; + // $request-> facePerType = 0; + $request->legalPersonName = $data['master_name']; + $request->legalIdentityCard = $data['master_id_card']; //法人证件号 + $request->legalMobile = $data['master_phone']; + $request->faceAgantIdenName = $data['master_name']; + $request->faceAgantIdenCard = $data['master_id_card']; + $request->backUrl = env('url.url_prefix') . '/api/Hetong/notifyOrganizationFaceCreate'; + $response = $requestUtils->doPost("/v2/user/organizationFaceCreate", $request); + return $response; + } + + public function VehicleRentSigning($data, $id, $notify) + { + $requestUtils = new RequestUtils($this->serviceUrl, $this->appkey, $this->appSecret); + $request = new ApplySignReq(); + $request->contractName = $data['name']; + $request->signatories = $data['signatories']; //签约方 + $request->serverCa = 1; //是否需要服务端云证书 + $request->fileType = 1; //合同上传方式 url + $request->url = $data['url']; + $request->notifyUrl = $notify . '?id=' . $id; + + $request->needQifengSign = 1; + //发起PING请求 + // halt($request); + $response = $requestUtils->doPost("/v2/sign/applySign", $request); + return $response; + } + + public function downloadVehicleContractFile($applyNo) + { + $requestUtils = new RequestUtils($this->serviceUrl, $this->appkey, $this->appSecret); + $contract_url = VehicleContract::where('contract_no', $applyNo)->value('contract_url'); + if ($contract_url && !empty($contract_url)) { + return $contract_url; + } + //初始化请求参数 + $request = array( + "applyNo" => $applyNo, //TODO + + ); + $response = $requestUtils->doPost("/v2/sign/linkFile", $request); + if ($response->success) { + $this->getDownload($response->data, root_path() . 'public/uploads/vehicle_contract/' . $applyNo . '.pdf'); + return env('project.website_domain') . '/uploads/vehicle_contract/' . $applyNo . '.pdf'; + } else { + return false; + } + } + + public function downloadVehicleContractEvidence($applyNo, $companyName, $companyCode) + { + //构建请求工具 + $requestUtils = new RequestUtils($this->serviceUrl, $this->appkey, $this->appSecret); + //初始化合同参数 + $request = array( + "applyNo" => $applyNo, + "fullName" => $companyName, //签约人名称(合同发起接口中传入的签署人姓名) + "identityCard" => $companyCode, //统一社会信用代码 + "identityType" => 12, //证件类型 1身份证, 2护照, 3台胞证, 4港澳居民来往内地通行证, 11营业执照, 12统一社会信用代码, 20子账号, 99其他 + "dealType" => 1 + ); + $response = $requestUtils->doPost("/v2/sign/presLinkFile", $request); + if ($response->success) { + $this->getDownload($response->data, root_path().'public/uploads/vehicle_contract_evidence/'.$applyNo.'_'.$companyCode.'.zip'); + return env('project.website_domain').'/uploads/vehicle_contract_evidence/'.$applyNo.'_'.$companyCode.'.zip';; + } else { + return false; + } + } + + public function SigningLink($data) + { + //构建请求工具 + $requestUtils = new RequestUtils($this->serviceUrl, $this->appkey, $this->appSecret); + //初始化合同参数 + $response = $requestUtils->doPost("/v2/sign/link", $data); + return $response; + } + + public function sms($data) + { + $requestUtils = new RequestUtils($this->serviceUrl, $this->appkey, $this->appSecret); + //初始化请求参数 + $request = array( + "applyNo" => $data['applyNo'], //TODO + + //"businessNo" => "0000XXXXXXXXX", //TODO + + "fullName" => $data['fullName'], //TODO * + "identityCard" => $data['identityCard'], //TODO * + "identityType" => 12, //TODO * + "signNotifyType" => 1 //默认为1 + ); + $response = $requestUtils->doPost("/v2/sign/notify", $request); + return $response; + } + + //html模板 + public function html_contract($data, $id) + { + $requestUtils = new RequestUtils($this->serviceUrl, $this->appkey, $this->appSecret); + //CURLFile 可以传url或filePath,但必须保证文件存在且有效,否则php不会报错,只会导致http请求返回null(并没有调到服务端)。 + //初始化合同参数 + $request = new ApplySignReq(); + $request->contractName = $data['name']; + $request->signatories = $data['signatories']; //签约方 + $request->serverCa = 1; //是否需要服务端云证书 + $request->fileType = 3; + $request->htmlContent = $data['content']; + $request->notifyUrl = env('url.url_prefix') . '/notify_url?id=' . $id; + $request->needQifengSign = 1; + + //发起PING请求 + $response = $requestUtils->doPost("/v2/sign/applySign", $request); + return $response; + } + + /** + * 下载合同 + */ + public function download_file($applyNo) + { + $requestUtils = new RequestUtils($this->serviceUrl, $this->appkey, $this->appSecret); + $find = Db::name('contract')->where('contract_no', $applyNo)->value('contract_url'); + if ($find) { + return $this->success('获取成功', ['url' => env('url.url_prefix') . $find]); + } + //初始化请求参数 + $request = array( + "applyNo" => $applyNo, //TODO + + ); + $response = $requestUtils->doPost("/v2/sign/linkFile", $request); + if ($response->success == true) { + $this->getDownload($response->data, root_path() . 'public/uploads/contract/' . $applyNo . '.pdf'); + Db::name('contract')->where('contract_no', $applyNo)->update(['contract_url' => '/uploads/contract/' . $applyNo . '.pdf']); + return $this->success('获取成功', ['url' => env('url.url_prefix') . '/uploads/contract/' . $applyNo . '.pdf']); + } else { + return $this->fail('获取失败'); + } + } + public function download_shop_file($applyNo) + { + $requestUtils = new RequestUtils($this->serviceUrl, $this->appkey, $this->appSecret); + $find = Db::name('contract')->where('contract_no', $applyNo)->value('contract_url'); + if ($find) { + return $this->success('获取成功', ['url' => env('url.url_prefix') . $find]); + } + //初始化请求参数 + $request = array( + "applyNo" => $applyNo, //TODO + + ); + $response = $requestUtils->doPost("/v2/sign/linkFile", $request); + if ($response->success == true) { + $this->getDownload($response->data, root_path() . 'public/uploads/contract/' . $applyNo . '.pdf'); + Db::name('shop_contract')->where('contract_no', $applyNo)->update(['contract_url' => '/uploads/contract/' . $applyNo . '.pdf']); + return $this->success('获取成功', ['url' => env('url.url_prefix') . '/uploads/contract/' . $applyNo . '.pdf']); + } else { + return $this->fail('获取失败'); + } + } + /** + * 保全后合同文件及证据包下载 + */ + public function EvidenceDownload($param) + { + //初始化请求参数 + $requestUtils = new RequestUtils($this->serviceUrl, $this->appkey, $this->appSecret); + + $request = array( + "applyNo" => $param['applyNo'], + "fullName" => $param['fullName'], + "identityCard" => $param['identityCard'], + "identityType" => 12, + "dealType" => 1, + ); + $response = $requestUtils->doPost("/v2/sign/presLinkFile", $request); + if ($response->success == true) { + $this->getDownload($response->data, root_path() . 'public/uploads/evidence/' . $param['applyNo'] . '.zip'); + Db::name('contract')->where('contract_no', $param['applyNo'])->update(['evidence_url' => '/uploads/evidence/' . $param['applyNo'] . '.zip']); + return $this->success('获取成功', ['url' => env('url.url_prefix') . '/uploads/evidence/' . $param['applyNo'] . '.zip']); + } else { + return $this->fail('获取失败'); + } + } + + /** + * 保全后合同文件及证据包下载 + */ + public function EvidenceShopDownload($param) + { + //初始化请求参数 + $requestUtils = new RequestUtils($this->serviceUrl, $this->appkey, $this->appSecret); + + $request = array( + "applyNo" => $param['applyNo'], + "fullName" => $param['fullName'], + "identityCard" => $param['identityCard'], + "identityType" => 12, + "dealType" => 1, + ); + $response = $requestUtils->doPost("/v2/sign/presLinkFile", $request); + if ($response->success == true) { + $this->getDownload($response->data, root_path() . 'public/uploads/evidence_shop_contract/' . $param['applyNo'] . '.zip'); + Db::name('shop_contract')->where('contract_no', $param['applyNo'])->update(['evidence_url' => '/uploads/evidence_shop_contract/' . $param['applyNo'] . '.zip']); + return $this->success('获取成功', ['url' => env('url.url_prefix') . '/uploads/evidence_shop_contract/' . $param['applyNo'] . '.zip']); + } else { + return $this->fail('获取失败'); + } + } + + + public function getDownload($url, $publicDir = '', $fileName = '', $type = 0) + { + + //获取文件路径 + $newOneDir = substr($publicDir, 0, strrpos($publicDir, "/")); + if (trim($url) == '') { + return false; + } + //检验访问url是否有效 + $array = get_headers($url, 1); + if (!preg_match('/200/', $array[0])) { + return false; + } + if (trim($publicDir) == '') { + return false; + } + //创建保存目录 + if (!file_exists($newOneDir) && !mkdir($newOneDir, 0777, true)) { + return false; + } + //获取远程文件所采用的方法 + if ($type) { + $ch = curl_init(); + $timeout = 5; + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); + $content = curl_exec($ch); + curl_close($ch); + } else { + ob_start(); + readfile($url); + $content = ob_get_contents(); + ob_end_clean(); + } + $size = strlen($content); + //文件大小 + $fp2 = @fopen($publicDir, 'a'); + fwrite($fp2, $content); + fclose($fp2); + unset($content, $url); + } +} diff --git a/app/common/enum/notice/NoticeEnum.php b/app/common/enum/notice/NoticeEnum.php index d6e030ad..4c2d460d 100644 --- a/app/common/enum/notice/NoticeEnum.php +++ b/app/common/enum/notice/NoticeEnum.php @@ -37,6 +37,11 @@ class NoticeEnum const CHANGE_MOBILE_CAPTCHA = 103; const FIND_LOGIN_PASSWORD_CAPTCHA = 104; const REGISTER_CAPTCHA = 105; + + const WQ = 106; + const FCHT = 107; + const WQTZ = 108; + const FACE_CREATE = 109; /** @@ -92,6 +97,10 @@ class NoticeEnum self::CHANGE_MOBILE_CAPTCHA => '变更手机验证码', self::FIND_LOGIN_PASSWORD_CAPTCHA => '找回登录密码验证码', self::REGISTER_CAPTCHA => '注册验证码', + self::WQ => '网签短信', + self::FCHT => '废除合同', + self::WQTZ => '网签通知', + self::FACE_CREATE => '人脸识别上传通知', ]; if ($flag) { @@ -122,6 +131,14 @@ class NoticeEnum 'ZHDLMM' => self::FIND_LOGIN_PASSWORD_CAPTCHA, //注册 'YZMZC' => self::REGISTER_CAPTCHA, + //网签 + 'WQ'=>self::WQ, + //废除合同 + 'FCHT'=>self::FCHT, + //网签通知 + 'WQTZ'=>self::WQTZ, + //人脸识别 + 'FACE_CREATE'=>self::FACE_CREATE, ]; return $scene[$tag] ?? ''; } diff --git a/app/common/model/company/Company.php b/app/common/model/company/Company.php new file mode 100644 index 00000000..195c0a03 --- /dev/null +++ b/app/common/model/company/Company.php @@ -0,0 +1,68 @@ +value('name'); + } + + public function getProvinceNameAttr($value) + { + return Db::name('geo_province')->where(['province_code' => $this->province])->value('province_name'); + } + + public function getCityNameAttr($value) + { + return Db::name('geo_city')->where(['city_code' => $this->city])->value('city_name'); + } + + public function getAreaNameAttr($value) + { + return Db::name('geo_area')->where(['area_code' => $this->area])->value('area_name'); + } + + public function getStreetNameAttr($value) + { + return Db::name('geo_street')->where(['street_code' => $this->street])->value('street_name'); + } + + public function getVillageNameAttr($value) + { + return Db::name('geo_village')->where(['village_code' => $this->village])->value('village_name'); + } + + public function getBrigadeNameAttr($value) + { + return Db::name('geo_brigade')->where(['id' => $this->brigade])->value('brigade_name'); + } + public function getAreaManagerNameAttr($value) + { + return Db::name('admin')->where(['id' => $this->area_manager])->value('name'); + } + + public function getContractAttr() + { + $find=Contract::where('party_a|party_b', $this->id)->field('check_status,status')->find(); + if($find){ + return $find->toArray(); + }else{ + return []; + } + } + } \ No newline at end of file diff --git a/app/common/model/contract/Contract.php b/app/common/model/contract/Contract.php new file mode 100644 index 00000000..b8ab7517 --- /dev/null +++ b/app/common/model/contract/Contract.php @@ -0,0 +1,11 @@ +getMessage()); } } - - - /** - * @notes 视频上传 - * @param $cid - * @param int $user_id - * @param string $saveDir - * @return array - * @throws Exception - * @author 段誉 - * @date 2021/12/29 16:32 - */ - public static function video($cid, int $sourceId = 0, int $source = FileEnum::SOURCE_ADMIN, string $saveDir = 'uploads/video') + + + /** + * @notes 视频上传 + * @param $cid + * @param int $sourceId + * @param int $source + * @param string $saveDir + * @return array + * @throws Exception + * @author 段誉 + * @date 2021/12/29 16:32 + */ + public static function video($cid, int $sourceId = 0, int $source = FileEnum::SOURCE_ADMIN, string $saveDir = 'uploads/video'): array { try { $config = [ @@ -160,5 +162,74 @@ class UploadService throw new Exception($e->getMessage()); } } + + /** + * @notes 上传文件 + * @param $cid + * @param int $sourceId + * @param int $source + * @param string $saveDir + * @return array + * @throws Exception + * @author 段誉 + * @date 2021/12/29 16:30 + */ + public static function file($cid, int $sourceId = 0, int $source = FileEnum::SOURCE_ADMIN, string $saveDir = 'uploads/files'): array + { + try { + $config = [ + 'default' => ConfigService::get('storage', 'default', 'local'), + 'engine' => ConfigService::get('storage') ?? ['local' => []], + ]; + + // 2、执行文件上传 + $StorageDriver = new StorageDriver($config); + $StorageDriver->setUploadFile('file'); + $fileName = $StorageDriver->getFileName(); + $fileInfo = $StorageDriver->getFileInfo(); + + // 校验上传文件后缀 + if (!in_array(strtolower($fileInfo['ext']), config('project.file_file'))) { + throw new Exception("上传文件不允许上传" . $fileInfo['ext'] . "文件"); + } + + // 上传文件 + $saveDir = $saveDir . '/' . date('Ymd'); + if (!$StorageDriver->upload($saveDir)) { + throw new Exception($StorageDriver->getError()); + } + + // 3、处理文件名称 + if (strlen($fileInfo['name']) > 128) { + $name = substr($fileInfo['name'], 0, 123); + $nameEnd = substr($fileInfo['name'], strlen($fileInfo['name']) - 5, strlen($fileInfo['name'])); + $fileInfo['name'] = $name . $nameEnd; + } + + // 4、写入数据库中 + $file = File::create([ + 'cid' => $cid, + 'type' => FileEnum::FILE_TYPE, + 'name' => $fileInfo['name'], + 'uri' => $saveDir . '/' . str_replace("\\", "/", $fileName), + 'source' => $source, + 'source_id' => $sourceId, + 'create_time' => time(), + ]); + + // 5、返回结果 + return [ + 'id' => $file['id'], + 'cid' => $file['cid'], + 'type' => $file['type'], + 'name' => $file['name'], + 'uri' => FileService::getFileUrl($file['uri']), + 'url' => $file['uri'] + ]; + + } catch (Exception $e) { + throw new Exception($e->getMessage()); + } + } } \ No newline at end of file diff --git a/app/common/service/storage/engine/Server.php b/app/common/service/storage/engine/Server.php index 07bf0d51..27276e21 100644 --- a/app/common/service/storage/engine/Server.php +++ b/app/common/service/storage/engine/Server.php @@ -42,7 +42,7 @@ abstract class Server } // 校验上传文件后缀 - $limit = array_merge(config('project.file_image'), config('project.file_video')); + $limit = array_merge(config('project.file_image'), config('project.file_video'), config('project.file_file')); if (!in_array(strtolower($this->file->extension()), $limit)) { throw new Exception('不允许上传' . $this->file->extension() . '后缀文件'); } diff --git a/composer.json b/composer.json index 93319bb1..941a5466 100644 --- a/composer.json +++ b/composer.json @@ -33,7 +33,8 @@ "tencentcloud/tencentcloud-sdk-php": "^3.0", "alibabacloud/client": "^1.5", "rmccue/requests": "^2.0", - "w7corp/easywechat": "^6.8" + "w7corp/easywechat": "^6.8", + "ext-curl": "*" }, "require-dev": { "symfony/var-dumper": "^4.2", diff --git a/config/database.php b/config/database.php index b8da8852..2c460435 100644 --- a/config/database.php +++ b/config/database.php @@ -38,7 +38,7 @@ return [ // 数据库编码默认采用utf8 'charset' => env('database.charset', 'utf8mb4'), // 数据库表前缀 - 'prefix' => env('database.prefix', 'la_'), + 'prefix' => env('database.prefix', ''), // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) 'deploy' => 0, // 数据库读写是否分离 主从式有效 @@ -75,7 +75,7 @@ return [ // 数据库编码默认采用utf8 'charset' => env('database1.charset', 'utf8mb4'), // 数据库表前缀 - 'prefix' => env('database1.prefix', 'la_'), + 'prefix' => env('database1.prefix', ''), // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) 'deploy' => 0, // 数据库读写是否分离 主从式有效 @@ -111,7 +111,7 @@ return [ // 数据库编码默认采用utf8 'charset' => env('database2.charset', 'utf8mb4'), // 数据库表前缀 - 'prefix' => env('database2.prefix', 'la_'), + 'prefix' => env('database2.prefix', ''), // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) 'deploy' => 0, // 数据库读写是否分离 主从式有效 @@ -147,7 +147,7 @@ return [ // 数据库编码默认采用utf8 'charset' => env('database3.charset', 'utf8mb4'), // 数据库表前缀 - 'prefix' => env('database3.prefix', 'la_'), + 'prefix' => env('database3.prefix', ''), // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器) 'deploy' => 0, // 数据库读写是否分离 主从式有效 diff --git a/config/project.php b/config/project.php index 3ba585da..b34e9c1c 100644 --- a/config/project.php +++ b/config/project.php @@ -73,6 +73,11 @@ return [ 'file_video' => [ 'wmv', 'avi', 'mpg', 'mpeg', '3gp', 'mov', 'mp4', 'flv', 'f4v', 'rmvb', 'mkv' ], + + // 文件上传限制 (文件) + 'file_file' => [ + 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'pdf', 'txt','apk','ipa','wgt' + ], // 登录设置 'login' => [