TODO:文档待完善

# @kt/request

根据科拓的业务抽离的 request 请求框架，基于 axios 封装。

# Usage

## 基本

request 目前的格式固定如下

```ts
const { code, data } = await request.post(
  'foo/bar',
  { foo: 'bar' },
  { loading: false }
);
```

or 后端接口返回的 code 是 resCode，data 是 resData

```ts
const { resCode, resData } = await request.post(
  'foo/bar',
  { foo: 'bar' },
  { loading: false }
);
```

注意：这里的 ”code“ 和 ”data“ 会保留后端的接口风格。后端接口是什么，这里就是什么。

```
参数 1*：路径

参数 2：入参，非必填

参数 3：axios 的配置，[点击查阅](https://axios-http.com/zh/docs/req_config) + 自定义的配置

tips：*为必填
```

自定义的配置如下：

```ts
// 自定义的配置
interface CommonConfig {
  /**
   * 接口验证授权逻辑，一般来用来处理自动跳转至登录页
   *
   * Default: true
   */
  customAuth?: boolean;
  /**
   * 全局提示，接口请求成功，但 code 码错误
   *
   * Default: true
   */
  codeErrTip?: boolean;
  /**
   * 全局提示，接口请求错误
   *
   * Default: true
   */
  rejectErrTip?: boolean;
  /**
   * 全局显示 loading
   *
   * Default: false,Mobile-Default: true
   */
  loading?: boolean;
  /**
   * 标记是否在请求的时候加入取消接口队列
   *
   * Default: false
   */
  cancel?: boolean;
}
```

## customCode

枚举 request 的自定义错误码，灵活扩展，语义清晰。

目前 request 的有两个自定义错误（默认）：

```js
customCode: {
  // 将所有错误收敛到内部，暴露出来的 code
  custom: 4400,
  // axios 请求取消 code
  canceled: 4401
}
```

为了防止和后端的 code 冲突，提供了外部自定义 code 的手段（[详细请看](./src/types.ts#L128)）。

使用场景：

**`customCode.custom`**

```js
import request, { customCode } from '@kt/request';
const foo = async () => {
  const { code, data } = await request.get('foo/bar');
  if (code === 2000) {
    // do something...
  } else if (code === customCode.custom) {
    // 处理错误
  }
};
```

**`customCode.canceled`**

```js
import request, { customCode } from '@kt/request';

let controller: AbortController;
const handleFoo = async () => {
  controller?.abort();
  controller = new AbortController();
  const foo = async () => {
    const { code, data } = await request.get(
      'foo/bar',
      {},
      {
        signal: controller.signal
      }
    );
    if (code === customCode.canceled) {
      // 接口被取消
    } else if (code === 2000) {
    }
  };
};
```

## i18n 支持

一些错误提示的 i18n 支持。

request 库内部兼容了 i18n，当外部显式传入 $t 方法，控制权将交给外部的 vue-i18n 来控制国际化。

配置（注意两个地方）：

requestRegister.ts

```ts
import i18n from '@/locale';

const config: RequestConfig = {
  /* ... */
  $t: i18n.global.t
  /* ... */
};
```

locale/index.ts 文件合并

```ts
const zh_CN = require('./lang/zh_CN');
const zh_TW = require('./lang/zh_TW');
const en_US = require('./lang/en_US');

// 导入 @kt/request 语言包
import KTRequest_zh_CN from '@kt/request/dist/locale/lang/zh_CN';
import KTRequest_zh_TW from '@kt/request/dist/locale/lang/zh_TW';
import KTRequest_en_US from '@kt/request/dist/locale/lang/en_US';

/* ... */
const messages = {
  zh_CN: { ...zh_CN, ...KTRequest_zh_CN },
  zh_TW: { ...zh_TW, ...KTRequest_zh_TW },
  en_US: { ...en_US, ...KTRequest_en_US }
};
/* ... */
```

# 注意

## 约定、规范

- 统一使用 async/await

```ts
const foo = async () => {
  const { code, data } = await request.get('foo/bar');
};
```

- 统一判断成功 code，再执行下一步

```ts
const foo = async () => {
  const { code, data } = await request.get('foo/bar');

  // code 按照后端的正确 code 来
  if (code === 2000) {
    // 在这里解构 data
    const { foo, bar } = data;

    // do something...
  }
};
```

- 如何处理 reject 状态？

一般来说，我们用 `try catch` 处理 `async await`，**没有捕获错误会导致程序出现问题，影响下一步代码的执行**。

```ts
try {
  const foo = async () => {
    const { code, data } = await request.get('foo/bar');
    // ...
  };
} catch (error) {}
```

但是在大部分业务中，**很少需要去做局部接口错误的处理**，统一在库进行全局处理。所以我们没有必要每个接口都使用 `try catch`。

@kt/request 库把错误收敛到内部，并暴露出一个 code 为 4400 的 `Promise.resolve` 回调。

如果有需要在局部判断的话，就这样子处理，如下：

```ts
const foo = async () => {
  const { code, data } = await request.get('foo/bar');
  if (code === 2000) {
    // do something...
  } else if (code === customCode.custom) {
    // 处理错误
  }
};
```
