strapi实现接口自由二

上文 我们已经学会了通过管理界面去配置生成我们所需要的接口,但是生成的接口可能不能完全匹配我们的需求,这种时候我们就需要去定制相关接口了。文档相关可见 后端定制

批量删除

原本我们配置生成的删除接口只能删除单个,批量删除是必不可少的功能,所以我们先来实现下内容的批量删除~

内容批量删除

先在项目的根目录下新建文件 utils/index.ts,定义好服务器将返回的响应的信息:

ini 复制代码
export function response(ctx, code, data = null, msg='') {
  ctx.body = {
    code,
    msg: msg,
    data,
  };
}

需要先来改造下文件 src/api/content/controllers/content.ts

javascript 复制代码
import { response } from '../../../utils';

export default factories.createCoreController('api::content.content',({strapi}) => ({
  async deleteMany(ctx){
    try {
      let res = await strapi.db.query("api::content.content").deleteMany({
        where: {
          id: {
            $in: ctx.request.body.idList // 请求参数-内容id数组
          },
        },
      });
      response(ctx, 200, res);
    } catch (error) {
      // 状态码code可自定义
      response(ctx, 1001, null, error.message);
    }
  }
}))

然后我们需要创建自定义路由,新增文件src/api/content/routes/01-custom-routes.ts

arduino 复制代码
export default {
  routes: [
    {
      method: 'POST',
      path: '/contents/deleteMany',
      handler: 'content.deleteMany',
    }
  ]
}

最后打开管理界面,配置批量删除接口的权限:

权限配置完之后,我们的内容批量删除接口就可以访问拉~

目录批量删除

目录批量删除的同时,我们需要删除掉目录下的内容,在开发过程中发现,批量删除接口没法根据关联的目录id去删除内容,所以就只能先找到目录关联的内容,再根据内容id去删除内容。

先来改造下文件 src/api/catalogue/controllers/catalogue.ts

javascript 复制代码
export default factories.createCoreController(
  "api::catalogue.catalogue",
  ({ strapi }) => ({
    async deleteMany(ctx) {
      try {
        const idList = ctx.request.body.idList;
        if (!idList.length) {
          return response(ctx, 1002, null, '参数不能为空');
        }
        // 根据参数判断是否需要删除目录下的内容
        const needDeleteAll = ctx.request.body.needDeleteAll;
        if (needDeleteAll) {
          // 没有办法通过目录id删除关联的所有内容,所有先获取目录下的所有内容
          let contentList = await strapi.entityService.findMany(
            "api::content.content",
            {
              filters: {
                catalogue: {
                  id: {
                    $in: idList,
                  },
                },
              },
            }
          );
          // 再拿到目录下所有内容的id
          const contentIdList = contentList?.map((item) => item.id);
          // 根据内容的id删除内容
          await strapi.db.query("api::content.content").deleteMany({
            where: {
              id: {
                $in: contentIdList,
              },
            },
          });
        }
        // 删除目录
        await strapi.db.query("api::catalogue.catalogue").deleteMany({
          where: {
            id: {
              $in: idList,
            },
          },
        });
        response(ctx, 200);
      } catch (error) {
        response(ctx, 1001, null, error.message);
      }
    }
}))

创建自定义路由,新增文件src/api/catalogue/routes/01-custom-routes.ts

arduino 复制代码
export default {
  routes: [
    {
      method: 'POST',
      path: '/catalogues/deleteMany',
      handler: 'catalogue.deleteMany',
    }
  ]
}

最后打开管理界面,配置批量删除接口的权限。权限配置完之后,我们的目录批量删除接口就可以访问拉~

小说批量删除

小说批量删除的同时,需要删除小说下的目录和内容,实现过程同目录批量删除,这个就留给大家自行去探索~

批量新增

原本我们配置生成的新增接口只能新增单个,所以我们现在来实现下批量新增。

在开发过程中发现createMany()API是没办法创建关联关系的,所以就只能循环去使用create()API。

内容批量新增

需要先来改造下文件 src/api/content/controllers/content.ts,新增以下函数:

javascript 复制代码
async createMany(ctx) {
  try {
    const list = ctx.request.body.contentList;
    if (!list.length) {
      return response(ctx, 1002, null, '参数不能为空');
    }
    // createMany Api无法创建关联关系,所以只能循环使用create
    // 如果传多个目录的内容,异步执行的话会造成数据库死锁问题,所以只能改成同步
    for (let index = 0; index < list.length; index++) {
      const item = list[index];
      if (!item.content) {
        throw { message: "参数缺少" };
      }
      await strapi.entityService.create("api::content.content", {
        data: item,
      });
    }
    response(ctx, 200);
  } catch (error) {
    response(ctx, 1001, null, error.message);
  }
}

自定义路由文件src/api/content/routes/01-custom-routes.ts,新增以下路由:

css 复制代码
{
  method: 'POST',
  path: '/contents/createMany',
  handler: 'content.createMany',
}

最后打开管理界面,配置批量新增内容接口的权限,权限配置完即可访问。

目录批量新增

需要先来改造下文件 src/api/catalogue/controllers/content.ts,新增以下函数:

javascript 复制代码
async createMany(ctx) {
    try {
      const list = ctx.request.body.catalogueList;
      if (!list.length) {
        return response(ctx, 1002, null, '参数不能为空');
      }
      // createMany Api无法创建关联关系,所以只能循环使用create
      // 这里操作的是同一小说的目录,所以同步执行不会存在死锁问题
      let res = await Promise.all(
        list.map((item) => {
          if (!item.catalogueIndex || !item.catalogueName) {
            throw { message: "参数缺少" };
          }
          return strapi.entityService.create("api::catalogue.catalogue", {
            data: item,
          });
        })
      );
      response(ctx, 200, res);
    } catch (error) {
      response(ctx, 1001, null, error.message);
    }
  },

自定义路由文件src/api/catalogue/routes/01-custom-routes.ts,新增以下路由:

css 复制代码
{
  method: 'POST',
  path: '/catalogues/createMany',
  handler: 'catalogue.createMany',
}

最后打开管理界面,配置批量新增目录接口的权限,权限配置完即可访问。

小说批量新增

小说的批量新增也留给大家自行探索吧~

参考文章

1、Strapi 中文网

相关推荐
腾讯TNTWeb前端团队44 分钟前
helux v5 发布了,像pinia一样优雅地管理你的react状态吧
前端·javascript·react.js
范文杰4 小时前
AI 时代如何更高效开发前端组件?21st.dev 给了一种答案
前端·ai编程
拉不动的猪4 小时前
刷刷题50(常见的js数据通信与渲染问题)
前端·javascript·面试
拉不动的猪4 小时前
JS多线程Webworks中的几种实战场景演示
前端·javascript·面试
FreeCultureBoy5 小时前
macOS 命令行 原生挂载 webdav 方法
前端
uhakadotcom6 小时前
Astro 框架:快速构建内容驱动型网站的利器
前端·javascript·面试
uhakadotcom6 小时前
了解Nest.js和Next.js:如何选择合适的框架
前端·javascript·面试
uhakadotcom6 小时前
React与Next.js:基础知识及应用场景
前端·面试·github
uhakadotcom6 小时前
Remix 框架:性能与易用性的完美结合
前端·javascript·面试
uhakadotcom6 小时前
Node.js 包管理器:npm vs pnpm
前端·javascript·面试