DiverseYouthNightSchool/application/manystoreapi/controller/Common.php

363 lines
14 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\manystoreapi\controller;
use app\admin\model\school\classes\VirtualHead;
use app\common\controller\ManystoreApiBase;
use app\common\exception\UploadException;
use app\common\library\Upload;
use app\common\library\Virtual;
use app\common\model\Area;
use app\common\model\ManystoreAttachment;
use app\common\model\Version;
use fast\Random;
use think\captcha\Captcha;
use think\Config;
use think\Hook;
/**
* 机构API后台公共接口
*/
class Common extends ManystoreApiBase
{
protected $noNeedLogin = ['init', 'captcha','virtualgenerate','get_week_by_time'];
protected $noNeedRight = '*';
public function _initialize()
{
if (isset($_SERVER['HTTP_ORIGIN'])) {
header('Access-Control-Expose-Headers: __token__');//跨域让客户端获取到
}
//跨域检测
check_cors_request();
if (!isset($_COOKIE['PHPSESSID'])) {
Config::set('session.id', $this->request->server("HTTP_SID"));
}
parent::_initialize();
}
/**
* 加载初始化
*
* @ApiParams (name="version", type="string", required=true, description="版本号")
* @ApiParams (name="lng", type="string", required=true, description="经度")
* @ApiParams (name="lat", type="string", required=true, description="纬度")
*/
public function init()
{
if ($version = $this->request->request('version')) {
$lng = $this->request->request('lng');
$lat = $this->request->request('lat');
//配置信息
$upload = Config::get('upload');
//如果非服务端中转模式需要修改为中转
if ($upload['storage'] != 'local' && isset($upload['uploadmode']) && $upload['uploadmode'] != 'server') {
//临时修改上传模式为服务端中转
set_addon_config($upload['storage'], ["uploadmode" => "server"], false);
$upload = \app\common\model\Config::upload();
// 上传信息配置后
Hook::listen("upload_config_init", $upload);
$upload = Config::set('upload', array_merge(Config::get('upload'), $upload));
}
$upload['cdnurl'] = $upload['cdnurl'] ? $upload['cdnurl'] : cdnurl('', true);
$upload['uploadurl'] = preg_match("/^((?:[a-z]+:)?\/\/)(.*)/i", $upload['uploadurl']) ? $upload['uploadurl'] : url($upload['storage'] == 'local' ? '/api/common/upload' : $upload['uploadurl'], '', false, true);
$content = [
'citydata' => Area::getCityFromLngLat($lng, $lat),
'versiondata' => Version::check($version),
'uploaddata' => $upload,
'coverdata' => Config::get("cover"),
];
$this->apisuccess('', $content);
} else {
$this->apierror(__('Invalid parameters'));
}
}
/**
* 用户上传文件(上传到总后台)
* @ApiMethod (POST)
* @ApiParams (name="file", type="File", required=true, description="文件流")
* @ApiParams (name="category", type="string", required=true, description="分类标识category1=非机密类1,category2=非机密类2,cert=证件机密类,code=二维码类,user=用户普通上传")
*
*/
public function upload()
{
Config::set('default_return_type', 'json');
//必须设定cdnurl为空,否则cdnurl函数计算错误
Config::set('upload.cdnurl', '');
$category = $this->request->post("category",'user');
// var_dump($category);die;
$chunkid = $this->request->post("chunkid");
if ($chunkid) {
if (!Config::get('upload.chunking')) {
$this->apierror(__('Chunk file disabled'));
}
$action = $this->request->post("action");
$chunkindex = $this->request->post("chunkindex/d");
$chunkcount = $this->request->post("chunkcount/d");
$filename = $this->request->post("filename");
$method = $this->request->method(true);
if ($action == 'merge') {
$attachment = null;
//合并分片文件
try {
$upload = new Upload();
$attachment = $upload->merge($chunkid, $chunkcount, $filename);
} catch (UploadException $e) {
$this->apierror($e->getMessage());
}
$this->apisuccess(__('Uploaded successful'), ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
} elseif ($method == 'clean') {
//删除冗余的分片文件
try {
$upload = new Upload();
$upload->clean($chunkid);
} catch (UploadException $e) {
$this->apierror($e->getMessage());
}
$this->apisuccess();
} else {
//上传分片文件
//默认普通上传文件
$file = $this->request->file('file');
try {
$upload = new Upload($file);
$upload->chunk($chunkid, $chunkindex, $chunkcount);
} catch (UploadException $e) {
$this->apierror($e->getMessage());
}
$this->apisuccess();
}
} else {
$attachment = null;
//默认普通上传文件
$file = $this->request->file('file');
try {
$upload = new Upload($file,$category);
$attachment = $upload->upload();
// $attachment = $upload->upload();
} catch (UploadException $e) {
$this->apierror($e->getMessage().$e->getFile().$e->getLine());
} catch (\Exception $e) {
$this->apierror($e->getMessage().$e->getFile().$e->getLine());
}
$this->apisuccess(__('Uploaded successful'), ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
}
}
/**
* 机构端上传文件(上传到机构后台)
* @ApiMethod (POST)
* @ApiParams (name="file", type="File", required=true, description="文件流")
* @ApiParams (name="category", type="string", required=true, description="分类标识category1=非机密类1,category2=非机密类2,cert=证件机密类,code=二维码类,user=用户普通上传")
*
*/
public function manystoreupload()
{
Config::set('default_return_type', 'json');
$file = $this->request->file('file');
$category = $this->request->post("category",'user');
if (empty($file)) {
$this->apierror(__('No file upload or server upload limit exceeded'));
}
//判断是否已经存在附件
$sha1 = $file->hash();
$extparam = $this->request->post();
$upload = Config::get('upload');
preg_match('/(\d+)(\w+)/', $upload['maxsize'], $matches);
$type = strtolower($matches[2]);
$typeDict = ['b' => 0, 'k' => 1, 'kb' => 1, 'm' => 2, 'mb' => 2, 'gb' => 3, 'g' => 3];
$size = (int)$upload['maxsize'] * pow(1024, isset($typeDict[$type]) ? $typeDict[$type] : 0);
$fileInfo = $file->getInfo();
$suffix = strtolower(pathinfo($fileInfo['name'], PATHINFO_EXTENSION));
$suffix = $suffix && preg_match("/^[a-zA-Z0-9]+$/", $suffix) ? $suffix : 'file';
$fileInfo['suffix'] = $suffix;
$mimetypeArr = explode(',', strtolower($upload['mimetype']));
$typeArr = explode('/', $fileInfo['type']);
//禁止上传PHP和HTML文件
if (in_array($fileInfo['type'], ['text/x-php', 'text/html']) || in_array($suffix, ['php', 'html', 'htm', 'phar', 'phtml']) || preg_match("/^php(.*)/i", $fileInfo['suffix'])) {
$this->apierror(__('Uploaded file format is limited'));
}
//Mimetype值不正确
if (stripos($fileInfo['type'], '/') === false) {
$this->apierror(__('Uploaded file format is limited'));
}
//验证文件后缀
if ($upload['mimetype'] !== '*' &&
(
!in_array($suffix, $mimetypeArr)
|| (stripos($typeArr[0] . '/', $upload['mimetype']) !== false && (!in_array($fileInfo['type'], $mimetypeArr) && !in_array($typeArr[0] . '/*', $mimetypeArr)))
)
) {
$this->apierror(__('Uploaded file format is limited'));
}
//验证是否为图片文件
$imagewidth = $imageheight = 0;
if (in_array($fileInfo['type'], ['image/gif', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/png', 'image/webp']) || in_array($suffix, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'webp'])) {
$imgInfo = getimagesize($fileInfo['tmp_name']);
if (!$imgInfo || !isset($imgInfo[0]) || !isset($imgInfo[1])) {
$this->apierror(__('Uploaded file is not a valid image'));
}
$imagewidth = isset($imgInfo[0]) ? $imgInfo[0] : $imagewidth;
$imageheight = isset($imgInfo[1]) ? $imgInfo[1] : $imageheight;
}
$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($fileInfo['name'], 0, strripos($fileInfo['name'], '.')) : $fileInfo['name'],
'{suffix}' => $suffix,
'{.suffix}' => $suffix ? '.' . $suffix : '',
'{filemd5}' => md5_file($fileInfo['tmp_name']),
];
$savekey = $upload['savekey'];
$savekey = str_replace(array_keys($replaceArr), array_values($replaceArr), $savekey);
$uploadDir = substr($savekey, 0, strripos($savekey, '/') + 1);
$fileName = substr($savekey, strripos($savekey, '/') + 1);
//
$splInfo = $file->validate(['size' => $size])->move(ROOT_PATH . '/public' . $uploadDir, $fileName);
$category = array_key_exists($category, config('site.attachmentcategory') ?? []) ? $category : 'user';
if ($splInfo) {
$user_id = 0;
$user = $this->auth->getUser();//登录用户
if($user)$user_id = $user['user_id'];
$params = array(
'category' => $category,
'shop_id' => (int)$this->auth->shop_id ?:0,
'user_id' => $user_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 = new ManystoreAttachment;
$attachment->data(array_filter($params));
$attachment->save();
\think\Hook::listen("upload_after", $attachment);
// $this->success(__('Upload successful'), null, [
// 'url' => $uploadDir . $splInfo->getSaveName()
// ]);
$this->apisuccess(__('Uploaded successful'), ['url' => $attachment->url, 'fullurl' => cdnurl($attachment->url, true)]);
} else {
// 上传失败获取错误信息
$this->apierror($file->getError());
}
}
/**
* 验证码
* @ApiParams (name="id", type="string", required=true, description="要生成验证码的标识")
* @return \think\Response
*/
public function captcha($id = "")
{
\think\Config::set([
'captcha' => array_merge(config('captcha'), [
'fontSize' => 44,
'imageH' => 150,
'imageW' => 350,
])
]);
$captcha = new Captcha((array)Config::get('captcha'));
return $captcha->entry($id);
}
/**
* @ApiTitle(生成随机昵称和头像)
* @ApiSummary(生成随机昵称和头像)
* @ApiMethod(GET)
* @ApiParams(name = "number", type = "int",required=true,description = "生成数量")
* @ApiReturn({ unpaid_user_data 参与中 paid_user_data 已报名 })
*/
public function virtualgenerate(){
$number = $this->request->get('number/d','');
if(empty($number)){
$this->apierror(__('缺少必要参数'));
}
try {
$res = (new Virtual)->getVirtualUser($number);
} catch (\Exception $e){
// Log::log($e->getMessage());
$this->apierror($e->getMessage(),['errcode'=>$e->getCode()]);
}
$this->apisuccess('生成成功', $res);
}
/**
* @ApiTitle(通过时间点得到当前的星期数据)
* @ApiSummary(通过时间点得到当前的星期数据)
* @ApiMethod(GET)
* @ApiParams(name="time",type="string",required=true,description="选择的时间点")
* @ApiReturn({ unpaid_user_data 参与中 paid_user_data 已报名 })
*/
public function get_week_by_time(){
$time = $this->request->get('time/s','');
// if(empty($time)){
// $this->error(__('缺少必要参数'));
// }
try {
$res = (new Virtual)->getWeekByTime($time);
} catch (\Exception $e){
// Log::log($e->getMessage());
$this->apierror($e->getMessage(),['errcode'=>$e->getCode()]);
}
$this->apisuccess('生成成功', $res);
}
}