npm package: @retailwe/common-libs-landtransfer
Description: RetailWe libs
Latest version: 0.0.3

# LandTransfer 落地中转

## Feature

- 落地中转：唯一入口，统一路由分发
- 路由映射：长短路径的映射转换
- Scene 短链方案： 满足生成无限小程序码场景

## 背景

在小程序的生态中，有诸多进入小程序的入口，如：小程序码、小程序跳转、公众号文章、公众号菜单等等。
根据小程序的设计，暴露给外部的连接是真实的页面路径（如：pages/home/index），该设计在实践中存在以下问题：

1. 各个落地页分散，后期修改真实文件路径难度大。
2. 加载落地页之后，只要点击回退，就退出小程序，没有更好的留住用户。

LandTransfer 用来解决落地中转的问题，暴露给外部的只需要是唯一的中转页，该页面可以是首页，可以是空白中转页，也可以是其他任何页面，随业务需求。

## 安装

```shell
yarn add '@retailwe/common-libs-landtransfer' --save-exact
```

## 快速使用（普通模式）

![普通模式](https://bluesun-1252625244.cos.ap-guangzhou.myqcloud.com/img/20200817162442.png)

假如维护了一个落地页面： `$LAND_PAGE = /pages/land-page/index`;

```javascript
// in /pages/land-page/index.js

import { LandTransfer } from '@retailwe/common-libs-landtransfer';
const landTransfer = new LandTransfer(LandTransferParams);

Page({
  onLoad(options) {
      landTransfer
        .run(options)
        .then(() => {...})
        .catch(() => {...});
  }
});
```

其中 

- `LandTransfer(LandTransferParams)`

```javascript
export interface LandTransferParams {
  // 目标连接参数：$LAND_PAGE?path=xxx
  pathName?: string;

  // 短连接参数，$LAND_PAGE?sPath=xxx
  shortPathName?: string;

  // 如果指定了该方法，则识别 $LAND_PAGE?scene=sp=xxx 的方式
  onDecodeSceneShortParams?: (sceneSp: string) => Promise<object>;

  // 转换 shortPath → path
  onConvertShortPath?: (shortPath: string) => Promise<string>;
}
```

## 短链映射模式

![短链映射](https://bluesun-1252625244.cos.ap-guangzhou.myqcloud.com/img/20200817162443.png)

该模式需要开发者自行定义短链与长链的映射关系。

```javascript
// in /pages/land-page/index.js

import { LandTransfer } from '@retailwe/common-libs-landtransfer';

const routerMap = {
  '/home': '/pages/home/index',
}

const landTransfer = new LandTransfer({
  onConvertShortPath: () => {
    return Promise.resolve(routerMap[sPath]);
  }
});

Page({
  onLoad(options) {
    landTransfer
      .run(options)
      .then(() => {...})
      .catch(() => {...});
  }
});
```

## 短链 Scene 模式

![短链 Scene 模式](https://bluesun-1252625244.cos.ap-guangzhou.myqcloud.com/img/20200817162444.png)

该模式主要适配[小程序无限量太阳码](https://developers.weixin.qq.com/miniprogram/dev/api-backend/open-api/qr-code/wxacode.getUnlimited.html)的技术。

LandTransfer 定义 scene 参数格式为：`sp=abc`，其中 `abc` 的转换，需要开发者通过 `onDecodeSceneShortParams` 方法自行定义，一般是由后端提供 API 服务。

以下提供前端示例代码，以及完整的前后端时序图，供参考。

```javascript
// in /pages/land-page/index.js

import { LandTransfer } from '@retailwe/common-libs-landtransfer';

const routerMap = {
  '/home': '/pages/home/index',
}

const landTransfer = new LandTransfer({
  onConvertShortPath: () => {
    return Promise.resolve(routerMap[sPath]);
  },
  // 此处接收 scene: sp=abc，中的 sp value
  onDecodeSceneShortParams: (sceneSp) => {
    return API
        .decodeSceneSP({ sceneSp })
        .then((content) => {
            // 假如后端存的是 JSON 字符串，前端decode
            // 要求输出：{ sPath: '/home', a: 1, b:2 }
            // 或：{ sPath: '/pages/home/index', a: 1, b:2 }
            return JSON.parse(content);
        })
  }
});

Page({
  onLoad(options) {
    landTransfer
      .run(options)
      .then(() => {...})
      .catch(() => {...});
    }
});
```

![Scene短链模式](https://bluesun-1252625244.cos.ap-guangzhou.myqcloud.com/img/20200819112451.png)

## 在 RetailWe Seed 项目中使用 Decorator

如果使用 Retailwe Seed 框架，LandTransfer 提供了更便捷的 Decorator 使用方式，封装了示例创建，onLoad 监听等操作。

```javascript
import { decorator as landTransfer } from '@retailwe/common-libs-landtransfer';
import { wxPage } from '@/core/decorator/index';

// such as /pages/home/index.ts
@wxPage()
export default class Home extends DecorationPage {
  @landTransfer(LandTransferParams);
  onLoad() {...}
}
```

## 单元测试覆盖率

[单元测试覆盖率](cov/index.html)