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 中文网

相关推荐
长天一色7 分钟前
【ECMAScript 从入门到进阶教程】第三部分:高级主题(高级函数与范式,元编程,正则表达式,性能优化)
服务器·开发语言·前端·javascript·性能优化·ecmascript
NiNg_1_23424 分钟前
npm、yarn、pnpm之间的区别
前端·npm·node.js
秋殇与星河27 分钟前
CSS总结
前端·css
BigYe程普1 小时前
我开发了一个出海全栈SaaS工具,还写了一套全栈开发教程
开发语言·前端·chrome·chatgpt·reactjs·个人开发
余生H1 小时前
前端的全栈混合之路Meteor篇:关于前后端分离及与各框架的对比
前端·javascript·node.js·全栈
程序员-珍1 小时前
使用openapi生成前端请求文件报错 ‘Token “Integer“ does not exist.‘
java·前端·spring boot·后端·restful·个人开发
axihaihai1 小时前
网站开发的发展(后端路由/前后端分离/前端路由)
前端
流烟默1 小时前
Vue中watch监听属性的一些应用总结
前端·javascript·vue.js·watch
2401_857297912 小时前
招联金融2025校招内推
java·前端·算法·金融·求职招聘
茶卡盐佑星_2 小时前
meta标签作用/SEO优化
前端·javascript·html