接口对接键名五花八门?我做了个工具重写键名

前言

作为前端,肯定遇到过对接接口的时候键名不规范的问题,接口返回的数据命名不规范,接口接收的参数命名又不规范

js 复制代码
{
    cDefine1: 'value1',
    cDefine2: 'value2'
    xxjob: 'value3'
}

那么当我们要写逻辑的时候,就要重新去命名,如果不重新命名,以后后端改键名了,如果涉及复杂的计算逻辑,你就头大了

还有同一个字段,在不同的接口,有时候返回数字,有时候返回字符串,这个很恶心人,我就遇到过,一个ID,本来它的管理列表ID这一列是数字的,然后在其他接口联查返回来又变字符串了,如果你用的是===去匹配,就会埋下深坑!

所以我把常用的自己封装的方法提取封装成了一个工具库

今天的主角就是其中的一个工具:双向映射

BiMap

BiMap是一个双向映射工具,它接收一个多维数组,然后根据传入的数组规则,生成一个映射实例

比如我这里有一个数组,涉及到深层对象、递归

js 复制代码
const data = [
  {
    a: 1,
    b: 1,
    c: {
      d: 1,
      e: 1,
      f: [
        {
          g: 1,
          h: 1,
        },
      ],
    },
    children: [
      {
        a: 0,
        b: 0,
        c: {
          d: 0,
          e: 0,
          f: [
            {
              g: 0,
              h: 0,
            },
          ],
        },
        k: 0,
      },
      {
        a: 1,
        b: 1,
        c: {
          d: 1,
          e: 1,
          f: [
            {
              g: 1,
              h: 1,
            },
          ],
        },
        k: 1,
      },
    ],
    k: 1,
  },
];

然后我使用BiMap写一个映射

js 复制代码
const map = new BiMap([
  ["a", "A"], // 把'a'转成'A',也可以反过来把'A'转成'a'
  [
    "b",
    "B",
    {
      transformType: String, // 把键名对应的value进行处理,比如转成字符串,转成数字,转成Boolean
    },
  ],
  [
    "c",
    "C", // 数组嵌套数组表示c是复杂对象,里面的数据还要继续转换,c.d会变成C.D
    [
      [
        "d",
        "D",
        {
          transformSourceType: "object", // 转换数据的类型 object、map、array
          transformType: Number,
          transformInverted: true, // 是否可以反过来转换 如为true就会把原本值为'否'变成0
          transform: {
            0: "否",
            1: "是",
          },
        },
      ],
      [
        "e",
        "E",
        {
          transformType: Boolean,
        },
      ],
      [
        "f",
        "F",
        [
          [
            "g",
            "G",
            {
              transformSourceType: "map",
              transformType: Number,
              transformInverted: true,
              transform: new Map([
                [0, "zero"],
                [1, "one"],
              ]),
            },
          ],
          [
            "h",
            "H",
            {
              transformSourceType: "array",
              transformType: Number,
              transformInverted: true,
              transformLabelKey: "label",
              transformValueKey: "value",
              transform: [
                {
                  label: "否",
                  value: 0,
                },
                {
                  label: "是",
                  value: 1,
                },
              ],
            },
          ],
        ],
      ],
    ],
  ],
  [
    "children",
    "CHILDREN",
    {
      recursion: true,
    },
  ],
  [
    "k",
    "K",
    new BiMap([
      [0, "零"],
      [1, "一"],
    ]), // 深层对象映射可以使用数组嵌套也可以直接使用BiMap BiMap可以处理键名转换也可以处理值的转换
  ],
]);

BiMapConversion

BiMapConversion是一个用来把数据转换成映射后的数据的工具 它接收两个参数,一个是待转换数据,一个是BiMap规则

js 复制代码
const mapData = BiMapConversion(data, map);

转换结果

如下图所示,左侧是原始数据,右侧是双向映射后的数据

在接口处统一做出入数据管理

js 复制代码
import { BiMapConversion } from 'kk-utils-library/bidirectional-mapping';
import {
  $factoryCreateReqItemMap,
  $factoryCreateResItemMap,
  $factoryDeleteReqItemMap,
  $factoryDeleteResItemMap,
  $factoryDetailReqItemMap,
  $factoryDetailResItemMap,
  $factoryListReqItemMap,
  $factoryListResItemMap,
  $factoryPageReqItemMap,
  $factoryPageResItemMap,
  $factoryUpdateReqItemMap,
  $factoryUpdateResItemMap
} from '@/constants/bi-map/factory';

// 获取工厂列表
export function getFactoryList(Service) {
  return (params) =>
    new Promise((resolve, reject) => {
      params = BiMapConversion(params || {}, $factoryListReqItemMap); // 出参转换
      Service.get('/bms/factory/list', params)
        .then((res) => {
          res.data = BiMapConversion(res.data || [], $factoryListResItemMap); // 数据转换
          resolve(res);
        })
        .catch((error) => reject(error));
    });
}

