httpPostJson(); 访问链接 //new Client($app); 上传文件 parent::__construct($config); $this->store_id = $config['store_id']; $this->mini_id = $config['mini_id']; $this->app = (new WechatMini())::getWechatConfig($config['store_id'], $config['mini_id']); } public function storeIcpInfo() { try { $mini_id = $this->mini_id; //查询当前状态 //查询人脸核身任务状态 $this->queryIcpVerifyTask(); //获取小程序备案状态及驳回原因 $this->getIcpEntranceInfo(); $store_mini_icp_info = StoreMiniIcp::find()->where(['mini_id' => $mini_id, 'is_delete' => 0]) ->select('task_id, mini_id, face_status, icp_form, icp_audit_status, icp_audit_info') ->asArray()->one(); if ($store_mini_icp_info) { $store_mini_icp_info['face_status'] = (int)$store_mini_icp_info['face_status']; if (intval($store_mini_icp_info['icp_audit_status']) >= 2) { $store_mini_icp_info['face_status'] = 3; } $store_mini_icp_info['icp_audit_status'] = (int)$store_mini_icp_info['icp_audit_status']; $store_mini_icp_info['icp_form'] = json_decode($store_mini_icp_info['icp_form'], true); $store_mini_icp_info['icp_audit_info'] = json_decode($store_mini_icp_info['icp_audit_info'], true) ?: ''; } else { $store_mini_icp_info = (object)[]; } $data = [ 'icp_info' => $store_mini_icp_info ]; //单位性质 $icpSubjectTypesResult = $this->queryIcpSubjectTypes(); if ($icpSubjectTypesResult['code'] === 0) { $data = array_merge($data, [ 'subject_types' => $icpSubjectTypesResult['data']['data'] ]); } //区域信息 $icpDistrictCodeResult = $this->queryIcpDistrictCode(); if ($icpDistrictCodeResult['code'] === 0) { $data = array_merge($data, [ 'district_code' => $icpDistrictCodeResult['data']['data'] ]); } //获取证件类型 $icpCertificateTypesResult = $this->queryIcpCertificateTypes(); if ($icpCertificateTypesResult['code'] === 0) { $data = array_merge($data, [ 'certificate_types' => $icpCertificateTypesResult['data']['data'] ]); } //获取前置审批项类型 $queryIcpNrlxTypesResult = $this->queryIcpNrlxTypes(); if ($queryIcpNrlxTypesResult['code'] === 0) { $data = array_merge($data, [ 'nrlx_types' => $queryIcpNrlxTypesResult['data']['data'] ]); } //获取小程序服务内容类型 $icpServiceContentTypesResult = $this->queryIcpServiceContentTypes(); if ($icpServiceContentTypesResult['code'] === 0) { $data = array_merge($data, [ 'service_content_types' => $icpServiceContentTypesResult['data']['data'] ]); } return [ 'code' => 0, 'msg' => '获取成功', 'data' => $data ]; } catch (\Exception $e) { return [ 'code' => $e->getCode() ?: 1, 'msg' => $e->getMessage() ]; } } /** * 申请小程序备案 */ public function applyIcpFiling() { try { //请求微信接口 $app = $this->app; if (!$app) { throw new \Exception('获取小程序信息失败'); } $params_ = $this->params; $mini_id = $this->mini_id; $store_mini_icp = StoreMiniIcp::findOne(['mini_id' => $mini_id, 'is_delete' => 0]); if (!$store_mini_icp) { throw new \Exception('未进行人脸识别核验'); } $store_mini_icp->icp_form = json_encode($params_, JSON_UNESCAPED_UNICODE); if (!$store_mini_icp->save()) { throw new \Exception(json_encode($store_mini_icp->errors, JSON_UNESCAPED_UNICODE)); } if (!$store_mini_icp->task_id) { throw new \Exception('未进行人脸识别核验'); } // TODO 图片处理 ['media_id' => '', 'url' => ''] ['微信所需media_id' => '', '前端图片显示地址' => ''] //备案主体信息-个人主体额外信息-临时居住证明照片 $residence_permit = $params_['icp_subject']['personal_info']['residence_permit']; if ($residence_permit) { $params_['icp_subject']['personal_info']['residence_permit'] = $residence_permit['media_id']; } //备案主体信息-主体额外信息-主体证件照片 $certificate_photo = $params_['icp_subject']['organize_info']['certificate_photo']; if ($certificate_photo) { $params_['icp_subject']['organize_info']['certificate_photo'] = $certificate_photo['media_id']; } //备案主体信息-主体负责人信息-负责人证件正面照片 $certificate_photo_front = $params_['icp_subject']['principal_info']['certificate_photo_front']; if ($certificate_photo_front) { $params_['icp_subject']['principal_info']['certificate_photo_front'] = $certificate_photo_front['media_id']; } //备案主体信息-主体负责人信息-负责人证件背面照片 $certificate_photo_back = $params_['icp_subject']['principal_info']['certificate_photo_back']; if ($certificate_photo_back) { $params_['icp_subject']['principal_info']['certificate_photo_back'] = $certificate_photo_back['media_id']; } //备案主体信息-主体负责人信息-授权书 $authorization_letter = $params_['icp_subject']['principal_info']['authorization_letter']; if ($authorization_letter) { $params_['icp_subject']['principal_info']['authorization_letter'] = $authorization_letter['media_id']; } //备案主体信息-主体负责人信息-扫脸认证任务id $params_['icp_subject']['principal_info']['verify_task_id'] = $store_mini_icp->task_id; //微信小程序信息-微信小程序基本信息-前置审批项-前置审批媒体材料 $nrlx_details_media = $params_['icp_applets']['base_info']['nrlx_details']['media']; if ($nrlx_details_media) { $params_['icp_applets']['base_info']['nrlx_details']['media'] = $nrlx_details_media['media_id']; } //微信小程序信息-小程序负责人信息-负责人证件正面照片 $certificate_photo_front = $params_['icp_applets']['principal_info']['certificate_photo_front']; if ($certificate_photo_front) { $params_['icp_applets']['principal_info']['certificate_photo_front'] = $certificate_photo_front['media_id']; } //微信小程序信息-小程序负责人信息-负责人证件背面照片 $certificate_photo_back = $params_['icp_applets']['principal_info']['certificate_photo_back']; if ($certificate_photo_back) { $params_['icp_applets']['principal_info']['certificate_photo_back'] = $certificate_photo_back['media_id']; } //微信小程序信息-小程序负责人信息-授权书 $authorization_letter = $params_['icp_applets']['principal_info']['authorization_letter']; if ($authorization_letter) { $params_['icp_applets']['principal_info']['authorization_letter'] = $authorization_letter['media_id']; } //微信小程序信息-小程序负责人信息-扫脸认证任务id $params_['icp_applets']['principal_info']['verify_task_id'] = $store_mini_icp->task_id; //其他备案媒体材料-互联网信息服务承诺书 最大数量1 $commitment_letter_ = $params_['icp_materials']['commitment_letter']; if ($commitment_letter_) { $params_['icp_materials']['commitment_letter'] = $this->arrayChange($commitment_letter_); } //其他备案媒体材料-主体更名函 media_id(非个人类型,且发生过更名时需要上传) 最大数量1 $business_name_change_letter_ = $params_['icp_materials']['business_name_change_letter']; if ($business_name_change_letter_) { $params_['icp_materials']['business_name_change_letter'] = $this->arrayChange($business_name_change_letter_); } //其他备案媒体材料-党建确认函 最大数量1 $party_building_confirmation_letter_ = $params_['icp_materials']['party_building_confirmation_letter']; if ($party_building_confirmation_letter_) { $params_['icp_materials']['party_building_confirmation_letter'] = $this->arrayChange($party_building_confirmation_letter_); } //其他备案媒体材料-承诺视频 最大数量1 $promise_video_ = $params_['icp_materials']['promise_video']; if ($promise_video_) { $params_['icp_materials']['promise_video'] = $this->arrayChange($promise_video_); } //其他备案媒体材料-党建确认函 最大数量1 $authenticity_responsibility_letter_ = $params_['icp_materials']['authenticity_responsibility_letter']; if ($authenticity_responsibility_letter_) { $params_['icp_materials']['authenticity_responsibility_letter'] = $this->arrayChange($authenticity_responsibility_letter_); } //其他备案媒体材料-小程序备案信息真实性承诺书 最大数量1 $authenticity_commitment_letter_ = $params_['icp_materials']['authenticity_commitment_letter']; if ($authenticity_commitment_letter_) { $params_['icp_materials']['authenticity_commitment_letter'] = $this->arrayChange($authenticity_commitment_letter_); } //其他备案媒体材料-小程序建设方案书 最大数量1 $website_construction_proposal_ = $params_['icp_materials']['website_construction_proposal']; if ($website_construction_proposal_) { $params_['icp_materials']['website_construction_proposal'] = $this->arrayChange($website_construction_proposal_); } //其他备案媒体材料-主体其它附件 最大数量10 $subject_other_materials_ = $params_['icp_materials']['subject_other_materials']; if ($subject_other_materials_) { $params_['icp_materials']['subject_other_materials'] = $this->arrayChange($subject_other_materials_); } //其他备案媒体材料-小程序其它附件 最大数量10 $applets_other_materials_ = $params_['icp_materials']['applets_other_materials']; if ($applets_other_materials_) { $params_['icp_materials']['applets_other_materials'] = $this->arrayChange($applets_other_materials_); } //其他备案媒体材料-手持证件照 最大数量1 $holding_certificate_photo_ = $params_['icp_materials']['holding_certificate_photo']; if ($holding_certificate_photo_) { $params_['icp_materials']['holding_certificate_photo'] = $this->arrayChange($holding_certificate_photo_); } if ($params_['icp_applets']['base_info']['nrlx_details']) { foreach ($params_['icp_applets']['base_info']['nrlx_details'] as $nrlx_index => $nrlx_item) { if (intval($nrlx_item['type']) === 24) {//以上都不涉及 $params_['icp_applets']['base_info']['nrlx_details'][$nrlx_index] = [ 'type' => 24 ]; } } } else { $params_['icp_applets']['base_info']['nrlx_details'] = [ [ 'type' => 24 ] ]; } if (isset($params_['icp_subject']['base_info']['commnet'])) { unset($params_['icp_subject']['base_info']['commnet']); } $client = new BaseClient($app); $result = $client->httpPostJson('wxa/icp/apply_icp_filing', $params_); //返回微信信息 if ($result['errcode'] !== 0) { $msg = $result['errmsg']; if ($result['hints']) { $msg = ''; foreach ($result['hints'] as $hint) { if ($hint['errmsg']) { $msg .= $hint['errmsg'] . ";"; } } } throw new \Exception($msg, $result['errcode']); } return [ 'code' => 0, 'msg' => '申请已提交' ]; } catch (\Exception $e) { if (strpos($e->getMessage(), 'cURL error 28') !== false) { return $this->applyIcpFiling(); } return [ 'code' => $e->getCode() ?: 1, 'msg' => $e->getMessage() ]; } } /** * @param array $array * @return array * 数组转换 */ public function arrayChange($array = []) { $array_ = []; foreach ($array as $item) { if ($item['media_id']) { $array_[] = $item['media_id']; } } return $array_; } /** * 获取小程序备案状态及驳回原因 */ public function getIcpEntranceInfo() { try { //请求微信接口 $app = $this->app; if (!$app) { throw new \Exception('获取小程序信息失败'); } $mini_id = $this->mini_id; $client = new BaseClient($app); $result = $client->httpGet('wxa/icp/get_icp_entrance_info'); //返回微信信息 if ($result['errcode'] !== 0) { throw new \Exception($result['errmsg'], $result['errcode']); } $status = $result['info']['status']; $is_canceling = (int)$result['info']['is_canceling']; $audit_data = $result['info']['audit_data']; $store_mini_icp = StoreMiniIcp::findOne(['mini_id' => $mini_id, 'is_delete' => 0]); if ($store_mini_icp) { $store_mini_icp->icp_audit_status = (int)$status; $store_mini_icp->is_cancel_icp = $is_canceling; if ($is_canceling === 1) { $store_mini_icp->is_delete = 1; } $store_mini_icp->icp_audit_info = json_encode($audit_data, JSON_UNESCAPED_UNICODE); if (!$store_mini_icp->save()) { throw new \Exception(json_encode($store_mini_icp->errors, JSON_UNESCAPED_UNICODE)); } } return [ 'code' => 0, 'msg' => '状态已更新' ]; } catch (\Exception $e) { return [ 'code' => $e->getCode() ?: 1, 'msg' => $e->getMessage() ]; } } /** * 撤销小程序备案申请 */ public function cancelApplyIcpFiling() { try { //请求微信接口 $app = $this->app; if (!$app) { throw new \Exception('获取小程序信息失败'); } $mini_id = $this->mini_id; $client = new BaseClient($app); $result = $client->httpPostJson('wxa/icp/cancel_apply_icp_filing'); //返回微信信息 if ($result['errcode'] !== 0) { throw new \Exception($result['errmsg'], $result['errcode']); } $store_mini_icp = StoreMiniIcp::findOne(['mini_id' => $mini_id, 'is_delete' => 0]); if ($store_mini_icp) { $store_mini_icp->is_cancel_icp = 1; $store_mini_icp->is_delete = 1; if (!$store_mini_icp->save()) { throw new \Exception(json_encode($store_mini_icp->errors, JSON_UNESCAPED_UNICODE)); } } return [ 'code' => 0, 'msg' => '申请已提交' ]; } catch (\Exception $e) { return [ 'code' => $e->getCode() ?: 1, 'msg' => $e->getMessage() ]; } } /** * 注销小程序备案 */ public function cancelIcpfiling() { try { //请求微信接口 $app = $this->app; if (!$app) { throw new \Exception('获取小程序信息失败'); } $params_ = $this->params; $data = [ 'cancel_type' => (int)$params_['cancel_type'] ]; $client = new BaseClient($app); $result = $client->httpPostJson('wxa/icp/cancel_icp_filing', $data); //返回微信信息 if ($result['errcode'] !== 0) { throw new \Exception($result['errmsg'], $result['errcode']); } return [ 'code' => 0, 'msg' => '提交成功,请注意短信通知,如果想终止注销流程,忽略该条短信即可' ]; } catch (\Exception $e) { return [ 'code' => $e->getCode() ?: 1, 'msg' => $e->getMessage() ]; } } /** * 发起小程序管理员人脸核身 */ public function createIcpVerifyTask() { try { //请求微信接口 $app = $this->app; if (!$app) { throw new \Exception('获取小程序信息失败'); } $store_id = $this->store_id; $mini_id = $this->mini_id; $store_mini_icp = StoreMiniIcp::findOne(['mini_id' => $mini_id, 'is_delete' => 0]); // $end_time = intval($store_mini_icp->created_at) + (60 * 60 * 24); // if (($store_mini_icp && ($end_time < time())) || !$store_mini_icp) { $client = new BaseClient($app); $result = $client->httpPostJson('wxa/icp/create_icp_verifytask'); //返回微信信息 if ($result['errcode'] !== 0) { throw new \Exception($result['errmsg'], $result['errcode']); } // StoreMiniIcp::updateAll(['is_delete' => 1], ['mini_id' => $mini_id, 'is_delete' => 0]); // TODO 首次猜测可能每个小程序备案一次 //保存人脸核验任务id task_id if (!$store_mini_icp) { $store_mini_icp = new StoreMiniIcp(); } $store_mini_icp->task_id = $result['task_id']; // } else { // if (in_array($store_mini_icp->face_status, [0, 1]) && $end_time > time()) { // throw new \Exception('请在公众平台安全助手中点击小程序备案人脸核验提醒消息继续完成核验'); // } // } $store_mini_icp->store_id = $store_id; $store_mini_icp->mini_id = $mini_id; $store_mini_icp->created_at = time(); if (!$store_mini_icp->save()) { throw new \Exception(json_encode($store_mini_icp->errors, JSON_UNESCAPED_UNICODE)); } return [ 'code' => 0, 'msg' => '已发送人脸核身', 'data' => [ 'task_id' => $result['task_id'] ] ]; } catch (\Exception $e) { return [ 'code' => $e->getCode() ?: 1, 'msg' => $e->getMessage() ]; } } /** * 查询人脸核身任务状态 */ public function queryIcpVerifyTask() { try { //请求微信接口 $app = $this->app; if (!$app) { throw new \Exception('获取小程序信息失败'); } $mini_id = $this->mini_id; $params_ = $this->params; $store_mini_icp = StoreMiniIcp::find()->where(['task_id' => $params_['task_id'], 'is_delete' => 0]) ->select('id, task_id')->asArray()->one(); if (!$store_mini_icp) { $store_mini_icp = StoreMiniIcp::find()->where(['mini_id' => $mini_id, 'is_delete' => 0]) ->select('id, task_id')->asArray()->one(); } if (empty($store_mini_icp)) { throw new \Exception('查询任务id失败'); } $data = [ 'task_id' => $store_mini_icp['task_id'] ]; $client = new BaseClient($app); $result = $client->httpPostJson('wxa/icp/query_icp_verifytask', $data); //返回微信信息 if ($result['errcode'] !== 0) { throw new \Exception($result['errmsg'], $result['errcode']); } $store_mini_icp = StoreMiniIcp::findOne($store_mini_icp['id']); if ($result['face_status'] !== intval($store_mini_icp->face_status)) { $store_mini_icp->face_time = time(); } $end_time = intval($store_mini_icp->created_at) + (60 * 60 * 24 * 3); if ($end_time > time() && intval($result['face_status']) === 0) { $result['face_status'] = -1; } $store_mini_icp->is_finish = (int)$result['is_finish']; $store_mini_icp->face_status = (int)$result['face_status']; if (!$store_mini_icp->save()) { throw new \Exception(json_encode($store_mini_icp->errors, JSON_UNESCAPED_UNICODE)); } return [ 'code' => 0, 'msg' => '已更新人脸核身状态' ]; } catch (\Exception $e) { return [ 'code' => $e->getCode() ?: 1, 'msg' => $e->getMessage() ]; } } /** * 获取单位性质 */ public function queryIcpSubjectTypes() { try { //请求微信接口 $app = $this->app; if (!$app) { throw new \Exception('获取小程序信息失败'); } $client = new BaseClient($app); $result = $client->httpGet('wxa/icp/query_icp_subject_types'); //返回微信信息 if ($result['errcode'] !== 0) { throw new \Exception($result['errmsg'], $result['errcode']); } $icp_certificate_type_result = $this->queryIcpCertificateTypes(); if ($icp_certificate_type_result['code'] === 0) { $icp_certificate_type = $icp_certificate_type_result['data']['data']; foreach ($result['items'] as &$item) { foreach ($icp_certificate_type as $type) { if ($type['subject_type'] === $item['type']) { $item['icp_type'][] = $type; } } } } return [ 'code' => 0, 'msg' => '获取成功', 'data' => [ 'data' => $result['items'] ] ]; } catch (\Exception $e) { return [ 'code' => $e->getCode() ?: 1, 'msg' => $e->getMessage() ]; } } /** * 获取区域信息 */ public function queryIcpDistrictCode() { try { //请求微信接口 $app = $this->app; if (!$app) { throw new \Exception('获取小程序信息失败'); } $client = new BaseClient($app); $result = $client->httpGet('wxa/icp/query_icp_district_code'); //返回微信信息 if ($result['errcode'] !== 0) { throw new \Exception($result['errmsg'], $result['errcode']); } return [ 'code' => 0, 'msg' => '获取成功', 'data' => [ 'data' => $result['items'] ] ]; } catch (\Exception $e) { return [ 'code' => $e->getCode() ?: 1, 'msg' => $e->getMessage() ]; } } /** * 获取证件类型 */ public function queryIcpCertificateTypes() { try { //请求微信接口 $app = $this->app; if (!$app) { throw new \Exception('获取小程序信息失败'); } $client = new BaseClient($app); $result = $client->httpGet('wxa/icp/query_icp_certificate_types'); //返回微信信息 if ($result['errcode'] !== 0) { throw new \Exception($result['errmsg'], $result['errcode']); } return [ 'code' => 0, 'msg' => '获取成功', 'data' => [ 'data' => $result['items'] ] ]; } catch (\Exception $e) { return [ 'code' => $e->getCode() ?: 1, 'msg' => $e->getMessage() ]; } } /** * 获取前置审批项类型 */ public function queryIcpNrlxTypes() { try { //请求微信接口 $app = $this->app; if (!$app) { throw new \Exception('获取小程序信息失败'); } $client = new BaseClient($app); $result = $client->httpGet('wxa/icp/query_icp_nrlx_types'); //返回微信信息 if ($result['errcode'] !== 0) { throw new \Exception($result['errmsg'], $result['errcode']); } return [ 'code' => 0, 'msg' => '获取成功', 'data' => [ 'data' => $result['items'] ] ]; } catch (\Exception $e) { return [ 'code' => $e->getCode() ?: 1, 'msg' => $e->getMessage() ]; } } /** * 获取小程序服务内容类型 */ public function queryIcpServiceContentTypes() { try { //请求微信接口 $app = $this->app; if (!$app) { throw new \Exception('获取小程序信息失败'); } $client = new BaseClient($app); $result = $client->httpGet('wxa/icp/query_icp_service_content_types'); //返回微信信息 if ($result['errcode'] !== 0) { throw new \Exception($result['errmsg'], $result['errcode']); } $result['items'] = $this->getChild($result['items']); return [ 'code' => 0, 'msg' => '获取成功', 'data' => [ 'data' => $result['items'] ] ]; } catch (\Exception $e) { return [ 'code' => $e->getCode() ?: 1, 'msg' => $e->getMessage() ]; } } public function getChild($content, $type = 0){ $arr = []; foreach ($content as $k => $v) { if($v['parent_type'] == $type){ $v['child'] = $this->getChild($content, $v['type']); $arr[] = $v; } } return $arr; } /** * 上传media图片 */ public function uploadIcpMedia() { try { //请求微信接口 $app = $this->app; if (!$app) { throw new \Exception('获取小程序信息失败'); } $params_ = $this->params; $client = new BaseClient($app); $params = [ 'media' => $params_['media'] ]; $image_path = $this->saveTempImage($params['media']); $imageUrl = Image::ImageSize($image_path, 2); $result = $client->httpUpload('wxa/icp/upload_icp_media', [ 'media' => $imageUrl ], [ 'type' => $params_['type'], 'certificate_type' => $params_['certificate_type'], 'icp_order_field' => $params_['icp_order_field'], ]); //返回微信信息 if ($result['errcode'] !== 0) { throw new \Exception($result['errmsg'], $result['errcode']); } $store_media = new StoreMedia(); $store_media->store_id = $this->store_id; $store_media->mini_id = $this->mini_id; $store_media->media_id = $result['media_id']; $store_media->event = $params_['icp_order_field']; $store_media->local_url = $params['media']; $store_media->save(); return [ 'code' => 0, 'msg' => '获取成功', 'data' => [ 'media_id' => $result['media_id'] ] ]; } catch (\Exception $e) { return [ 'code' => $e->getCode() ?: 1, 'msg' => $e->getMessage() ]; } } //获取网络图片到临时目录 private function saveTempImage($url) { if (strpos($url, 'http') === false) { $url = 'http:' . trim($url); } if (!is_dir(\Yii::$app->runtimePath . '/image')) { mkdir(\Yii::$app->runtimePath . '/image'); } $save_path = \Yii::$app->runtimePath . '/image/' . md5($url) . '.jpg'; CurlHelper::download($url, $save_path); return $save_path; } }