# os-cfpd

## 基本

文档入口: https://choice-form.github.io/os-cfpd/content/

- 完整问卷说明入口 [[CFPDFullSurvey]]
- 部分问卷说明入口 [[CFPDPartialSurvey]]

Standard data format for choiceform portable survey design

这个包包含的内容：

1. cfpd 的整个数据结构规范。
2. cfpd 的解压和压缩工具。

答题端核心和设计端核心将会共同依赖这个包。

## 发布版本

1. changelog 中填好更改说明
2. yarn release [version] [commit]
   > release 的详情可以看[changelog.md](./CHANGELOG.md)开头的说明，或[tools/release.js](./tools/release.js)的实现

## 类型名称命名规范

1. 本库提供的所有给外部参考的类型名都已 `CFPD` 开头 (Choice Form Portable Design)，仅供本包内部使用的仍然用常规的 `I` 开头
2. 对于给外部参考的类型，因问卷系统数据结构非常复杂，复杂类型经常会多重继承获取动态能力的，名称差不多很容易混淆类型职责，为了快速分辨各个类型的意图，我们用了一套规则类合理的维护这种关系，并且按分类不同可能会在 `CFPD` 后加不同的字母以示区别，方便快速识别依赖关系
   - `常规类型`不附加任何字母：`CFPD`
   - `标准基类类型`：`CFPDB`
   - `混入基类类型`：`CFPDM`
   - `混入内容类型`：`CFPDX`

对于第 2 点的规则，这里举例说明：

比如我们以节点的类型关系举例：

选择题目需要基本节点功能，问题功能，选项功能，多选功能。

填空题目需要基本节点功能，问题功能，选项功能，选项输入数控制功能。

循环节点需要基本节点功能，选项功能。

其中基本节点功能是所有节点都需要的，当成`标准基类类型`，子类节点总是继承这个类型，这里节点类型是服务目标。

其他功能是不同的节点按需多继承的`混入基类类型`，这些`混入基类类型`本身总是符合(继承)`标准基类类型`的规范(因为他们只为服务目标存在)，同时通过混入`混入内容类型`获得额外的能力。

`混入内容类型`不一定总会单独被定义，只有它需要被在脱离它的服务目标(这里是节点)的场合中被使用时，财货单独被定义，否则，它直接被合并在`混入基类类型`中

所以类型会定义成如下这种方式：

```typescript
/**
 * 标准基类类型，没有真实对应它的节点类型
 */
interface CFPDBNode {
  /**
   * 节点id
   */
  nodeUuid: string;
  /**
   * 节点名称
   */
  nodeName: string;
}
/**
 * 拥有问题功能的节点，没有真实对应它的节点类型
 * 假设它的混入内容没有需要被脱离与节点使用，所有直接混入到自身
 */
interface CFPDBQuestionNode extends CFPDBNode {
  /**
   * 问题文字
   */
  questionText: string;
  /**
   * 问题描述
   */
  describe: string;
}

/**
 * 拥有选项功能的节点，没有真实对应它的节点类型
 * 假设它的混入内容没有需要被脱离于节点使用，所有直接混入到自身
 */
interface CFPDMOptionNode extends CFPDBNode {
  /**
   * 自身选项
   */
  options: any[];
  /**
   * 引用选项
   */
  refOptions: any[];
  /**
   * 选项引用配置
   */
  optionRefers: any[];
}

/**
 * 为多选节点服务的混入功能，但是因为假设这个类型需要在节点类型之外还被使用，所以单独抽出了。
 */
interface CFPDXMultiSelect {
  /**
   * 是否开启多选功能
   */
  multiSelect: boolean;
  /**
   * 最多可选项
   */
  multiMax: number;
  /**
   * 最少需选项
   */
  multiMin: number;
}

/**
 * 拥有多选功能的节点，没有真实对应它的节点类型
 * 假设它的混入内容是需要被脱离于节点使用，所有单独定义到了CFPDMultiSelect中
 */
interface CFPDMMultiSelectNode extends CFPDBNode, CFPDMOptionNode, CFPDXMultiSelect {}

/**
 * 拥有控制选项输入数限制功能的节点，没有真实对应它的节点类型
 * 假设它的混入内容是需要被脱离于节点使用，所有单独定义到了CFPDMultiSelect中
 */
interface CFPDMInputCountNode extends CFPDBNode, CFPDMOptionNode {
  /**
   * 是否开始输入想限制
   */
  useFillCount: boolean;
  /**
   * 最少需要输入的项目数
   */
  fillCount: number;
}

/**
 * 选择题目节点，通过多继承获得了基础功能，问题功能, 选项功能，多选功能
 * 有真实对应它的节点类型
 *
 */
interface CFPDSelectNode
  extends CFPDBNode,
    CFPDBQuestionNode,
    CFPDMOptionNode,
    CFPDMMultiSelectNode {
  // 除了从多方继承来的功能，可能还有自己身上的功能
}

/**
 * 填空题目节点，通过多继承获得了基础功能，问题功能, 选项功能，输入项数控制功能
 * 有真实对应它的节点类型
 *
 */
interface CFPDFillNode extends CFPDBNode, CFPDBQuestionNode, CFPDMOptionNode, CFPDMInputCountNode {
  // 除了从多方继承来的功能，可能还有自己身上的功能
}

/**
 * 循环控制节点，通过多继承获得了基础功能，选项功能
 * 有真实对应它的节点类型
 *
 */
interface CFPDLoopNode extends CFPDBNode, CFPDMOptionNode {
  // 除了从多方继承来的功能，可能还有自己身上的功能
}
```

## Git commit message 约定

格式如下，具体例子可以使用 `git log` 看看。

```
[类型]: [简短描述]

[详细描述，可选]
```

类型如下：

- feat: 新功能
- fix: 修补 bug
- docs: 文档
- style: 代码格式
- refactor: 重构，即不是新增功能，也不是修改 bug 的代码变动
- test: 测试
- chore: 构建过程或辅助工具的变动

注意：本仓库配置了一些提交前检查，如果遇到提交失败，请注意看其提示信息。
