diff --git a/.env.example b/.env.example index 1372073..6879583 100644 --- a/.env.example +++ b/.env.example @@ -14,4 +14,4 @@ DB_PREFIX= REDIS_HOST=localhost REDIS_AUTH=(null) REDIS_PORT=6379 -REDIS_DB=0 +REDIS_DB=0 \ No newline at end of file diff --git a/.gitignore b/.gitignore index a6307af..4ef58b1 100644 --- a/.gitignore +++ b/.gitignore @@ -6,10 +6,9 @@ .git/ runtime/ vendor/ -docs/ .phpintel/ .env .DS_Store .phpunit* *.cache -extend/Ca/msyh.ttf +extend/Ca/msyh.ttf \ No newline at end of file diff --git a/app/Services/CaService.php b/app/Services/CaService.php index 403bce5..b4669e2 100644 --- a/app/Services/CaService.php +++ b/app/Services/CaService.php @@ -12,8 +12,7 @@ use App\Model\UserDoctor; use App\Model\UserDoctorInfo; use App\Model\UserPharmacistInfo; use Extend\Alibaba\Oss; -use Extend\Ca\Ca; -use Extend\Ca\CaGatewayFactory; +use Extend\Ca\CaOnline; use Hyperf\Utils\WaitGroup; use Intervention\Image\ImageManager; use Swoole\Coroutine\Channel; @@ -24,8 +23,6 @@ use TCPDF; */ class CaService extends BaseService { - protected Ca $caGateway; - // 疾病名称 protected string $icd_name; @@ -66,8 +63,6 @@ class CaService extends BaseService * @param int $type 类型 1:医院 2:医生 3:药师 */ public function __construct(array|object $order_prescription,int $type,string|int $user_id = ""){ - $this->caGateway = $this->buildGateway(); - // 获取用户、医院签名图片地址、用户标识信息 if ($type == 1){ // 医院 @@ -228,18 +223,13 @@ class CaService extends BaseService $this->prescription_pdf_oss_path = "applet/prescription/" . $order_prescription_id. '.pdf'; } - protected function buildGateway(): Ca - { - return CaGatewayFactory::makeScene('prescription'); - } - /** * 获取云证书签名+验证云证书签名 * @param array|object $order_prescription */ public function getVerifyCertSign(array|object $order_prescription) { - $caGateway = $this->caGateway; + $CaOnline = new CaOnline(); // 获取云证书签名 $data = array(); @@ -264,10 +254,11 @@ class CaService extends BaseService $data['product'][] = $product; } - $cert_sign_result = $caGateway->getCertSign($this->entity_id, $this->entity_id, $data); + dump($this->entity_id); + $cert_sign_result = $CaOnline->getCertSign($this->entity_id, $this->entity_id, $data); // 验证云证书签名 验证无需处理,只要不返回错误即可 - $caGateway->verifyPkcs7($cert_sign_result['signP7'], $data); + $CaOnline->verifyPkcs7($cert_sign_result['signP7'], $data); $this->cert_serial_number = $cert_sign_result['certSerialnumber']; } @@ -430,7 +421,8 @@ class CaService extends BaseService */ public function downCaPdfToLocal(string $file_id): void { - $prescription_pdf_result = $this->caGateway->getSignedFile($this->entity_id, $file_id); + $CaOnline = new CaOnline(); + $prescription_pdf_result = $CaOnline->getSignedFile($this->entity_id, $file_id); $file = fopen($this->prescription_pdf_local_path, "w"); fwrite($file, $prescription_pdf_result); @@ -444,7 +436,9 @@ class CaService extends BaseService */ public function downCaPdfToOss(string $file_id): string { - $prescription_pdf_result = $this->caGateway->getSignedFile($this->entity_id, $file_id); + $CaOnline = new CaOnline(); + + $prescription_pdf_result = $CaOnline->getSignedFile($this->entity_id, $file_id); // 上传oss $oss = new Oss(); @@ -504,7 +498,7 @@ class CaService extends BaseService ], ]; - $caGateway = $this->caGateway; + $CaOnline = new CaOnline(); // 检测是否已添加签章配置 $params = array(); @@ -520,7 +514,7 @@ class CaService extends BaseService $data['sign_param'] = json_encode($sign_param); $data['seal_img'] = $sign_image; - $caGateway->addUserSignConfig($this->entity_id,$this->card_num,$data); + $CaOnline->addUserSignConfig($this->entity_id,$this->card_num,$data); $params = array(); $params['cert_id'] = $user_ca_cert['cert_id']; @@ -541,11 +535,11 @@ class CaService extends BaseService $data = array(); $data['sign_param'] = json_encode($sign_param); $data['pdf_file'] = $pdf_file; - $sign_pdf_result = $caGateway->addSignPdf($this->entity_id, $data); + $sign_pdf_result = $CaOnline->addSignPdf($this->entity_id, $data); if (empty($sign_pdf_result[0]['fileId'])) { throw new BusinessException("处方签章失败"); } return $sign_pdf_result[0]['fileId']; } -} +} \ No newline at end of file diff --git a/app/Services/OrderPrescriptionService.php b/app/Services/OrderPrescriptionService.php index 13597f2..c9ca983 100644 --- a/app/Services/OrderPrescriptionService.php +++ b/app/Services/OrderPrescriptionService.php @@ -152,6 +152,7 @@ class OrderPrescriptionService extends BaseService throw new BusinessException("医生开方日期错误"); } + dump($user_id); $CaService = new CaService($order_prescription,$type,$user_id); // 获取云证书签名+验证云证书签名 @@ -569,4 +570,4 @@ class OrderPrescriptionService extends BaseService return $promotion; } -} +} \ No newline at end of file diff --git a/app/Services/UserDoctorService.php b/app/Services/UserDoctorService.php index 6c0f306..6061d6c 100644 --- a/app/Services/UserDoctorService.php +++ b/app/Services/UserDoctorService.php @@ -1761,6 +1761,7 @@ class UserDoctorService extends BaseService }else{ $user_id = $user_info['user_id']; } + dump($user_info['user_id']); $prescription_open_result = $OrderPrescriptionService->openPrescription($order_prescription->order_prescription_id,2,$user_id); if (empty($prescription_open_result['prescription_img_oss_path']) || empty($prescription_open_result['file_id'])){ Db::rollBack(); @@ -3158,4 +3159,4 @@ class UserDoctorService extends BaseService return $multi_point_enable; } -} +} \ No newline at end of file diff --git a/config/config.php b/config/config.php index b4f39a3..6497f4a 100644 --- a/config/config.php +++ b/config/config.php @@ -108,30 +108,6 @@ return [ "secret" => env('CA_ONLINE_APP_SECRET', 'adf718ebc1fb4bb7b158de9117d1313a'), "api_url" => env('CA_ONLINE_API_URL', 'http://testmicrosrv.scca.com.cn:9527'), ], - 'gateway' => [ - 'driver' => env('CA_DRIVER', 'v2'), //legacy 老版本 v2新版本 - 'mode' => env('CA_MODE', 'online'), - 'prescription' => [ - 'driver' => env('CA_PRESCRIPTION_DRIVER', env('CA_DRIVER', 'v2')),//legacy 老版本 v2新版本 - 'mode' => env('CA_PRESCRIPTION_MODE', env('CA_MODE', 'online')), - ], - ], - 'v2' => [ - 'offline' => [ - 'app_id' => env('CA_V2_OFFLINE_APP_ID', ''), - 'secret' => env('CA_V2_OFFLINE_SECRET', ''), - 'api_url' => env('CA_V2_OFFLINE_API_URL', 'http://testmicrosrv.scca.com.cn:9527'), - 'enable_auth_signature' => env('CA_V2_OFFLINE_ENABLE_AUTH_SIGNATURE', true), - ], - 'online' => [ - 'app_id' => env('CA_V2_ONLINE_APP_ID', 'SCCA1951838127584579586'), - 'secret' => env('CA_V2_ONLINE_SECRET', 'a26bf6c8b78b4099939ab09accbc9a80'), - 'api_url' => env('CA_V2_ONLINE_API_URL', 'http://testmicrosrv.scca.com.cn:9527'), - 'notify_url' => env('CA_V2_ONLINE_NOTIFY_URL', ''), - 'jump_url' => env('CA_V2_ONLINE_JUMP_URL', ''), - 'enable_auth_signature' => env('CA_V2_ONLINE_ENABLE_AUTH_SIGNATURE', true), - ], - ], ], 'prescription_platform' => [ // 处方平台 "client_id" => env('PRE_PLAT_CLIENT_ID', 'ZD-004'), diff --git a/extend/Ca/CaGatewayFactory.php b/extend/Ca/CaGatewayFactory.php deleted file mode 100644 index eda5d8b..0000000 --- a/extend/Ca/CaGatewayFactory.php +++ /dev/null @@ -1,37 +0,0 @@ - new CaOnline(), - ['legacy', 'offline'] => new CaOffline(), - ['v2', 'online'] => new CaOnlineV2(), - ['v2', 'offline'] => new CaOfflineV2(), - default => throw new BusinessException("不支持的CA驱动配置: {$resolvedDriver}/{$resolvedMode}"), - }; - } -} diff --git a/extend/Ca_V2/Ca.php b/extend/Ca_V2/Ca.php deleted file mode 100644 index 513143f..0000000 --- a/extend/Ca_V2/Ca.php +++ /dev/null @@ -1,247 +0,0 @@ -isValidConfig($config)) { - throw new BusinessException("缺少{$label}配置"); - } - - $this->config = $config; - $this->app_id = $config['app_id']; - $this->api_url = rtrim($config['api_url'], '/'); - $this->secret = $config['secret']; - } - - protected function isValidConfig(mixed $config): bool - { - if (!is_array($config)) { - return false; - } - - return !empty($config['app_id']) && !empty($config['api_url']) && !empty($config['secret']); - } - - protected function buildSignPayload(array $data): string - { - $signData = []; - if (isset($data['form_params'])) { - $signData = $data['form_params']; - } - - if (isset($data['multipart'])) { - foreach ($data['multipart'] as $item) { - if (($item['name'] ?? '') === 'pdfFile') { - continue; - } - - $signData[$item['name']] = $item['contents']; - } - } - - if (empty($signData)) { - return ''; - } - - ksort($signData); - return implode('&', $signData); - } - - protected function getAuthSignature(array $data): string - { - return hash('sha256', $this->buildSignPayload($data)); - } - - protected function shouldAttachAuthSignature(string $path): bool - { - $enabled = filter_var((string) ($this->config['enable_auth_signature'] ?? false), FILTER_VALIDATE_BOOLEAN); - if (!$enabled) { - return false; - } - - return str_contains($path, '/api/cloudCert/open/v2/cert/') - || str_contains($path, '/api/cloudCert/open/v3/cert/') - || str_contains($path, '/api/certgw/certapi/') - || str_contains($path, '/v5/api/certgw/certapi/'); - } - - protected function buildCertSignPayload(array $data): string - { - $payload = json_encode($data, JSON_UNESCAPED_UNICODE); - if ($payload === false) { - throw new BusinessException('CA V2签名原文序列化失败'); - } - - return $payload; - } - - protected function buildCertSignTransportPayload(array $data): string - { - return base64_encode($this->buildCertSignPayload($data)); - } - - protected function resolveCertSerialnumber(string $entityId, array $response): string - { - return (string) ($response['certSerialnumber'] ?? $response['certSn'] ?? ''); - } - - protected function normalizeCertSignResponse(string $entityId, array $response): array - { - if (empty($response['signP7']) && !empty($response['requestId'])) { - $result = $this->getCertSignResult((string) $response['requestId']); - if (is_array($result) && !empty($result['signP7'])) { - $response = array_merge($response, $result); - } - } - - if (empty($response['signP7'])) { - if (!empty($response['signUrl'])) { - throw new BusinessException('当前证书未开启免密签署,返回的是页面签署链接,暂不支持服务端自动完成'); - } - - throw new BusinessException('CA V2签名响应缺少signP7'); - } - - if (empty($response['certSerialnumber'])) { - $response['certSerialnumber'] = $this->resolveCertSerialnumber($entityId, $response); - } - - return $response; - } - - protected function getOptionalConfig(string $key): string - { - return trim((string) ($this->config[$key] ?? '')); - } - - public function getCertSign(string $user_id, string $pin, array $data): mixed - { - $generator = $this->container->get(IdGeneratorInterface::class); - $payload = $this->buildCertSignTransportPayload($data); - - $option = [ - 'form_params' => [ - 'entityId' => $user_id, - 'requestId' => (string) $generator->generate(), - 'businessType' => 'certSign', - 'toSign' => $payload, - 'extParam' => json_encode(['toSignEncoding' => 'base64'], JSON_UNESCAPED_UNICODE), - ], - ]; - - $notifyUrl = $this->getOptionalConfig('notify_url'); - if ($notifyUrl !== '') { - $option['form_params']['notifyUrl'] = $notifyUrl; - } - - $jumpUrl = $this->getOptionalConfig('jump_url'); - if ($jumpUrl !== '') { - $option['form_params']['jumpUrl'] = $jumpUrl; - } - - try { - $response = $this->httpRequest($this->api_url . '/open/api/data/certSign', $option); - if (empty($response)) { - throw new BusinessException(HttpEnumCode::getMessage(HttpEnumCode::SERVER_ERROR)); - } - - return $this->normalizeCertSignResponse($user_id, $response); - } catch (GuzzleException $e) { - throw new BusinessException($e->getMessage()); - } - } - - public function getCertSignResult(string $requestId): mixed - { - $option = [ - 'form_params' => [ - 'requestId' => $requestId, - ], - ]; - - try { - return $this->httpRequest($this->api_url . '/open/api/data/getCertSignResult', $option); - } catch (GuzzleException $e) { - throw new BusinessException($e->getMessage()); - } - } - - public function verifyPkcs7(string $sign_p7, array $data) - { - $generator = $this->container->get(IdGeneratorInterface::class); - - $option = [ - 'form_params' => [ - 'opType' => '签名验证', - 'requestId' => $generator->generate(), - 'signedData' => $sign_p7, - 'toSign' => $this->buildCertSignTransportPayload($data), - ], - ]; - - try { - $response = $this->httpRequest( - $this->api_url . '/signgw-service/api/signature/verifyPkcs7', - $option - ); - if (empty($response)) { - throw new BusinessException(HttpEnumCode::getMessage(HttpEnumCode::SERVER_ERROR)); - } - - return $response; - } catch (GuzzleException $e) { - throw new BusinessException($e->getMessage()); - } - } - - public function httpRequest(string $path, array $arg = []): mixed - { - $headers = [ - 'app_id' => $this->app_id, - 'signature' => $this->getRequestSign($arg), - ]; - - if ($this->shouldAttachAuthSignature($path)) { - $headers['authSignature'] = $this->getAuthSignature($arg); - } - - $arg['headers'] = array_merge($arg['headers'] ?? [], $headers); - - $response = $this->client->post($path, $arg); - if ($response->getStatusCode() != '200') { - throw new BusinessException($response->getBody()->getContents()); - } - - $body = json_decode($response->getBody(), true); - if (empty($body)) { - throw new BusinessException(HttpEnumCode::getMessage(HttpEnumCode::SERVER_ERROR)); - } - - if ($body['result_code'] != 0) { - if (!empty($body['result_msg'])) { - throw new BusinessException($body['result_msg']); - } - - throw new BusinessException(HttpEnumCode::getMessage(HttpEnumCode::SERVER_ERROR)); - } - - return $body['body']; - } - - public function getRequestSign(array $data): string - { - return hash_hmac('sha1', $this->buildSignPayload($data), $this->secret); - } -} diff --git a/extend/Ca_V2/CaOffline.php b/extend/Ca_V2/CaOffline.php deleted file mode 100644 index f7eecaa..0000000 --- a/extend/Ca_V2/CaOffline.php +++ /dev/null @@ -1,42 +0,0 @@ -initConfig('ca.v2.offline', 'ca_v2_offline'); - } - - public function getCloudCert(array $data, string $type = 'Personal'): mixed - { - $option = [ - 'form_params' => [ - 'entityId' => $data['user_id'], - 'entityType' => $type, - 'pin' => $data['user_id'], - 'cardNumber' => $data['card_num'], - ], - ]; - - try { - $response = $this->httpRequest( - $this->api_url . '/cloud-certificate-service/api/cloudCert/open/v2/cert/offlineAuthCertEnroll', - $option - ); - if (empty($response)) { - throw new BusinessException(HttpEnumCode::getMessage(HttpEnumCode::SERVER_ERROR)); - } - - return $response; - } catch (GuzzleException $e) { - throw new BusinessException($e->getMessage()); - } - } -} diff --git a/extend/Ca_V2/CaOnline.php b/extend/Ca_V2/CaOnline.php deleted file mode 100644 index f38559a..0000000 --- a/extend/Ca_V2/CaOnline.php +++ /dev/null @@ -1,152 +0,0 @@ -initConfig('ca.v2.online', 'ca_v2_online'); - } - - public function getCloudCert(array $data, string $type = 'Personal'): mixed - { - $option = [ - 'form_params' => [ - 'entityId' => $data['user_id'], - 'entityType' => $type, - 'personalPhone' => (string) $data['mobile'], - 'personalName' => $data['card_name'] ?? '', - 'personalIdNumber' => $data['card_num'] ?? '', - 'orgName' => $data['org_name'] ?? '', - 'orgNumber' => $data['org_number'] ?? '', - 'pin' => $data['user_id'], - 'province' => '四川省', - 'locality' => '成都市', - 'authType' => '实人认证', - 'authTime' => $this->getAuthTime(), - 'authResult' => '认证通过', - 'authNoticeType' => '数字证书申请告知', - ], - ]; - - try { - $response = $this->httpRequest( - $this->api_url . '/cloud-certificate-service/api/cloudCert/open/v2/cert/certEnroll', - $option - ); - if (empty($response)) { - throw new BusinessException(HttpEnumCode::getMessage(HttpEnumCode::SERVER_ERROR)); - } - - return $response; - } catch (GuzzleException $e) { - throw new BusinessException($e->getMessage()); - } - } - - public function removeCloudCert(array $data): mixed - { - $option = [ - 'form_params' => [ - 'entityId' => $data['user_id'], - 'pin' => $data['user_id'], - 'authType' => '实人认证', - 'authTime' => $this->getAuthTime(), - 'authResult' => '认证通过', - 'authNoticeType' => '数字证书吊销告知', - ], - ]; - - try { - $response = $this->httpRequest( - $this->api_url . '/cloud-certificate-service/api/cloudCert/open/v2/cert/certRevoke', - $option - ); - if (empty($response)) { - throw new BusinessException(HttpEnumCode::getMessage(HttpEnumCode::SERVER_ERROR)); - } - - return $response; - } catch (GuzzleException $e) { - throw new BusinessException($e->getMessage()); - } - } - - public function renewCloudCert(array $data): mixed - { - $option = [ - 'form_params' => [ - 'entityId' => $data['user_id'], - 'pin' => $data['user_id'], - 'authType' => '实人认证', - 'authTime' => $this->getAuthTime(), - 'authResult' => '认证通过', - 'authNoticeType' => '数字证书更新告知', - ], - ]; - - try { - $response = $this->httpRequest( - $this->api_url . '/cloud-certificate-service/api/cloudCert/open/v2/cert/certRenew', - $option - ); - if (empty($response)) { - throw new BusinessException(HttpEnumCode::getMessage(HttpEnumCode::SERVER_ERROR)); - } - - return $response; - } catch (GuzzleException $e) { - throw new BusinessException($e->getMessage()); - } - } - - public function getServiceUrl(array $data): mixed - { - $option = [ - 'form_params' => $data, - ]; - - try { - return $this->httpRequest($this->api_url . '/open/api/data/getServiceUrl', $option); - } catch (GuzzleException $e) { - throw new BusinessException($e->getMessage()); - } - } - - public function getPasswordLessSignInfo(string $entityId): mixed - { - $option = [ - 'form_params' => [ - 'entityId' => $entityId, - ], - ]; - - try { - return $this->httpRequest($this->api_url . '/open/api/data/passwordLessSignInfo', $option); - } catch (GuzzleException $e) { - throw new BusinessException($e->getMessage()); - } - } - - protected function resolveCertSerialnumber(string $entityId, array $response): string - { - $serialNumber = parent::resolveCertSerialnumber($entityId, $response); - if ($serialNumber !== '') { - return $serialNumber; - } - - $signInfo = $this->getPasswordLessSignInfo($entityId); - return (string) ($signInfo['certSn'] ?? ''); - } - - protected function getAuthTime(): string - { - return (string) round(microtime(true) * 1000); - } -} diff --git a/runtime_ca_doc.html b/runtime_ca_doc.html deleted file mode 100644 index e271c89..0000000 --- a/runtime_ca_doc.html +++ /dev/null @@ -1,258 +0,0 @@ - -
- - - -