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

前言

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

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

相关推荐
帮帮志7 分钟前
如何启动vue项目及vue语法组件化不同标签应对的作用说明
前端·javascript·vue.js
森哥的歌18 分钟前
深入解析Vue3中ref与reactive的区别及源码实现
前端·javascript·vue.js
恋猫de小郭22 分钟前
React Native 前瞻式重大更新 Skia & WebGPU & ThreeJS,未来可期
android·javascript·flutter·react native·react.js·ios
shmily麻瓜小菜鸡31 分钟前
vue3使用tailwindcss报错问题
开发语言·前端·javascript·vue.js
帆张芳显34 分钟前
前端EXCEL插件,智表ZCELL产品V3.0 版本发布,底层采用canvas全部重构,功能大幅扩展,性能极致提升,满足千万级单元格加载
前端·重构·excel·jquery·插件·智表
神仙别闹40 分钟前
基于HTML+JavaScript+CSS实现教学网站
javascript·css·html
python_chai1 小时前
CSS从入门到精通:全面解析CSS核心知识体系
前端·css
会飞的鱼先生2 小时前
vue3的深入组件-组件 v-model
前端·javascript·vue.js
2401_837088503 小时前
CSS opacity
前端·css
Lysun0013 小时前
(pnpm)引入 其他依赖失败,例如‘@element-plus/icons-vue‘失败
前端·javascript·npm·pnpm