import { Meta } from '@storybook/addon-docs/blocks';

<Meta title="研发文档/介绍" />

# 介绍

本文简要介绍实操业务背景以及对其对应技术方案的思考。

## 什么是实操

简单来说，实操指的是仓库的作业流程，一个作业流程会存在多个场景，在作业流程中这些场景会根据业务需要进行切换，例如在超市购物时，收银员用扫码枪不停的「滴」直到完成收银，这就是一次实操作业过程。


## 实操页与普通管理页的区别

从业务角度来说，实操页面最特别的地方在于，它在业务上天然有着流程的概念，对于常规中后台页面，我们只用关心在「单」场景中，组件级别的交互、状态管理、渲染，但对于实操页面，抽象层次要再上升一层，我们的视角会聚焦到「多」场景。

回到问题本身，我们当然可以把实操页面当成普通的中后台页面来进行研发，但随着业务复杂度地不断提升，在多场景的业务背景下，缺少规范和最佳实践的代码将会快速冗余，并且越来越难以理解和维护，未来很难适应业务快速地发展与变化。

## 实操技术方案需要具备哪些特性

结合业务场景考虑，以及根据现有开发经验，我们认为实操技术方案需要满足以下几点：

1. 一定要能提供在场景流程上的解决方案， 支持根据业务快速对场景进行编排（增、删、改、复用），并且保证场景流转时页面的渲染性能，这是实操研发的根本。

2. 一定要在基于团队研发的基础上（研发规约、样板间、视觉规范）上去做自定义拓展，控制抽象封装的层度，保证未来任何一个同学在切换业务时都没有太强的研发割裂感。

3. 一定要符合开闭原则，对拓展开放，对修改封闭。在平衡好自由度的基础上进行约束，保证所有人都能写出符合规范和最佳实践的代码。


## 实操页面流

综上，我们选用了实操页面流作为实操研发方案，该方案实现了页面渲染与业务逻辑完全分离，有更清晰的业务流转代码。

该方案可以分为UI层和逻辑层两大部分。

### UI层

UI有3种调用方式，toast 提示类 overlay 弹窗类 router页面跳转类。我们约定如下：

* **toast** 页面不阻断用户操作，故在 toast 类页面的实现中，应在页面渲染完成后立即调用 onNext 把执行权限交还给流程控制。在框架层面默认5秒后会卸载toast页面，可通过 data.duration 字段来控制
* **overlay** 会覆盖到 router 上的弹层页面，主要是为了模拟模态弹窗，上一个界面通常作为背景使用。通常在实现 overlay 页面的时候都需要模拟 Dialog的模态效果，以达到UI要求
* **router** 普通的页面跳转, 会卸载上一个界面。


```javascript
import { UserInterface } from '@cniot/pageflow';
// appId 在当前浏览器页不重复的 id
const appId = "reviewPackage";
const UI = UserInterface.create(appId);
// 调用一个页面
await UI.toast("/pages/toast", {})
// 调用一个页面
await UI.overlay("/pages/toast", {})
// 调用一个页面
await UI.router("/pages/toast", {})
```

### 逻辑层

逻辑层运用了flow的概念来进行流程控制，主要包含以下几个关键词：

* 把实操流程拆解为帧(frame)
* 每一帧与其他帧没有关联
* 帧是串联在一起的，执行的时候默认总是一帧一帧的执行
* 可以通过流程控制语句改变帧的执行顺序
* 帧执行顺序被压入历史记录，可以 back 回上一帧

![flow原理](https://cdn.nlark.com/yuque/0/2022/png/217591/1644807365799-9bce2101-a625-489e-8b21-8ac5d734b085.png?x-oss-process=image%2Fresize%2Cw_1444%2Climit_0)