diff --git a/app/Cache/Redis/Common/CommonRedisKey.php b/app/Cache/Redis/Common/CommonRedisKey.php index 4e64c48..92e7351 100644 --- a/app/Cache/Redis/Common/CommonRedisKey.php +++ b/app/Cache/Redis/Common/CommonRedisKey.php @@ -5,10 +5,10 @@ namespace App\Cache\Redis\Common; class CommonRedisKey { /** - * @var $type * @return string + *@var string $type */ - public static function getSystemRegionList($type = 'all') + public static function getSystemRegionList(string $type = 'all'): string { return '__system:address:list:'.$type; } diff --git a/app/Controller/Common/ThirdCallbackController.php b/app/Controller/Common/ThirdCallbackController.php new file mode 100644 index 0000000..4dacc46 --- /dev/null +++ b/app/Controller/Common/ThirdCallbackController.php @@ -0,0 +1,29 @@ +process(); + } +} diff --git a/app/Cron/Oss/OssDelByDisableTask.php b/app/Cron/Oss/OssDelByDisableTask.php index bf15a2f..cc4888d 100644 --- a/app/Cron/Oss/OssDelByDisableTask.php +++ b/app/Cron/Oss/OssDelByDisableTask.php @@ -10,14 +10,57 @@ declare(strict_types=1); namespace App\Cron\Oss; +use App\Cache\Redis\Common\CommonRedisKey; +use App\Cache\Redis\RedisCache; +use App\Extend\DateUtil; +use App\Lib\Log; +use App\Model\OssObject; use Hyperf\Crontab\Annotation\Crontab; +use Hyperf\Di\Annotation\Inject; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; +use RedisException; -#[Crontab(rule: "* * * * *", name: "OssDelByDisableTask", singleton: true , callback: "execute", memo: "这是一个示例的定时任务")] +#[Crontab(rule: "0 5 * * *", name: "OssDelByDisableTask", singleton: true , callback: "execute", memo: "定时删除未使用的oss资源")] class OssDelByDisableTask { - public function execute() + /** + * 日志 + * @var Log $log + */ + #[Inject] + protected Log $log; + + /** + * 缓存 + * @var RedisCache $redis + */ + #[Inject] + protected RedisCache $redis; + + /** + * @return void + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws RedisException + */ + public function execute(): void { - //todo Write logic - var_dump(date('Y-m-d H:i:s', time())); + $ossObjectModel = new OssObject(); + + $time = date('Y-m-d H:i:s',time() - DateUtil::DAY); + $list = $ossObjectModel->getOssIdListByIsEnabled($time); + + if (empty($list)){ + $this->log->notice(__CLASS__.'昨日没有无效的资源'); + return; + } + + + foreach ($list->toArray() as $item) { + $this->redis->lPush(CommonRedisKey::getDeleteOssImgListByOssId(), (string)$item,'system'); + } + + $this->log->notice(__CLASS__.'异步删除昨日无效图片'); } } \ No newline at end of file diff --git a/app/Cron/Oss/OssDelByOssIdTask.php b/app/Cron/Oss/OssDelByOssIdTask.php index 2d14da9..e70a6b0 100644 --- a/app/Cron/Oss/OssDelByOssIdTask.php +++ b/app/Cron/Oss/OssDelByOssIdTask.php @@ -10,14 +10,90 @@ declare(strict_types=1); namespace App\Cron\Oss; +use App\Cache\Redis\Common\CommonRedisKey; +use App\Cache\Redis\RedisCache; +use App\Lib\Log; +use App\Model\OssObject; use Hyperf\Crontab\Annotation\Crontab; +use Hyperf\Di\Annotation\Inject; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; -#[Crontab(rule: "* * * * *", name: "OssDelByOssIdTask", singleton: true , callback: "execute", memo: "这是一个示例的定时任务")] +#[Crontab(rule: "* * * * *", name: "OssDelByOssIdTask", singleton: true , callback: "execute", memo: "根据id删除oss的逻辑")] class OssDelByOssIdTask { - public function execute() + /** + * 日志 + * @var Log $log + */ + #[Inject] + protected Log $log; + + /** + * 缓存 + * @var RedisCache $redis + */ + #[Inject] + protected RedisCache $redis; + + /** + * @return void + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + */ + public function execute(): void { - //todo Write logic - var_dump(date('Y-m-d H:i:s', time())); + try { + $key = CommonRedisKey::getDeleteOssImgListByOssId(); + + $delNum = 0; + $ossIds = []; + for ($i = 1; $i < 50; $i++) { + $one = $this->redis->rPop($key); + if (empty($one)){ + continue; + } + $ossIds[] = $one; + } + + if (count($ossIds) == 0) { + $this->log->notice(__CLASS__.':success:无根据id删除的列表'); + return; + } + + $ossObjectModel = new OssObject(); + + //获取url列表用于删除oss + $urlList = $ossObjectModel->whereIn('id', $ossIds)->pluck('url'); + + if (empty($urlList)){ + $this->log->error(__CLASS__.':删除内容关联失败,无法获取url!'); + return; + } + + if(count($urlList->toArray()) != count($ossIds)) + { + $this->log->error(__CLASS__.':删除内容关联失败,url数量与id数量不一致!'); + return; + } + + // 删除oss图片 + $res = $ossObjectModel->whereIn('id', $ossIds)->delete(); + if (!$res) { + $this->log->error(__CLASS__.':删除内容关联失败,删除sql执行失败!'); + return; + } + + //删除oss资源 + //把图片地址丢到删除redis队列 + foreach ($urlList as $item) { + $this->redis->lPush(CommonRedisKey::getDeleteOssImgListByUrl(), $item); + } + + $this->log->notice(__CLASS__.':success:删除oss文件个数:' . $delNum); + }catch (\Exception $e){ + $this->log->error(__CLASS__.':'.$e->getMessage()); + return; + } } } \ No newline at end of file diff --git a/app/Cron/Oss/OssDelByUrlTask.php b/app/Cron/Oss/OssDelByUrlTask.php index 0f87328..a6d0be8 100644 --- a/app/Cron/Oss/OssDelByUrlTask.php +++ b/app/Cron/Oss/OssDelByUrlTask.php @@ -10,14 +10,66 @@ declare(strict_types=1); namespace App\Cron\Oss; +use App\Cache\Redis\Common\CommonRedisKey; +use App\Cache\Redis\RedisCache; +use App\Lib\Log; use Hyperf\Crontab\Annotation\Crontab; +use Hyperf\Di\Annotation\Inject; +use OSS\Core\OssException; +use OSS\Http\RequestCore_Exception; +use OSS\OssClient; +use Psr\Container\ContainerExceptionInterface; +use Psr\Container\NotFoundExceptionInterface; +use RedisException; +use function Hyperf\Config\config; -#[Crontab(rule: "* * * * *", name: "OssDelByUrlTask", singleton: true , callback: "execute", memo: "这是一个示例的定时任务")] +#[Crontab(rule: "* * * * *", name: "OssDelByUrlTask", singleton: true , callback: "execute", memo: "根据url删除oss的逻辑")] class OssDelByUrlTask { - public function execute() + /** + * 日志 + * @var Log $log + */ + #[Inject] + protected Log $log; + + /** + * 缓存 + * @var RedisCache $redis + */ + #[Inject] + protected RedisCache $redis; + + /** + * @return void + * @throws OssException + * @throws RequestCore_Exception + * @throws ContainerExceptionInterface + * @throws NotFoundExceptionInterface + * @throws RedisException + */ + public function execute(): void { - //todo Write logic - var_dump(date('Y-m-d H:i:s', time())); + $key = CommonRedisKey::getDeleteOssImgListByUrl(); + + // 阿里云oss上传 + $OssClient = new OssClient( + config('ali.access_key_id'), + config('ali.access_key_secret'), + config('ali.intranet_endpoint') + ); + $bucket = config('ali.bucket'); + + $delNum = 0; + for ($i = 1; $i < 50; $i++) { + $url = $this->redis->rPop($key); + + if (!empty($url)) { + $delNum++; + $OssClient->deleteObject($bucket, $url); + } + } + + $this->log->notice(__CLASS__.':success:删除oss文件个数:' . $delNum); } } \ No newline at end of file diff --git a/app/Extend/DateUtil.php b/app/Extend/DateUtil.php new file mode 100644 index 0000000..a67c046 --- /dev/null +++ b/app/Extend/DateUtil.php @@ -0,0 +1,99 @@ + 'integer', 'size' => 'integer','height' => 'integer', 'width' => 'integer', 'audio_second' => 'integer', 'video_duration' => 'integer', 'is_enabled' => 'integer', 'type' => 'integer']; + + const CREATED_AT = 'create_time'; + + const UPDATED_AT = null; + + /** + * url访问器 + * @param $value + * @return string + */ + public function getUrlAttribute($value) + { + return config('ali.oss_url').$value; + } + + /** + * 根据ids获取资源id列表 + * @param array $ids + * @return Collection + */ + public function getIdListByIds(array $ids): Collection + { + return $this->whereIn('id', $ids)->pluck('id'); + } + + + /** + * 根据ids更新oss Enable状态 + */ + public function updateEnabledByIds(array $ids): int + { + return $this->whereIn('id', $ids)->update(['is_enabled' => 1]); + } + + /** + * 根据ids 更新oss Disable状态 + * @param array $ids + * @return int + */ + public function updateDisableByIds(array $ids): int + { + return $this->whereIn('id', $ids)->update(['is_enabled' => 0]); + } + + /** + * 根据id获取信息 + * @param array $ids + * @return Collection + */ + public function getInfoByOssIds(array $ids): Collection + { + return $this->whereIn('id', $ids)->get(); + } + + /** + * 根据is_enabled获取传入时间前无效资源id + * @param $time + * @return Collection|false + */ + public function getOssIdListByIsEnabled($time): Collection|false + { + return $this->where([ + ['is_enabled', '=', 0], + ['create_time', '<',$time] + ])->pluck('id') ?? false; + } +} diff --git a/app/Service/Common/OssCallbackService.php b/app/Service/Common/OssCallbackService.php index 7bcb1c7..0932d85 100644 --- a/app/Service/Common/OssCallbackService.php +++ b/app/Service/Common/OssCallbackService.php @@ -10,13 +10,12 @@ declare(strict_types=1); namespace App\Service\Common; -use AlibabaCloud\SDK\Sts\V20150401\Sts; use App\Cache\Redis\Common\CommonRedisKey; use App\Cache\Redis\RedisCache; use App\Exception\AdminException; use App\Lib\AdminReturn; use App\Lib\Log; -use App\Service\ServiceTrait\Common\AliStsTrait; +use App\Model\OssObject; use Exception; use Hyperf\Di\Annotation\Inject; use Hyperf\HttpServer\Contract\RequestInterface; @@ -28,7 +27,6 @@ use function Hyperf\Config\config; class OssCallbackService { - use AliStsTrait; /** * 请求对象 @@ -116,7 +114,7 @@ class OssCallbackService $this->ossClient = new OssClient( config('ali.access_key_id'), config('ali.access_key_secret'), - config('oss.sts_endpoint') + config('ali.intranet_endpoint') ); $this->bucket = config('ali.bucket'); @@ -167,7 +165,8 @@ class OssCallbackService return $this->adminReturn->success('上传成功',[ 'id' => $this->newId, - 'url' => config('ali.oss_url') . $this->newObjectPath, 'old_file_name' => $this->fileName + 'url' => config('ali.oss_url') . $this->newObjectPath, + 'old_file_name' => $this->fileName ]); } @@ -277,23 +276,23 @@ class OssCallbackService break; } -// $ossObjectModel = new OssObject(); -// -// $ossObjectModel->url = $this->newObjectPath; -//// $ossObjectModel->url = urldecode($this->data['object']); -// $ossObjectModel->width = $this->data['imageInfo_width'] ?? 0; -// $ossObjectModel->height = $this->data['imageInfo_height'] ?? 0; -// $ossObjectModel->audio_second = $this->data['audio_second'] ?? 0; -// $ossObjectModel->video_duration = $this->data['video_duration'] ?? 0; -// $ossObjectModel->size = $this->data['size'] ?? 0; -// -// $ossObjectModel->type = $type; -// -// if (!$ossObjectModel->save()){ -// throw new AdminException('保存图片失败'); -// } + $ossObjectModel = new OssObject(); -// $this->newId = $ossObjectModel->id; + $ossObjectModel->url = $this->newObjectPath; +// $ossObjectModel->url = urldecode($this->data['object']); + $ossObjectModel->width = $this->data['imageInfo_width'] ?? 0; + $ossObjectModel->height = $this->data['imageInfo_height'] ?? 0; + $ossObjectModel->audio_second = $this->data['audio_second'] ?? 0; + $ossObjectModel->video_duration = $this->data['video_duration'] ?? 0; + $ossObjectModel->size = $this->data['size'] ?? 0; + + $ossObjectModel->type = $type; + + if (!$ossObjectModel->save()){ + throw new AdminException('保存图片失败'); + } + + $this->newId = $ossObjectModel->id; } /** @@ -305,7 +304,7 @@ class OssCallbackService private function deleteOssObject(): void { //删除旧的文件 - $this->redisCache->lPush(CommonRedisKey::getDeleteOssImgListByUrl(), $this->data['object']); + $this->redisCache->lPush(CommonRedisKey::getDeleteOssImgListByUrl(), $this->data['object'],'system'); } } \ No newline at end of file diff --git a/config/autoload/ali.php b/config/autoload/ali.php index 11d2e0c..3662089 100644 --- a/config/autoload/ali.php +++ b/config/autoload/ali.php @@ -31,4 +31,6 @@ return [ 'sts_endpoint' => env('ALI_STS_ENDPOINT', 'sts.cn-shenzhen.aliyuncs.com'), // 阿里云 sts 角色 'role_arn' => env('ALI_ROLE_ARN', 'acs:ram::1644087445786901:role/oss'), + // 阿里云内网 endpoint + 'intranet_endpoint' => env('ALI_INTRANET_ENDPOINT', 'oss-cn-shenzhen-internal.aliyuncs.com'), ]; \ No newline at end of file