express 定时删除 oss 垃圾图片

news2024/11/27 12:54:11

一: 删除垃圾图片

思路:
  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 } = config

import 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 = [] } = result
      for (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 = cronExpression
    this.task = task
    this.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 设为 null
    if (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.coloradmin.cn/o/1448691.html

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

相关文章

Stable Diffusion之最全详解图解

Stable Diffusion之最全详解图解 1. Stable Diffusion介绍1.1 研究背景1.2 学术名词 2.Stable Diffusion原理解析2.1 技术架构2.2 原理介绍扩散过程 3.1 Diffusion前向过程3.2 Diffusion逆向&#xff08;推断&#xff09;过程 1. Stable Diffusion介绍 Stable Diffusion是2022…

蓝桥杯第七届电子类单片机组程序设计

目录 前言 蓝桥杯大赛历届真题 一、第七届比赛题&#xff1a; 二、功能实现&#xff1a; 1.基础/模板部分 2.菜单模式的切换 3.数码管闪烁功能 4.led灯闪烁部分 5.对按键的处理 5.对ds1302的处理 三、代码实现 main.c onewire.c onewire.h ds1302.c ds1302.h 前言 …

使用 Chainlit, Langchain 及 Elasticsearch 轻松实现对 PDF 文件的查询

在我之前的文章 “Elasticsearch&#xff1a;与多个 PDF 聊天 | LangChain Python 应用教程&#xff08;免费 LLMs 和嵌入&#xff09;” 里&#xff0c;我详述如何使用 Streamlit&#xff0c;Langchain, Elasticsearch 及 OpenAI 来针对 PDF 进行聊天。在今天的文章中&#xf…

PWR电源控制

PWR电源 PWR简介 PWR&#xff08;Power Control&#xff09;电源控制 PWR负责管理STM32内部的电源供电部分&#xff0c;可以实现可编程电压监测器和低功耗模式的功能 可编程电压监测器&#xff08;PVD&#xff09;可以监控VDD电源电压&#xff0c;当VDD下降到PVD阀值以下或上…

【安装指南】图床神器之Picgo下载、安装详细教程

&#x1f33c;一、概述 PicGo是一款开源的图片上传、管理工具&#xff0c;旨在帮助用户快速上传图片到云存储或图床&#xff0c;并提供链接方便在网页或其他应用中使用。它支持各种常见的图床服务商&#xff0c;如GitHub、七牛云、腾讯云等&#xff0c;并提供了简洁易用的界面和…

收藏:关于块存储,文件存储和对象存储

在B站上看到”【IT老齐465】“这个系列相当不错&#xff0c;每次的视频15分钟左右&#xff0c;出了400多个了&#xff0c;今天偶然看到&#xff0c;地址是&#xff1a;【IT老齐465】块存储、文件存储、对象存储的关系与区别_哔哩哔哩_bilibili 精彩摘录如下&#xff1a;

金庆培:世界需要有一个国际易货贸易协定

2024年2月4日&#xff0c;我拜访了中国金融与证券行业的著名专家徐士敏教授。 首先开言&#xff0c;他就告诉我&#xff1a;“你金老师&#xff0c;是研究中国自由贸易区创新发展和世界自由贸易区创新发展的专家&#xff0c;我认为&#xff0c;在当前世界经济形势下&#xff0c…

C语言每日一题(57)二叉树的最小深度

题目链接 力扣网111 二叉树的最小深度 题目描述 给定一个二叉树&#xff0c;找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明&#xff1a;叶子节点是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,…

四、案例 - Oracle数据迁移至MySQL

Oracle数据迁移至MySQL 一、生成测试数据表和数据1.在Oracle创建数据表和数据2.在MySQL创建数据表 二、生成模板文件1.模板文件内容2.模板文件参数详解2.1 全局设置2.2 数据读取&#xff08;Reader&#xff09;2.3 数据写入&#xff08;Writer&#xff09;2.4 性能设置 三、案例…

C++:priority_queue模拟实现

C&#xff1a;priority_queue模拟实现 什么是priority_queue模拟实现向上调整算法向下调整算法插入与删除 仿函数 什么是priority_queue priority_queue称为优先级队列。优先级队列是一种特殊的队列&#xff0c;其中每个元素都有一个相关的优先级。元素的优先级决定了它们在队…

Vue2中v-for 与 v-if 的优先级

在Vue2中&#xff0c;v-for 和 v-if 是常用的指令&#xff0c;它们在前端开发中非常有用。但是&#xff0c;当我们在同一个元素上同时使用这两个指令时&#xff0c;就需要注意它们的优先级关系了。 首先&#xff0c;让我们了解一下v-for和v-if的基本用法。 v-for 是Vue的内置…

基于JAVA的课程案例资源库系统 开源项目

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 管理员需求分析2.2 用户需求分析 三、系统设计3.1 业务流程设计3.1.1 管理员业务流程设计3.1.2 用户业务流程设计3.1.3 首页功能模块及业务流程分析3.1.4 案例资源中心功能模块及业务流程分析3.1.5 用户信息中心功能模块…

爱快使用VPN

文章目录 一、VPN服务器1. 各种VPN比较2. PPTP服务端配置3. 创建登录账号4. 创建端口映射5. 设置动态域名 二、Windows客户端1. 连接配置2. 不能连接 Internet 配置 一、VPN服务器 1. 各种VPN比较 PPTPIPSECOpenVPN简介微软推出的VPN协议&#xff0c;占用资源少更高级的VPN协…

再利用系统盘时,如何删除恢复分区(Recovery Partition)

系统盘有一个Recovery Partition&#xff0c;记录了重要的系统信息&#xff0c;不能删除。 Windows 10的 Disk Managment 不提供用户删除这个Partition的选项。 近日我插入一块原系统盘&#xff0c;Format后作为DataDisk&#xff0c;此时需要删除这块硬盘上的RecoveryPartition…

matplotlib画简单的论文图像

由于最近论文里需要插入绘图&#xff0c;因此写一篇博客记录一下 折曲线图 基本绘图 在matplotlib中折线和曲线图是最常用和最简单的图。只需要直接使用方法plot即可。 import matplotlib.pyplot as plt plt.plot(x,y) plt.show()其中上述的代码中x&#xff0c;y分别是横坐…

langchain==win11搭建使用GPU

annaconda安装Python 3.11.7 下载代码&#xff1a; GitHub - chatchat-space/Langchain-Chatchat: Langchain-Chatchat&#xff08;原Langchain-ChatGLM&#xff09;基于 Langchain 与 ChatGLM 等语言模型的本地知识库问答 | Langchain-Chatchat (formerly langchain-ChatGLM)…

【Tomcat】:One or more listeners failed to start.报错解决方案

报错信息:One or more listeners failed to start. Full details will be found in the appropriate container log file. 具体就是web.xml此配置报错: 服务器启动错误Tomcat:One or more listeners failed to start.报错解决方案 IDEA:在使用IDEA运行SSM项目的时候 , Tomcat运…

基于SSM的教材管理系统

文章目录 教材管理系统一、项目演示二、项目介绍三、系统部分功能截图四、部分代码展示五、底部获取项目源码&#xff08;9.9&#xffe5;&#xff09; 教材管理系统 一、项目演示 基于SSM的教材管理系统 二、项目介绍 有三个角色 1、管理员 功能模块&#xff1a;用户管理、教…

【数据结构】链表OJ面试题3《判断是否有环》(题库+解析)

1.前言 前五题在这http://t.csdnimg.cn/UeggB 后三题在这http://t.csdnimg.cn/gbohQ 记录每天的刷题&#xff0c;继续坚持&#xff01; 2.OJ题目训练 9. 给定一个链表&#xff0c;判断链表中是否有环。 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成…

幻兽帕鲁Palworld服务器设置参数(汉化)

创建幻兽帕鲁服务器配置参数说明&#xff0c;Palworld服务器配置参数与解释&#xff0c;阿腾云atengyun.com分享&#xff1a; 自建幻兽帕鲁服务器教程&#xff1a; 阿里云教程 https://t.aliyun.com/U/bLynLC腾讯云教程 https://curl.qcloud.com/oRMoSucP 幻兽帕鲁服务器 幻…