// 获取工厂分页
export function getFactoryPage(Service) {
  return (params) =>
    new Promise((resolve, reject) => {
      params = BiMapConversion(params || {}, $factoryPageReqItemMap);
      Service.get('/bms/factory/page', params)
        .then((res) => {
          if (!res.data) res.data = {};
          res.data.list = BiMapConversion(
            res.data.list || [],
            $factoryPageResItemMap
          );
          resolve(res);
        })
        .catch((error) => reject(error));
    });
}

// 获取工厂详情
export function getFactoryDetail(Service) {
  return (params) =>
    new Promise((resolve, reject) => {
      params = BiMapConversion(params || {}, $factoryDetailReqItemMap);
      Service.get(`/bms/factory/getById/${params.id}`, params)
        .then((res) => {
          res.data = BiMapConversion(res.data || {}, $factoryDetailResItemMap);
          resolve(res);
        })
        .catch((error) => reject(error));
    });
}

// 新建工厂
export function createFactory(Service) {
  return (params) =>
    new Promise((resolve, reject) => {
      params = BiMapConversion(params || {}, $factoryCreateReqItemMap);
      Service.post('/bms/factory/save', params)
        .then((res) => {
          res.data = BiMapConversion(res.data || {}, $factoryCreateResItemMap);
          resolve(res);
        })
        .catch((error) => reject(error));
    });
}

// 更新工厂
export function updateFactory(Service) {
  return (params) =>
    new Promise((resolve, reject) => {
      params = BiMapConversion(params || {}, $factoryUpdateReqItemMap);
      Service.post('/bms/factory/updateById', params)
        .then((res) => {
          res.data = BiMapConversion(res.data || {}, $factoryUpdateResItemMap);
          resolve(res);
        })
        .catch((error) => reject(error));
    });
}

// 删除工厂
export function deleteFactory(Service) {
  return (params) =>
    new Promise((resolve, reject) => {
      params = BiMapConversion(params || {}, $factoryDeleteReqItemMap);
      Service.delete(`/bms/factory/deleteById/${params.id}`, params)
        .then((res) => {
          res.data = BiMapConversion(res.data || {}, $factoryDeleteResItemMap);
          resolve(res);
        })
        .catch((error) => reject(error));
    });
}

这样,只要在constants文件夹下定义好各个接口的出参映射和数据接收映射,就可以在获取接口数据的时候拿到转换后的数据了,就不用重新去命名了,以后如果后端数据不变,键名改变,就能直接在bi-map管理的地方修改,而不用去逻辑里面修改了

其他

当然 BiMap定义的数据也能复用,比如

js 复制代码
// 分页参数
export const $paginationReqItemMap = new BiMap([
  ['pageNum', 'pageNumber'],
  ['pageSize', 'pageSize']
]);

// 列表
export const $listReqItemMap = new BiMap([
  ['code', 'code'], // 其他编码 一样的话就相当于不转换
  ['userName', 'userName'], // 申请人
]);
export const $expenseApplicationListResItemMap = new BiMap([
  ['id', 'id'], // ID
  ['code', 'otherCode'], // 其他编码
 ])
// 分页
export const $pageReqItemMap = new BiMap([
  ...$expenseApplicationListReqItemMap.sourceData, // BiMap实例上有个sourceData可以拿来复用
  ...$paginationReqItemMap.sourceData // 分页参数复用
]);
export const $pageResItemMap =
  $expenseApplicationListResItemMap; // 也可以直接用同一个实例

这样用了这个工具,每次接口发送和接收的时候,都能把我们自己的键名命名换成后端所需要的,也可以把后端的键名换成前端所需要的,这样不管后台怎么定义接口的参数key或者返回数据的对象key,都不影响我们了,我们只需要在接口出入参的地方进行映射就能解决了

结语

npm库地址:kk-utils-library

我的GitHub:GitHub

相关推荐
集成显卡3 分钟前
PlayWright | 初识微软出品的 WEB 应用自动化测试框架
前端·chrome·测试工具·microsoft·自动化·edge浏览器
前端小趴菜051 小时前
React - 组件通信
前端·react.js·前端框架
Amy_cx1 小时前
在表单输入框按回车页面刷新的问题
前端·elementui
dancing9991 小时前
cocos3.X的oops框架oops-plugin-excel-to-json改进兼容多表单导出功能
前端·javascript·typescript·游戏程序
后海 0_o2 小时前
2025前端微服务 - 无界 的实战应用
前端·微服务·架构
Scabbards_2 小时前
CPT304-2425-S2-Software Engineering II
前端
小满zs2 小时前
Zustand 第二章(状态处理)
前端·react.js
程序猿小D2 小时前
第16节 Node.js 文件系统
linux·服务器·前端·node.js·编辑器·vim
萌萌哒草头将军2 小时前
🚀🚀🚀Prisma 发布无 Rust 引擎预览版,安装和使用更轻量;支持任何 ORM 连接引擎;支持自动备份...
前端·javascript·vue.js
狼性书生2 小时前
uniapp实现的简约美观的星级评分组件
前端·uni-app·vue·组件