<?php namespace app\api\controller; use addons\qiniu\library\Auth; use app\common\controller\Api; use app\common\model\Area; use app\common\model\Attachment; use app\common\model\Version; use fast\Random; use think\Config; /** * 公共接口 */ class Common extends Api { protected $noNeedLogin = ['init','upload','upload_base64','base64_image_content']; protected $noNeedRight = '*'; /** * 加载初始化 * * @param string $version 版本号 * @param string $lng 经度 * @param string $lat 纬度 */ public function init() { if ($version = $this->request->request('version')) { $lng = $this->request->request('lng'); $lat = $this->request->request('lat'); $content = [ 'citydata' => Area::getCityFromLngLat($lng, $lat), 'versiondata' => Version::check($version), 'uploaddata' => Config::get('upload'), 'coverdata' => Config::get("cover"), ]; $this->success('', $content); } else { $this->error(__('Invalid parameters')); } } /** * 上传文件 * @ApiMethod (POST) * @param File $file 文件流 */ public function upload() { Config::set('default_return_type', 'json'); $config = get_addon_config('qiniu'); $file = $this->request->file('file'); if (!$file || !$file->isValid()) { $this->error("请上传有效的文件"); } $fileInfo = $file->getInfo(); $filePath = $file->getRealPath() ?: $file->getPathname(); preg_match('/(\d+)(\w+)/', $config['maxsize'], $matches); $type = strtolower($matches[2]); $typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3]; $size = (int)$config['maxsize'] * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0); $suffix = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION)); $suffix = $suffix ? $suffix : 'file'; $md5 = md5_file($filePath); $search = ['$(year)', '$(mon)', '$(day)', '$(etag)', '$(ext)']; $replace = [date("Y"), date("m"), date("d"), $md5, '.' . $suffix]; $object = ltrim(str_replace($search, $replace, $config['savekey']), '/'); $mimetypeArr = explode(',', strtolower($config['mimetype'])); $typeArr = explode('/', $fileInfo['type']); //检查文件大小 if (!$file->checkSize($size)) { $this->error("起过最大可上传文件限制"); } //验证文件后缀 if ($config['mimetype'] !== '*' && ( !in_array($suffix, $mimetypeArr) || (stripos($typeArr[0] . '/', $config['mimetype']) !== false && (!in_array($fileInfo['type'], $mimetypeArr) && !in_array($typeArr[0] . '/*', $mimetypeArr))) ) ) { $this->error(__('上传格式限制')); } $savekey = '/' . $object; $uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1); $fileName = substr($savekey, strripos($savekey, '/') + 1); //先上传到本地 $splInfo = $file->move(ROOT_PATH . '/public' . $uploadDir, $fileName); if ($splInfo) { $extparam = $this->request->post(); $filePath = $splInfo->getRealPath() ?: $splInfo->getPathname(); $sha1 = sha1_file($filePath); $imagewidth = $imageheight = 0; if (in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf'])) { $imgInfo = getimagesize($splInfo->getPathname()); $imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : $imagewidth; $imageheight = isset($imgInfo[1]) ? $imgInfo[1] : $imageheight; } $params = array( 'admin_id' => session('admin.id'), // 'user_id' => $this->auth->id, 'filesize' => $fileInfo['size'], 'imagewidth' => $imagewidth, 'imageheight' => $imageheight, 'imagetype' => $suffix, 'imageframes' => 0, 'mimetype' => $fileInfo['type'], 'url' => $uploadDir . $splInfo->getSaveName(), 'uploadtime' => time(), 'storage' => 'local', 'sha1' => $sha1, 'extparam' => json_encode($extparam), ); $attachment = Attachment::create(array_filter($params), true); $policy = array( 'saveKey' => ltrim($savekey, '/'), ); $auth = new \addons\qiniu\library\Auth($config['app_key'], $config['secret_key']); $token = $auth->uploadToken($config['bucket'], null, $config['expire'], $policy); $multipart = [ ['name' => 'token', 'contents' => $token], [ 'name' => 'file', 'contents' => fopen($filePath, 'r'), 'filename' => $fileName, ] ]; try { $client = new \GuzzleHttp\Client(); $res = $client->request('POST', $config['uploadurl'], [ 'multipart' => $multipart ]); $code = $res->getStatusCode(); //成功不做任何操作 } catch (\GuzzleHttp\Exception\ClientException $e) { $attachment->delete(); unlink($filePath); $this->error("上传失败"); } $qiniu = get_addon_config('qiniu')['cdnurl']; $url['yuan'] = '/' . $object; $url['dai'] = $qiniu.'/' . $object; //上传成功后将存储变更为qiniu $attachment->storage = 'qiniu'; $attachment->save(); $this->success("上传成功", $url); } else { $this->error('上传失败'); } return; } /** * base64上传文件 * * @ApiTitle (base64上传文件) * @ApiSummary (base64上传文件) * @ApiMethod (POST) * @ApiRoute (/api/common/upload_base64) * @ApiParams (name="base64_img", type="string", required=true, description="图片base64数据") * @ApiReturnParams (name="code", type="integer", required=true, sample="0") * @ApiReturnParams (name="msg", type="string", required=true, sample="返回成功") * @ApiReturn ({ 'code':'1', 'msg':'返回成功', "data": { "url": 当前页数, "priview_url": 总页数 } }) * */ public function upload_base64() { if($this->request->isPost()) { $param = $this->request->param(); $validate = new \think\Validate([ 'base64_img' => 'require', ]); $validate->message([ 'base64_img.require' => '缺少图片base64数据!', ]); if (!$validate->check($param)) { $this->error($validate->getError()); } $path = '/uploads/lesson_app'; $image = $this->base64_image_content($param['base64_img'],$path); if(!$image) { $this->error('上传失败'); } $upload = Config::get('upload'); $config = get_addon_config('qiniu'); $filePath = '.'.$path.'/'.$image; $suffix = strtolower(pathinfo($filePath, PATHINFO_EXTENSION)); $suffix = $suffix && preg_match("/^[a-zA-Z0-9]+$/", $suffix) ? $suffix : 'file'; $replaceArr = [ '{year}' => date("Y"), '{mon}' => date("m"), '{day}' => date("d"), '{hour}' => date("H"), '{min}' => date("i"), '{sec}' => date("s"), '{random}' => Random::alnum(16), '{random32}' => Random::alnum(32), '{filename}' => $suffix ? substr(pathinfo($filePath)['basename'], 0, strripos(pathinfo($filePath)['basename'], '.')) : pathinfo($filePath)['basename'], '{suffix}' => $suffix, '{.suffix}' => $suffix ? '.' . $suffix : '', '{filemd5}' => md5_file(realpath($filePath)), ]; $savekey = $upload['savekey']; $savekey = str_replace(array_keys($replaceArr), array_values($replaceArr), $savekey); $fileName = substr($savekey, strripos($savekey, '/') + 1); $policy = array( 'saveKey' => ltrim($savekey, '/'), ); $auth = new Auth($config['app_key'], $config['secret_key']); $token = $auth->uploadToken($config['bucket'], null, $config['expire'], $policy); $multipart = [ ['name' => 'token', 'contents' => $token], [ 'name' => 'file', 'contents' => fopen(realpath($filePath), 'r'), 'filename' => $fileName, ] ]; try { $client = new \GuzzleHttp\Client(); $res = $client->request('POST', $config['uploadurl'], [ 'multipart' => $multipart ]); $code = $res->getStatusCode(); //成功不做任何操作 } catch (\GuzzleHttp\Exception\ClientException $e) { // $attachment->delete(); unlink($filePath); $this->error("上传失败"); } unlink($filePath); $return = [ 'url' => $savekey, 'priview_url' => cdnurl($savekey,true) ]; $this->success('上传成功',$return); } } /** * [将Base64图片转换为本地图片并保存] * @E-mial wuliqiang_aa@163.com * @TIME 2017-04-07 * @WEB http://blog.iinu.com.cn * @param [Base64] $base64_image_content [要保存的Base64] * @param [目录] $path [要保存的路径] */ private function base64_image_content($base64_image_content,$path){ //匹配出图片的格式 if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)){ $type = $result[2]; $file_path = date('Ymd',time())."/"; $new_file = '.'.$path."/".$file_path; if(!file_exists($new_file)){ //检查是否有该文件夹,如果没有就创建,并给予最高权限 mkdir($new_file, 0777,true); } $new_file = $new_file.time().".{$type}"; if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $base64_image_content)))){ return $file_path.time().".{$type}"; }else{ return false; } }else{ return false; } } }