express 定时删除 oss 垃圾图片

一: 删除垃圾图片

思路:
  1. 获取 oss 中存储的所有图片文件;
  2. 获取数据库中存储的图片文件数据;
  3. 对比差异,不在数据库中的 oss 图片文件即为要删除的垃圾图片。
实现:

1、获取所有 oss 文件

import OSS from 'ali-oss'
import prisma from '@/services/index'import config from '@/config'
const { aliAccessKey, aliAccessKeySecret, ossBucketName, ossRegion } = configimport TaskOssScheduler from './schedule'const client = new OSS({region: ossRegion,accessKeyId: aliAccessKey,accessKeySecret: aliAccessKeySecret,bucket: ossBucketName
})/*** @description 获取 oss 下的图片* @param other * @returns */
export const getAllImgFromOss: any = async (other: any = {}) => {try {let continuationToken = null;let imgArray: string[] = []// 每页列举1000个文件。const maxKeys = '5';do {const result: any = await client.listV2({delimiter: '/',prefix: 'web/','start-after': 'web/', // web/ 目录之后的文件'continuation-token': continuationToken,'max-keys': maxKeys,...other}, {});continuationToken = result.nextContinuationToken;const { objects = [] } = resultfor (let i = 0; i < objects.length; i++) {imgArray.push(objects[i].name);}console.log(result);} while (continuationToken)return {list: imgArray,count: imgArray.length || 0,}} catch (error) {console.log(error);return []}
}

2、获取所有数据存储的图片数据

/*** 从数据库中获取图片*/
export const getAllImgFromModel = async () => {try {let dataBaseImgs: any = []// todo 未来查询多表const imgList = await prisma.applySitter.findMany({select: {idCardFrontUrl: true,idCardBackUrl: true,groomerImgUrl: true,manAndPetPhotoUrl: true,}})// 平铺返回值并替换路径域名部分imgList.map(item => {const items = Object.values(item).map(itemMap => itemMap?.replace('https://xxxx.com/', ''))dataBaseImgs.push(...items)})console.log(dataBaseImgs);return dataBaseImgs} catch (error) {return []}
}// 删除 oss 图片
export const delOssImgs = async (imgArr: string[]) => {try {const result = await client.deleteMulti(imgArr, { quiet: true });return result} catch (error) {throw error}
}

3、对比差异,找到要删除的图片

// 删除 oss 垃圾图片
export const delOssBadImgs = async () => {try {// 获取 oss 文件列表,// todo 暂时只获取 web 目录下图片// 1. oss 图片const ossResult = await getAllImgFromOss() || {}// 2. 存储到数据库图片const dataBaseResult = await getAllImgFromModel() || []// 3. 对比差异const badImgArr: string[] = []ossResult.list.forEach((arrItem: string) => {if (arrItem && !dataBaseResult.includes(arrItem)) {badImgArr.push(arrItem)}})// 4. 删除指定图片const delRes = await delOssImgs(badImgArr)// console.log('--->badImg');// console.log(badImgArr);if (delRes?.res.status === 200) {console.log('删除 oss 垃圾图片成功')} else {console.log('删除 oss 垃圾图片失败')}} catch (error) {}
}

二: 创建定时任务

1、安装依赖包 npm i node-schedule @types/node-schedule -S
node-schedule 为创建定时任务第三方库
2、创建定时任务基类文件 taskOssScheduler.ts

import schedule from 'node-schedule'
import dayjs from 'dayjs'
import type { Job, JobCallback } from 'node-schedule';// 定时任务基类
export default class TaskOssScheduler {cronExpression: string;task: JobCallback;job: Job | null;constructor(cronExpression: string, task: any) {this.cronExpression = cronExpressionthis.task = taskthis.job = null}// 启动任务start() {// 如果当前没有正在运行的任务,则创建新的任务if (!this.job) {this.job = schedule.scheduleJob(this.cronExpression, this.task);console.log(`定时任务启动: ${this.cronExpression}`);console.log(dayjs().format('YYYYMMDD-HH:mm:ss'));} else {this.stop()}}// 停止任务stop() {// 如果当前有正在运行的任务,则取消任务并将 job 设为 nullif (this.job) {this.job.cancel();console.log(`定时任务停止: ${this.cronExpression}`);console.log(dayjs().format('YYYYMMDD-HH:mm:ss'));this.job = null;}}
}

3、定义工具函数

// 每天的凌晨 2 点进行删除
// 入参任务开始时间及回调函数
export const DelOssImgTask = new TaskOssScheduler('0 0 2 * * *', delOssBadImgs)

4、定义 express 路由,通过访问路由,开启和关闭定时任务
ossController:

  startDelOssImgTask: async (req: Request, res: Response) => {try {// 开启定时删除 oss 垃圾图片任务DelOssImgTask.start()res.send(ComResult.success('定时任务开启'))} catch (error) {throw error}},stopDelOssImgTask: async (req: Request, res: Response) => {try {// 关闭定时删除 oss 垃圾图片任务DelOssImgTask.stop()res.send(ComResult.success('定时任务关闭'))} catch (error) {throw error}}

ossRoutes:

ossRoutes.post('/startDelOssImgTask', ossController.startDelOssImgTask)
ossRoutes.post('/stopDelOssImgTask', ossController.stopDelOssImgTask)

三、测试

在这里插入图片描述
oss 删除结果
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/682751.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Pr教程1-8节笔记

第一课 认识PR以及PR的学习方法 学习任务&#xff1a; 1、熟练掌握PR软件&#xff0c;同时掌握剪辑技术以及常用于制作特效的效果器。 2、认识PR软件的名称、主要功能以及用途作用。 3、明白学习PR我们能做些什么以及PR的学习方法。 知识内容&#xff1a; 1、PR是专门用于视…

微服务—ES数据同步

目录 数据同步 问题分析 方案1. 同步调用 方案2. 异步通知 方案3. 监听binlog​编辑 各方案对比 案例——利用MQ实现数据同步 步骤1. 导入hotel-admin项目 步骤2. 声明交换机、队列 步骤3. 发送MQ消息 步骤4. 接收MQ消息 步骤5. 测试同步功能 数据同步 elasticsea…

C#,计算几何,贝塞耳插值(Bessel‘s interpolation)的算法与源代码

Friedrich Wilhelm Bessel 1 贝塞耳插值&#xff08;Bessels interpolation&#xff09; 首先要区别于另外一个读音接近的插值算法&#xff1a;贝塞尔插值&#xff08;Bzier&#xff09;。 &#xff08;1&#xff09;读音接近&#xff0c;但不是一个人&#xff1b; &#x…

【zabbix】(三)-邮件告警配置

企业微信、钉钉和邮件告警配置的目的是为了确保监控系统检测到的问题能够及时传达给相关人员&#xff0c;并通过灵活的通知方式提高团队的响应速度和协作效率。 本文介绍的是QQ邮件告警 一 开启发件服务器SMTP功能 本文使用的是QQ邮箱&#xff0c;其他邮箱操作类似&#xff…

【Pygame手册01/20】最简应用:窗口

目录 一、说明 二、pygame是什么&#xff1f; 2.1 为游戏开发设计 2.2 版本发展史 2.3 特点 三、pygame安装要点 四、入门知识 4.1 初始使用 4.2 要更改 pygame 窗口的外观 4.3 完整窗口程序 4.4 窗口对象接口示例 五、隐形窗口和显性窗口 六、结论 一、说明 为什…

MySQL-----函数篇

目录 ▶ 字符串函数 ▶ 数值函数 ▶ 日期函数 ▶ 流程函数 ▶ 简介 函数是指一段可以直接被另一段程序调用的程序或代码。 ▶ 字符串函数 函数描述实例ASCII(s)返回字符串 s 的第一个字符的 ASCII 码。 返回 CustomerName 字段第一个字母的 ASCII 码&#xff1a; S…

电路设计(18)——9路抢答器的设计与制作

1.设计要求 设计、制作一台9路抢答器&#xff0c;抢答器应符合如下工作过程&#xff1a; 每次抢答前&#xff0c;主持人首先按下复位键&#xff0c;将抢答器上“抢答号”数显复位&#xff0c;显示为“0”。接着&#xff0c;主持人念答题内容&#xff0c;念毕即叫“抢答…

炫酷3D按钮

一.预览 该样式有一种3D变换的高级感&#xff0c;大家可以合理利用这些样式到自己的按钮上 二.代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice…

Java网络编程 双向通信

目录 网络编程实例创建客户端创建服务端测试 网络编程 Java的网络编程是Java编程语言中用于实现网络通信的一组API和工具。通过Java的网络编程&#xff0c;开发人员可以在Java应用程序中实现客户端和服务器之间的通信&#xff0c;从而构建各种网络应用。 以下是Java网络编程的…

步步深入 k8s 使用 pv pvc sc 在 nfs 基础上共享存储

博客原文 文章目录 前言集群环境nfs 环境搭建pod 挂载 nfs架构图 pvc 方式挂载 nfs架构图 storageclass 方式动态申请 pv架构图 参考 前言 持久化卷&#xff08;Persistent Volume, PV&#xff09;允许用户将外部存储映射到集群&#xff0c;而持久化卷申请&#xff08;Persist…

黄金交易策略(Nerve Nnife.mql4):利用锁定单消除保留单

完整EA&#xff1a; Nerve Knife.ex4黄金交易策略_黄金趋势ea-CSDN博客 趋势突然转变有大约30%的概率会产生一张锁定单&#xff0c;反复转变之后难免就会形成几个保留单了&#xff0c;可以选择一张与保留单同向同大小&#xff08;接近也行&#xff09;的单&#xff0c;去消除这…

半理想架构的Doherty功率放大器理论与仿真-基于GAN器件CGH40010F

半理想架构的Doherty功率放大器理论与仿真-基于GAN器件CGH40010F 理想架构的Doherty功率放大器理论与仿真中已经介绍了如何在ADS中使用理想电流源来对DPA的架构进行仿真。但是理想的电流源太理想了&#xff0c;电压、电流的许多行为都是需要自己使用数学公式去严格定义&#x…

【Python】Python代码的单元测试

Python代码的单元测试 单元测试的概念 定义&#xff1a;是指对软件中的最小可测试单元进行检查和验证。 作用&#xff1a;可以确保程序模块是否否和我们规范的输出&#xff0c;保证该模块经过修改后仍然是满足我们的需求。 单元测试的策略 如果要创建单元测试&#xff0c;…

比特币再次上演“初五破五”精彩戏法!

号外&#xff1a;2.13教链内参《随着BTC一度突破5万刀&#xff0c;超过9成持有者已盈利》 比特币无惧美通胀数据阻击&#xff0c;在短暂回落之后坚决反攻&#xff0c;在中国农历大年初五&#xff0c;2月14日情人节&#xff0c;大涨6%&#xff0c;从48k绝地反击&#xff0c;再次…

游戏服务器租用多少钱一年?

游戏服务器租用多少钱一年&#xff1f;1个月游戏服务器费用多少&#xff1f;阿里云游戏服务器26元1个月、腾讯云游戏服务器32元&#xff0c;华为云26元&#xff0c;游戏服务器配置从4核16G、4核32G、8核32G、16核64G等配置可选&#xff0c;游戏专业服务器公网带宽10M、12M、15M…

吃瓜 - 春山学

2024年春晚看似一个贵州献上的歌舞节目《上春山》&#xff08;白敬亭、魏大勋、魏晨合唱&#xff09;引发网络破案&#xff1a;白敬亭有没有抢C位和故意换衣服&#xff1f;网上的“白敬亭春晚走位风波”不断升级&#xff0c;喂到嘴里的瓜不吃也不行啊。 三人都是明侦的元老嘉…

JavaScript中的Symbol:加密与安全性

JavaScript中的Symbol是一种唯一且不可变的数据类型&#xff0c;引入了一种新的基本数据类型&#xff0c;用于表示独一无二的标识符。在本文中&#xff0c;我们将深入介绍JavaScript中的Symbol&#xff0c;讨论如何将其应用于JS加密中&#xff0c;提供案例代码&#xff0c;并说…

C#通过重写虚方法实现加、减、乘、除运算 通过多态确定人类的说话行为

目录 一、涉及到的知识点1 1.虚方法 2.重写方法 3.重写方法与重载方法的区别 4.通过KeyPressEventArgs.KeyChar限制键盘输入的内容 5.if-else if-else嵌套转换为switch case 二、 涉及到的知识点2 1.多态性 2.使用多态性的注意事项 3. 使用虚方法实现多态性 三、实…

黑马Java——集合进阶(不可变集合、Stream流、方法引用)

目录 一、不可变集合 1、创建不可变集合的应用场景 2、创建不可变集合的书写格式 2.1、不可变的List集合 2.2、不可变的Set集合 2.3、不可变的Map集合 3、小结 二、Stream流 1、体验Stream流的作用 2、Stream流的思想 3、Stream流的使用步骤 3.1、单列集合获取Strea…

站在C/C++的肩膀速通Java面向对象

默认学过C或C&#xff0c;对变量、表达式、选择、循环都会。 运行特征 解释型语言&#xff08;JavaScript、Python等&#xff09; 源文件-(平台专属解释器)->解释器中执行编译型语言&#xff08;C、Go等&#xff09; 源文件-(平台编译器)->平台可执行文件Java 源文件-(…