@shencom/api
Version:
shencom api group
309 lines (233 loc) • 10.5 kB
Markdown
name: shencom-api
description: 公司统一API客户端库。当需要调用后端服务接口时使用:(1)用户认证登录登出(ApiPhoneAndPasswordLogin等) (2)文件上传下载(ApiFileShow、ApiFileUpload等) (3)短信发送 (4)CMS内容管理 (5)GIS地理服务 (6)微信JSSDK配置 (7)高德/腾讯地图API (8)构建列表查询条件(ApiQueryConstruct、ApiSortsConstruct)。
# @shencom/api
公司统一 API 客户端库,提供预配置的后端服务接口函数,支持 UAA 认证、文件管理、CMS、GIS、微信、地图等服务。
> 依赖 `@shencom/request` 作为 HTTP 客户端,密码加密使用 `jsencrypt`。
## 安装
```bash
pnpm add @shencom/api
```
## 初始化
使用任何 API 函数前,必须先调用 `init` 进行初始化:
```ts
import { http } from '@shencom/request';
import { init } from '@shencom/api';
init(http, 'https://api.example.com');
```
## 导入方式
```ts
// 按需导入
import { ApiPhoneAndPasswordLogin, ApiFileShow, ApiQueryConstruct } from '@shencom/api';
// 导入枚举
import { OperateEnum, LrEnum, SortTypeEnum } from '@shencom/api';
```
## 用户认证 (UAA)
| 函数 | 说明 | 示例 |
|------|------|------|
| `ApiPhoneAndPasswordLogin(body)` | 手机号+密码登录 | `ApiPhoneAndPasswordLogin({ phone: '138...', password: 'xxx' })` |
| `ApiPhoneAndCodeLogin(body)` | 手机号+验证码登录 | `ApiPhoneAndCodeLogin({ phone: '138...', code: '1234' })` |
| `ApiPhoneAndCodeLoginOrRegister(body)` | 手机号验证码登录/自动注册 | 未注册手机号会自动注册 |
| `ApiPhoneOrUsernameAndPasswordLogin(body)` | 手机号/用户名+密码登录 | `{ username: 'admin', password: 'xxx' }` |
| `ApiPhoneOrUsernameAndPasswordAndCodeLogin(body)` | 租户端验证码登录 | 支持图形验证码或短信验证码 |
| `ApiPhoneOrUsernameAndPasswordAndCodeLoginPlatform(body)` | 平台端验证码登录 | 同上,平台端接口 |
| `ApiRefreshToken(refreshToken)` | 刷新 Token | `ApiRefreshToken('refresh_token_value')` |
| `ApiLogOut()` | 登出 | |
| `ApiGetPlaintextUserInfo()` | 获取当前用户信息 | 返回 `SC.User.Info` |
| `ApiSysUpdateInfo(body)` | 租户端-更新用户信息 | |
| `ApiSysUpdateInfoPlatform(body)` | 平台端-更新用户信息 | |
| `ApiUserSysUpdate(body)` | 租户端-修改密码 | `{ id, oldPassword, password }` |
| `ApiUserSysUpdatePlatform(body)` | 平台端-修改密码 | |
| `ApiResetPwd(body)` | 租户端-找回密码 | `{ param: '手机号/用户名', code, password }` |
| `ApiResetPwdPlatform(body)` | 平台端-找回密码 | |
| `ApiValidateImage(body)` | 获取图形验证码 | `{ username }` 或 `{ phone }` |
| `ApiNeedChangePwd()` | 是否需要修改密码 | 返回 `{ needChange, lastChangePwdTime }` |
| `ApiGetScCode()` | 获取 sccode | |
| `ApiScCodeLogin(code)` | sccode 登录 | |
| `ApiScOAuthSecuser(params)` | 获取跨租户授权签名 | |
| `ApiScOAuthLogin(params)` | 跨租户授权登录 | |
| `ApiIlhOauthLogin(body)` | 罗湖一级平台登录 | |
## 文件服务 (File)
| 函数 | 说明 | 示例 |
|------|------|------|
| `ApiFileShow({ ids })` | 文件详情 | `ApiFileShow({ ids: ['id1', 'id2'] })` |
| `ApiFileOssSign(body?)` | 获取 OSS 签名 | `{ open: 1, target: 0 }` |
| `ApiFileOssSignV2({ name })` | 获取 OSS 签名 V2 | `{ name: 'test.png' }` |
| `ApiFileOssBatchSignV2({ names })` | 批量获取 OSS 签名 | `{ names: ['a.png', 'b.jpg'] }` |
| `ApiFileOssUpload(body)` | OSS 签名上传 | 需要先调用 `ApiFileOssSign` 获取签名 |
| `ApiFileOssUploadV2(body)` | OSS 签名上传 V2 | 需要先调用 `ApiFileOssSignV2` 获取签名 |
| `ApiFileUpdate(body)` | 更新文件信息到数据库 | OSS 上传后调用 |
| `ApiFileUpload(body)` | 服务器直接上传 | `{ file, open: 1, target: 0 }` |
| `ApiFileStsToken(body?)` | 获取临时 STS Token | 用于客户端直传 |
| `ApiFilePresigned(body)` | 获取私有文件临时链接 | `{ ids, expiry: 3600 }` |
| `ApiFileExist({ etag })` | 判断重复文件 | 通过 etag 判断 |
| `ApiFileRepeat(body)` | 批量判断重复文件 | `{ origin, files: [{id, etag}] }` |
### 文件上传流程
```ts
// 方式1: OSS 签名上传(推荐)
const sign = await ApiFileOssSignV2({ name: file.name });
const ossResult = await ApiFileOssUploadV2({ ...sign, file, fileName: sign.objectName });
const fileInfo = await ApiFileUpdate({
fileName: ossResult.fileName,
name: ossResult.name,
remoteUrl: ossResult.remoteUrl,
fileSize: ossResult.fileSize,
etag: ossResult.etag,
});
// 方式2: 服务器直接上传
const result = await ApiFileUpload({ file, open: 1, isDownload: true });
```
## 短信服务 (SMS)
| 函数 | 说明 | 备注 |
|------|------|------|
| `ApiSmsTenants(body)` | 租户端发送短信 | `{ phone }` 或 `{ username }` |
| `ApiSmsPlatform(body)` | 平台端发送短信 | 同上 |
| `ApiSmsUnbound({ phone })` | 移动端发送短信 | 无系统用户限制 |
> 错误码: `615002` - 需要图形验证码, `500010` - 操作太频繁
## 内容管理 (CMS)
| 函数 | 说明 | 示例 |
|------|------|------|
| `ApiCMSCategoryTree(body)` | 获取栏目树 | |
| `ApiCMSCategoryIndex(body)` | 获取栏目列表 | |
| `ApiCMSArticlesIndex(body)` | 获取文章列表 | `{ categoryId, page, size }` |
| `ApiCMSArticlesShow({ id })` | 获取文章详情 | 返回包含 `content` |
## GIS 服务
| 函数 | 说明 | 示例 |
|------|------|------|
| `ApiGisShow({ ids })` | GIS 详情 | |
| `ApiGisCreate(body)` | 创建 GIS 点位 | `{ lat, lng, addr, mapType }` |
| `ApiFindRegionByLngLat({ lng, lat })` | 根据经纬度获取区域 | |
## 微信服务 (WeChat)
| 函数 | 说明 | 示例 |
|------|------|------|
| `ApiWechatGetConfig(scid)` | 获取公众号 JSSDK 配置 | 返回 `jWeixin.ConfigOptions` |
| `ApiWechatGetQrcode({ redirect })` | 获取微信登录二维码 | |
## 高德地图 (AMap)
| 函数 | 说明 | 示例 |
|------|------|------|
| `ApiAMapGeocodeGeo({ address, city? })` | 地理编码 | 地址转经纬度 |
| `ApiAMapGeocodeRegeo({ key, location })` | 逆地理编码 | 经纬度转地址 |
| `ApiAMapWeather({ city, extensions? })` | 天气查询 | `extensions: 'base'/'all'` |
| `ApiAMapIP({ ip? })` | IP 定位 | 不传 ip 则使用请求端 IP |
| `ApiAMapInputtips({ keywords, city? })` | 输入提示 | POI 搜索建议 |
## 腾讯地图 (QQMap)
| 函数 | 说明 | 示例 |
|------|------|------|
| `ApiQQMapGeocodeGeo({ key, address })` | 地理编码 | |
| `ApiQQMapGeocodeRegeo({ key, location })` | 逆地理编码 | `location: 'lat,lng'` |
| `ApiQQMapIP({ key, ip? })` | IP 定位 | |
## 查询工具 (Query)
用于构建列表接口的查询条件。
| 函数 | 说明 | 示例 |
|------|------|------|
| `ApiQueryConstruct(params)` | 创建查询条件数组 | 见下方示例 |
| `ApiQueryItemConstruct(val, prop, operate?, lr?)` | 创建单个查询条件 | `ApiQueryItemConstruct('张三', 'name')` |
| `ApiQueryInsert(target, source)` | 插入查询条件 | |
| `ApiQueryDelete(query, props)` | 删除指定字段查询条件 | `ApiQueryDelete(query, 'age')` |
| `ApiQueryDestructure(query)` | 查询条件转键值对 | `{ name: '张三', age: 100 }` |
```ts
import { ApiQueryConstruct, OperateEnum, LrEnum } from '@shencom/api';
// 单个条件
const query1 = ApiQueryConstruct('张三', 'name');
// [{ value: '张三', prop: 'name', operate: 'LIKE' }]
// 多个条件
const query2 = ApiQueryConstruct([
[100, 'age', OperateEnum.EQ],
['张三', 'name', OperateEnum.LIKE, LrEnum.AND],
['2024-01-01,2024-12-31', 'createTime', OperateEnum.BTW, LrEnum.AND],
]);
// 用于接口调用
const res = await someIndexApi({ query: query2, page: 1, size: 10 });
```
## 排序工具 (Sorts)
| 函数 | 说明 | 示例 |
|------|------|------|
| `ApiSortsConstruct(prop, type?)` | 创建排序条件 | `ApiSortsConstruct('createTime', 'DESC')` |
| `ApiSortsConstruct(params)` | 创建多个排序条件 | `ApiSortsConstruct([['createTime', 'DESC'], ['id']])` |
| `ApiSortsDelete(sorts, props)` | 删除排序条件 | |
| `ApiSortsDestructure(sorts)` | 排序条件转键值对 | `{ createTime: 'DESC' }` |
```ts
import { ApiSortsConstruct } from '@shencom/api';
const sorts = ApiSortsConstruct([
['createTime', 'DESC'],
['updateTime', 'ASC'],
]);
// [{ orderField: 'createTime', orderType: 'DESC' }, { orderField: 'updateTime', orderType: 'ASC' }]
```
## 枚举
### OperateEnum (查询操作符)
| 值 | 说明 | 示例 |
|------|------|------|
| `EQ` | 等于 | `age = 18` |
| `LT` | 小于 | `age < 18` |
| `GT` | 大于 | `age > 18` |
| `LTE` | 小于等于 | `age <= 18` |
| `GTE` | 大于等于 | `age >= 18` |
| `NEQ` | 不等于 | `age != 18` |
| `IN` | 包含 | `status IN (1, 2, 3)` |
| `NN` | 非空 | `name IS NOT NULL` |
| `NULL` | 为空 | `name IS NULL` |
| `BTW` | 区间 | `date BETWEEN '2024-01-01' AND '2024-12-31'` |
| `LIKE` | 模糊匹配 | `name LIKE '%张%'` |
| `LL` | 左模糊 | `name LIKE '%张'` |
| `RL` | 右模糊 | `name LIKE '张%'` |
### LrEnum (逻辑关系)
| 值 | 说明 |
|------|------|
| `AND` | 并且 |
| `OR` | 或者 |
### SortTypeEnum (排序类型)
| 值 | 说明 |
|------|------|
| `ASC` | 升序 |
| `DESC` | 降序 |
## 常用工作流
### 登录流程
```ts
import { ApiPhoneAndPasswordLogin } from '@shencom/api';
import { ScUserInfoBase } from '@shencom/utils-userinfo';
const userInfo = await ApiPhoneAndPasswordLogin({
phone: '13800138000',
password: '123456',
});
// 存储用户信息
userInfoStore.setRootInfo(userInfo);
```
### 列表查询
```ts
import { ApiQueryConstruct, ApiSortsConstruct, OperateEnum, LrEnum } from '@shencom/api';
// 构建查询条件
const query = ApiQueryConstruct([
[searchText, 'name', OperateEnum.LIKE],
[status, 'status', OperateEnum.EQ, LrEnum.AND],
]);
// 构建排序
const sorts = ApiSortsConstruct('createTime', 'DESC');
// 调用列表接口
const res = await someIndexApi({
query,
sorts,
page: 1,
size: 20,
});
```
## 使用建议
1. **必须初始化**:使用任何 API 前必须调用 `init(http, url)`
2. **密码自动加密**:登录/修改密码接口会自动使用 JSEncrypt 加密
3. **Token 自动处理**:部分公开接口会自动移除 Authorization 头
4. **类型安全**:所有接口都有完整的 TypeScript 类型定义
5. **统一错误处理**:错误处理由 `@shencom/request` 统一管理