['image/jpeg', 'image/png', 'image/x-png'], 'on' => ['idCardFront', 'idCardBack', 'ad']], // todo 暂时屏蔽 // [['file'], 'file', 'mimeTypes'=>['application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'text/csv'], 'on'=>['excel']], [['file'], 'isIdCardFront', 'on' => ['idCardFront']], [['file'], 'isInvoiceFront', 'on' => ['invoiceFront']], //[['file'], 'isIdCardBack', 'on'=>['idCardBack']], ]; } /** * 指定校验场景 * @return array */ public function scenarios() { $parentScenarios = parent::scenarios(); $customScenarios = [ 'idCardFront' => ['file', 'token'], 'idCardBack' => ['file', 'token'], 'invoiceFront' => ['file', 'token', 'remark', 'withdrawId'], 'proveFront' => ['file', 'token', 'rechargeId'], 'ad' => ['file', 'token'], 'article' => ['file', 'token'], 'excel' => ['file', 'token', 'excelOption'], 'goodsImg' => ['file', 'token'], ]; return array_merge($parentScenarios, $customScenarios); } public function attributeLabels() { return [ 'file' => '文件', ]; } /** * 校验上传token * @param $attributes */ public function isToken($attributes) { if (!Cache::getUploadToken($this->token)) { $this->addError($attributes, '上传token校验失败'); } } /** * 是否是身份证 * @param $attributes */ public function isIdCardFront($attributes) { // 查看该用户是否已经上传过身份证照片 $oneData = User::find()->select('ID_IMAGE')->where('ID=:ID', [':ID' => \Yii::$app->user->id])->asArray()->one(); if ($oneData['ID_IMAGE']) { $this->addError($attributes, '您已上传过身份证照片'); } $this->_ocrResult = OcrApi::instance()->idCard($this->file->tempName); if (!$this->_ocrResult['success']) { $this->addError($attributes, $this->_ocrResult['message']); } } /** * 前台上传发票 * @param $attributes */ public function isInvoiceFront($attributes) { $this->_ocrResult = OcrApi::instance()->vatInvoice($this->file->tempName); if (!$this->_ocrResult['success']) { $this->addError($attributes, $this->_ocrResult['message']); } } /** * 上传 * @return bool * @throws \yii\db\Exception */ public function upload() { if (!$this->validate()) { return false; } $oneUser = User::findOne(['ID' => \Yii::$app->user->id]); $db = \Yii::$app->db; $transaction = $db->beginTransaction(); try { switch ($this->scenario) { case 'invoiceFront': $uploadCategory = Uploads::CATEGORY_INVOICE; $uploadRemark = $this->remark; break; case 'idCardFront': $uploadCategory = Uploads::CATEGORY_ID_CARD; $uploadRemark = $this->_ocrResult['realName'] . '身份证正面'; break; case 'idCardBack': $uploadCategory = Uploads::CATEGORY_ID_CARD; $uploadRemark = $oneUser['REAL_NAME'] . '身份证背面'; break; case 'proveFront': case 'goodsImg': case 'ad': $uploadCategory = Uploads::CATEGORY_IMAGE; $uploadRemark = $this->file->baseName; break; case 'excel': $uploadCategory = Uploads::CATEGORY_EXCEL; $uploadRemark = $this->file->baseName; break; default : $uploadCategory = Uploads::CATEGORY_UN_KNOW; $uploadRemark = $this->file->baseName; break; } // 上传图片到远程服务器 if (in_array($this->scenario, $this->_remoteScenario)) { $remoteUploadApi = RemoteUploadApi::instance(); if ($uploadResult = $remoteUploadApi->upload($this->file->tempName)) { $uploadInfo = [ 'fileName' => $uploadResult['name'], 'category' => $uploadCategory, 'url' => $uploadResult['url'], 'fileSize' => $uploadResult['size'] ?? null, 'md5' => $uploadResult['md5'] ?? null, ]; } else { throw new Exception('Remote service error'); } // 删除本地临时文件 unlink($this->file->tempName); } else { // 生成文件名 $fileName = Tool::generateId(false); // $fileName = $this->file->baseName; // 保存在本地 $localPath = \Yii::$app->params['localUpload']['dns'] . $fileName . '.' . $this->file->extension; // $localPath = '/ng-stage/Volumes/HDD/workshop/old/ar.upload.ming/files/' . $fileName . '.' . $this->file->extension; if (!$this->file->saveAs($localPath)) { throw new Exception('Failed'); } $uploadInfo = [ 'fileName' => $fileName . '.' . $this->file->extension, 'category' => $uploadCategory, 'url' => $fileName . '.' . $this->file->extension, 'fileSize' => null, 'md5' => null, ]; } // 把上传的文件写入数据库记录中 // 把文件对应的相关资料存入数据库中 $uploads = new Uploads(); $uploads->FILE_NAME = $uploadInfo['fileName']; $uploads->CATEGORY = $uploadInfo['category']; $uploads->URL = $uploadInfo['url']; $uploads->FILE_SIZE = $uploadInfo['fileSize'] ?? null; $uploads->MD5 = $uploadInfo['md5'] ?? null; $uploads->REMARK = $uploadRemark; $uploads->CREATED_AT = Date::nowTime(); if (!$uploads->save()) { throw new Exception('Save error'); } // 如果是上传发票,更新发票信息,并绑定提现记录 if ($this->scenario == 'invoiceFront') { $withdraw = Withdraw::findOne(['ID' => $this->withdrawId]); //判断金额是否一致 if ($withdraw['AMOUNT'] != $this->_ocrResult['amount']) { throw new Exception('上传发票金额'.$this->_ocrResult['amount'].'与提现金额【'.$withdraw['AMOUNT'].'】不一致'); } //发票内容是否与后台预置信息相符 $configName = Cache::getSystemConfig()['invoiceItemName']['VALUE']; if (!in_array($this->_ocrResult['itemName'], explode("\n",$configName))) { throw new Exception('上传发票中货物或应税劳务服务名称与后台预置信息【' . $configName . '】不一致'); } //写入发票数据 if (InvoiceAudit::find()->where('INVOICE_NUM=:INVOICE_NUM AND WITHDRAW_ID!=:WITHDRAW_ID AND AUDIT_STATUS!=:AUDIT_STATUS', [':INVOICE_NUM' => $this->_ocrResult['invoiceNum'], ':WITHDRAW_ID' => $this->withdrawId, ':AUDIT_STATUS' => \Yii::$app->params['auditStatus']['reject']['value']])->exists()) { throw new Exception('该发票已被使用'); } if(!$invoiceModel = InvoiceAudit::findOne(['WITHDRAW_ID' => $this->withdrawId])){ $invoiceModel = new InvoiceAudit(); } $invoiceModel->USER_ID = $oneUser['ID']; $invoiceModel->WITHDRAW_ID = $this->withdrawId; $invoiceModel->INVOICE_CODE = $this->_ocrResult['invoiceCode']; $invoiceModel->INVOICE_NUM = $this->_ocrResult['invoiceNum']; $invoiceModel->INVOICE_DATE = $this->_ocrResult['invoiceDate']; $invoiceModel->AMOUNT = $this->_ocrResult['amount']; $invoiceModel->TAX_RATE = $this->_ocrResult['taxRate']; $invoiceModel->PURCHASER_NAME = $this->_ocrResult['purchaserName']; $invoiceModel->PURCHASER_REGISTER_NUM = $this->_ocrResult['purchaserRegisterNum']; $invoiceModel->PURCHASER_ADDRESS = $this->_ocrResult['purchaserAddress']; $invoiceModel->PURCHASER_BANK = $this->_ocrResult['purchaserBank']; $invoiceModel->SELLER_NAME = $this->_ocrResult['sellerName']; $invoiceModel->SELLER_REGISTER_NUM = $this->_ocrResult['sellerRegisterNum']; $invoiceModel->SELLER_ADDRESS = $this->_ocrResult['sellerAddress']; $invoiceModel->SELLER_BANK = $this->_ocrResult['sellerBank']; $invoiceModel->ITEM_NAME = $this->_ocrResult['itemName']; $invoiceModel->INVOICE_REMARK = $this->_ocrResult['invoiceRemark']; $invoiceModel->UPLOAD_ID = $uploads->ID; $invoiceModel->CREATED_AT = Date::nowTime(); if (!$invoiceModel->save()) { throw new Exception(Form::formatErrorsForApi($invoiceModel->getErrors())); } //写入提现表 $withdraw->INVOICE_ID = $invoiceModel->ID; $withdraw->AUDIT_STATUS = Withdraw::STATUS_APPLIED; $withdraw->UPDATED_AT = Date::nowTime(); if (!$withdraw->save()) { throw new Exception(Form::formatErrorsForApi($withdraw->getErrors())); } } // 如果是上传身份证正面的场景,则把识别出来的信息更新当前的会员信息 elseif ($this->scenario == 'idCardFront') { // 修改用户基本信息 $oneUser->REAL_NAME = $this->_ocrResult['realName']; $oneUser->ID_CARD = $this->_ocrResult['idCardNo']; $oneUser->ADDRESS = $this->_ocrResult['address']; $oneUser->NATION = Info::getNationCode($this->_ocrResult['nation']); $oneUser->ID_IMAGE = $uploadInfo['url']; if (!$oneUser->save()) { // throw new Exception('用户基本资料保存失败'); throw new Exception(Form::formatErrorsForApi($oneUser->getErrors())); } // 更新会员信息缓存 User::updateBaseInfoToRedis($oneUser['ID']); } elseif ($this->scenario == 'excel') { $excelTableClass = Excel::EXCEL_STRUCTURE[$this->excelOption]['excelTableClass']; // 把上传的文件写入到导入记录中 $excelImport = new ExcelImport(); $excelImport->OPTION_NAME = $this->excelOption; $excelImport->TABLE_NAME = $excelTableClass::tableName(); $excelImport->UPLOAD_ID = $uploads->ID; $excelImport->AUDIT_STATUS = \Yii::$app->params['auditStatus']['true']['value']; $excelImport->IMPORT_ADMIN_ID = \Yii::$app->user->id; $excelImport->AUDIT_ADMIN_ID = \Yii::$app->user->id; $excelImport->CREATED_AT = Date::nowTime(); if (!$excelImport->save()) { throw new Exception(Form::formatErrorsForApi($excelImport->getErrors())); } }elseif ($this->scenario == 'proveFront') { // 如果是上传充值凭证,绑定充值记录 $recharge = Recharge::findOne(['ID' => $this->rechargeId]); if(!$recharge){ throw new Exception("缺少参数ID"); } //写入充值表 $recharge->BANK_PROVE = $uploadInfo['fileName']; $recharge->AUDIT_STATUS = Recharge::STATUS_PROVED; if (!$recharge->save()) { throw new Exception(Form::formatErrorsForApi($recharge->getErrors())); } } $transaction->commit(); } catch (Exception $e) { $transaction->rollBack(); $this->addError('upload', $e->getMessage()); return false; } return $uploads; } }