### 术语说明:

#### 平台级字典
通用的类型定于与信息点定义


#### 集团级数据(集团级变更请求审核通过后形成的数据)
集团层面新增或编辑的类型与信息点数据


#### 集团级字典
平台级字典与集团级数据的并集


#### 集团方案
从集团级字典订阅类型与信息点后形成方案,是集团级字典的子集
集团可以配置任意个集团方案


#### 项目级数据(项目级变更请求审核通过后形成的数据)
项目层面新增或编辑的信息点数据


#### 项目级字典
项目所继承的集团方案包含的数据与项目级数据的并集
(继承:当集团方案变化时项目级字典也会同步发生变化)

#### 应用订阅
应用在项目级字典中订阅类型与信息点

```
站在用户或数据字典使用方的角度来看数据字典有三层:平台级字典,集团级字典,项目级字典
类型相同或信息点相同时项目级字典优先级最高,集团级次之,平台级字典最低,优先级高的会覆盖优先级低的

使用数据字典时明确"使用的字典位于哪个层级"对需求的分析和理解会有很大帮助

集团级数据、集团方案、项目级数据是数据字典内部逻辑概念
应用和服务应该关注的是项目级字典和应用订阅内容

```


### 字段约定

| 字段      | 说明                          | 备注 |
| --------- | ----------------------------- | ---- |
| class     | 类型                          |      |
| funcid    | 信息点                        |      |
| classCode | 类型定义的code: class.code    |      |
| className | 类型定义的name: class.name    |      |
| infoCode  | 信息点定义的code: funcid.code |      |
| infoName  | 信息点定义的name: funcid.name |      |
| groupId   | 集团ID                        |      |
| projectId | 项目ID                        |      |
| schemeId  | 集团方案ID                     |      |
|           |                               |      |
|           |                               |      |

### 数据结构

类型 class

| 字段       | 数据类型 | 说明                                                       |
| ---------- | -------- | ---------------------------------------------------------- |
| code       | String   | 全局唯一                                                   |
| name       | String   | 类型名称                                                   |
| aliasCode  | String   | 类型别名编码, 集团下唯一                                   |
| aliasName  | String   | 类型别名名称                                               |
| type       | String   | 类别:平台级common,集团级group,项目级project                |
| groupId    | String   | 集团id, type=group或type=project时该字段为集团id,否则为"0" |
| projectId  | String   | 集团id, type=project时该字段为项目id,否则为"0"             |
| majorCode  | String   | 专业编码, 上级类型是系统or设备时该字段有值                 |
| systemCode | String   | 系统编码,上级类型是设备时该字段有值,值为系统类型的code     |
| parentCode | String   | 上级类型code                                               |
|            |          |                                                            |

信息点 funcid

| 字段       | 数据类型          | 说明                                                         |
| ---------- | ----------------- | ------------------------------------------------------------ |
| code       | String            | 信息点编码,同类型下唯一                                      |
| name       | String            | 信息点名称                                                   |
| classCode  | String            | 类型编码                                                     |
| type       | String            | 字典级别:平台级common,集团级group,项目级project                  |
| category   | String            | 信息点分类:静态,脉冲,阶段,时序                  |
| groupId    | String            | 集团id, type=group或type=project时该字段为集团id,否则为"0"   |
| projectId  | String            | 集团id, type=project时该字段为项目id,否则为"0"               |
| firstTag   | String            | 一级标签                                                     |
| secondTag  | String            | 二级标签                                                     |
| priority   | String            | 优先级                                                       |
| inputMode  | String            | 输入方式                                                     |
| unit       | String            | 单位                                                         |
| dataType   | String            | 数据类型                                                     |
| isMultiple | Boolean           | 是否复数                                                         |
| isRegion   | Boolean           | 是否区间                                                         |
| formater   | String            | 数据格式                                                         |
| dataSource | String / Object[] | 数据源取值范围/枚举值清单等,根据dataType有不同的内容      |
| note       | String            | 备注                                                         |
| subFlag    | String            | 子分类标记:是否可以按此信息点进行子分类替换,同一类型下目前只支持一个子分类信息点 |

#### 信息点数据类型
|数据类型|类型名称|信息点分类|是否复数|是否区间|数据源|格式|
|---|---|---|---|---|---|---|
|INTEGER    | 整数      |静态/脉冲/时序/阶段    |true/false  |true/false  |{$gt:10, $lt:50}                                           | 无     |
|DOUBLE     | 浮点型    |静态/脉冲/时序/阶段    |true/false  |true/false  |{$gte:10.1, $lt:50.9}                                      | 无     |
|BOOLEAN    | 布尔值    |静态/脉冲/时序/阶段    |true/false  |false       |                                                           | 无     |
|STRING     | 字符串    |静态/脉冲/时序/阶段    |true/false  |false       |(字符串长度区间){$gt:10, $lt:50}                             | 无     |
|DATETIME   | 日期时间  |静态/脉冲/时序/阶段    |true/false  |true/false  |{$gt:'0915', $lt:'1031'}                                   | 'MMdd' |
|ENUM       | 单选枚举  |静态/脉冲/时序/阶段    |true/false  |false       |[{code: 'GC', name: '国产'},{code: 'JK', name: '进口'}]     | 无     |
|MENUM      | 多选枚举  |静态/脉冲/时序/阶段    |true/false  |false       |[{code: 'GC', name: '国产'},{code: 'JK', name: '进口'}]     | 无     |
|ATTACHMENT | 附件      |静态                 |true/false  |false       |                                                           | pdf    |
|OBJECT     | 对象      |静态                 |true/false  |false       |                                                           | 对象id |

说明
```
把原来的data_type拆解成多个属性,减少了data_type种类数量
使用新的数据类型时,使用新的数据类型时,创建或编辑信息点需要明确指出数据类型、动静分类、是否复数、是否区间、长度（可选）、取值区间（可选）、格式（可选）
Tree、Topology、Route、Function四种类型不再支持(有需求再加回来)

动静分类（静态 STATIC、脉冲 PULSE、时序 SEQUENTIAL、阶段 GRADATION）应该是信息点的一个分类，不是数据类型的属性，放在这里是为了更直观更容易理解
根据动静分类区分动态量或静态量,静态量的值存储的是具体的数据,动态量的值存储的是表号-功能号,动态量包括脉冲量、时序量和阶段量
根据是否区间来判断存储的值是具体值还是区间, 比如INTEGER非区间的值12, 区间值[8, 15],为了区分开闭区间,这里实际存储为{$gt: 12, $lte: 15}, 其中$gt大于,$lt小于,$gte大于等于,$lte小于等于
根据是否复数区分存储的值是单个值还是多个值,单个值存储形式为xxx,多个值存储形式为[xxx, yyy],如果同时是复数和区间,存储的是多个区间
取值区间可以约束值的取值范围,可以通过取值区间做一次校验,如果是区间值,区间也应该是在取值区间的内部
统一用DATETIME表示日期和时间,通过格式设定具体存储的内容,格式由数据字典进行维护,物理世界存储的数据严格符合格式
格式是数据存储的数据格式或文件格式,对于日期时间附件对象等可进行校验
单选枚举Enum单数存储为GC, 复数存储为[GC, JK]
多选枚举MEnum单数存储为[GC, JK], 复数存储为[[GC], [GC,JK]], 多选枚举单数和单选枚举复数的存储形式一样应该不会出现问题,因为实际使用时是和类型(Enum,Menum)一起使用,

```


### 接口

#### 基础接口: 专业

请求地址

```
POST: /major/query
```

请求参数

```
{
	"criteria": {
		"code": "AC"
	}
}
```
返回内容

```
{
    "result": "success",
    "count": 1,
    "data": [
        {
            "code": "AC",
            "name": "空调专业"
        }    
    ]
}
```

#### 基础接口:类型查询

请求地址

```
POST: /class/query
```

请求参数

```
{
	"criteria": {
		"majorCode": "AC"
	}
}
```

请求参数说明

| 字段     |            | 说明                                        |      |
| -------- | ---------- | ------------------------------------------- | :--- |
| criteria |            |                                             |      |
|          | code       | 类型编码                                    |      |
|          | type       | 分类:平台级common,集团级group,项目级project |      |
|          | groupId    | 集团id, type=group时必须传入该参数          |      |
|          | projectId  | 项目id, type=project时必须传入该参数        |      |
|          | parentCode | 上级类型编码                                |      |
|          | majorCode  | 专业编码,查询系统or设备时可以传入该字段     |      |
|          | systemCode | 系统类型编码, 查询设备时可以传入该字段      |      |
|          |            |                                             |      |

返回内容

```
{
    "result": "success",
    "count": 2,
    "data": class[]  // 类型列表
}
```



#### 基础接口:信息点查询
请求地址

```
POST: /funcid/query
```

请求参数

```
{
	"criteria": {
		"type": ["group"],
		"classCode": "ACCC"
	}
}
```

参数说明

| 字段     |           | 非空 | 描述                                        |
| -------- | --------- | ---- | ------------------------------------------- |
| criteria |           | Y    |                                             |
|          | classCode | Y    | 根据类型编码查询                            |
|          | type      | N    | 分类:平台级common,集团级group,项目级project |
|          | groupId   | N    | 集团id, type=group时必须传入该参数          |
|          | projectId | N    | 项目id, type=project时必须传入该参数        |
|          | code      | N    | 信息点编码                                  |
|          | name      | N    |                                             |
|          | firstTag  | N    | 一级标签                                    |
|          | secondTag | N    | 二级标签                                    |
|          | inputMode | N    |                                             |

返回内容

```
{
    "result": "success",
    "count": 159,
    "data": funcid[] // 信息点列表
}
```



#### 封装接口:类型树

请求地址

```
GET: /class
```

请求参数

| 参数名    | 说明                                    |                |
| --------- | --------------------------------------- | -------------- |
| groupId   | 集团id                                  | 可选           |
| schemeId  | 集团方案id                              | 可选           |
| projectId | 项目id                                  | 可选           |
| appId     | 应用id,传入appId时必须同时传入projectId | 可选           |
| subFlag   | true/false, 是否按分类信息点展示子分类  | 可选,默认false |

返回参数

```
{
    "result": "success",
    "data": [
        {
            "code": "project",
            "name": "项目",
            "aliasCode": "project",
            "aliasName": "项目"
        },
        {
            "code": "system",
            "name": "系统",
            "aliasCode": "system",
            "aliasName": "系统",
            "children": [
                {
                    "code": "system-AC",
                    "name": "空调专业",
                    "aliasCode": "system-AC",
                    "aliasName": "空调专业",
                    "children": [
                        {
                            "code": "ACCH",
                            "name": "中央供热系统",
                            "aliasCode": "ACCH",
                            "aliasName": "中央供热系统",
                            "majorCode": "AC",
                            "parentCode": "system"
                        },
                        {
                            "code": "ACCC",
                            "name": "中央供冷系统",
                            "aliasCode": "ACCC",
                            "aliasName": "中央供冷系统",
                            "majorCode": "AC",
                            "parentCode": "system"
                        }
                    ]
                }
            ]
        },
        {
            "code": "equipment",
            "name": "设备",
            "aliasCode": "equipment",
            "aliasName": "设备",
            "children": [
                {
                    "code": "equipment-AC",
                    "name": "空调专业",
                    "aliasCode": "equipment-AC",
                    "aliasName": "空调专业",
                    "children": [
                        {
                            "code": "equipment-ACCH",
                            "name": "中央供热系统",
                            "aliasCode": "equipment-ACCH",
                            "aliasName": "中央供热系统",
                            "children": [
                                {
                                    "code": "ACCHCL",
                                    "name": "供热集水器",
                                    "aliasCode": "ACCHCL",
                                    "aliasName": "供热集水器",
                                    "majorCode": "AC",
                                    "systemCode": "ACCH",
                                    "parentCode": "equipment"
                                }
                            ]
                        },
                        {
                            "code": "equipment-ACCC",
                            "name": "中央供冷系统",
                            "aliasCode": "equipment-ACCC",
                            "aliasName": "中央供冷系统",
                            "children": [
                                {
                                    "code": "ACCCWT",
                                    "name": "供冷水箱",
                                    "aliasCode": "ACCCWT",
                                    "aliasName": "供冷水箱",
                                    "majorCode": "AC",
                                    "systemCode": "ACCC",
                                    "parentCode": "equipment"
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}
```

#### 封装接口:信息点

请求地址

```
GET: /funcid
```

请求参数

| 参数名    | 说明                                    |      |
| --------- | --------------------------------------- | ---- |
| classCode   | 类型编码                                | 必选 |
| groupId   | 集团id                                  | 可选 |
| schemeId  | 集团方案id                              | 可选 |
| projectId | 项目id                                  | 可选 |
| appId     | 应用id,传入appId时必须同时传入projectId | 可选 |
|           |                                         |      |
请求参数说明
```
1.传入projectId是必须同时传入groupId
2.传入projectId时对应项目必须已配置集团方案,schemeId可以不传,否则报错"当前项目未配置集团方案"
3.传入appId时必须同时传入projectId

```

返回参数

```
{
    "result": "success",
    "count": 159,
    "data": funcid[] // 信息点列表
}
```



#### 基础接口: 提交变更请求

请求地址

```
POST: /req/create
```

请求参数

```
{
    "type": "group",
    "groupId": "WD",
    "projectId": "pj01",
    "note": "变更原因",
    "createUser": "f0bcc7a79f7043f9a16812b5f80580d2",
    "classes": [{
        "code": "类型编码",
        "name": "类型名称",
        "aliasCode": "",
        "aliasName": "",
        "parentCode": "",
        "majorCode": "",
        "systemCode": "",
        "note": "",
        "funcids": [{
            "code": "",
            "name": "",
            "firstTag": "",
            "secondTag": "",
            "unit": "",
            "dataType": "",
            "priority": "",
            "inputMode": "",
            "dataSource": "",
            "subFlag": false,
            "note": ""
        }]
    }]
}
```

请求参数说明

| 字段      |            |            | 类型     | 说明                           |
| --------- | ---------- | ---------- | -------- | ------------------------------ |
| type      |            |            | String   | group/project                  |
| groupId   |            |            | String   | 集团id, 不可为空               |
| projectId |            |            | String   | 项目id, type=project时不可为空 |
| note      |            |            | String   | 变更原因说明                   |
| createUser    |            |            | String   | 提交人id,不可为空              |
| classes   |            |            | Object[] | 不可为空且长度>0               |
|           | code       |            | String   | 不可为空                       |
|           | name       |            | String   |                                |
|           | aliasCode  |            | String   |                                |
|           | aliasName  |            | String   |                                |
|           | parentCode |            | String   |                                |
|           | majorCode  |            | String   |                                |
|           | systemCode |            | String   |                                |
|           | note       |            | String   |                                |
|           | funcids    |            | Object[] |                                |
|           |            | code       | String   | 不可为空                       |
|           |            | name       | String   |                                |
|           |            | firstTag   | String   |                                |
|           |            | secondTag  | String   |                                |
|           |            | unit       | String   |                                |
|           |            | dataType   | String   |                                |
|           |            | priority   | String   |                                |
|           |            | inputMode  | String   |                                |
|           |            | dataSource | String   |                                |
|           |            | subFlag    | Boolean  |                                |
|           |            | note       | String   |                                |
|           |            |            |          |                                |

接口逻辑说明:

```
1.type=group为集团级变更, type=project为项目级变更

2.classes不可为空且长度必须>0
若classes.code存在(从集团级字典判断)则为修改:
	name不可修改(传入也无效), 其他字段根据传入值进行修改, 不传则不修改
若classes.code不存在则为新增:
	code、name、parentCode不可为空
	parentCode=system时majorCode不可为空
	parentCode=equipment时majorCode、systemCode不可为空

3.funcids存在且长度>0时,根据classes.code进行判断
若funcids.code存在则为修改:
	所有字段都可以修改,根据传入值进行修改,不传则不修改
若funcids.code不存在则为新增:
	code、name、unit、dataType、inputMode、dataSource、subFlag不可为空
```

返回参数

```
{
    "result": "success",
    "data": {
    		"id": 123
    }
}
```

返回参数说明

| 字段 | 类型 | 说明   |
| ---- | ---- | ------ |
| id   | Int  | 变更ID |



#### 基础接口: 审核变更请求

请求地址

```
POST: /req/audit
```

请求参数

```
{
    "id": 123,
    "status": 2,
    "applyUser": "f0bcc7a79f7043f9a16812b5f80580d2"
}
```

请求参数说明

| 字段       | 类型   | 说明                                 |
| ---------- | ------ | ------------------------------------ |
| id         | Int    | 变更ID,不可为空                      |
| status     | Int    | 状态: 1待审核,2审核通过, 3审核不通过 |
| applyUser  | String    | 审核人id |
|            |        |                                      |

返回内容

```
{
    "result": "success",
}
```



#### 基础接口: 查询变更请求

请求地址

```
POST: /req/query
```

请求参数

```
{
    "criteria": {
        "id": 123,
        "type": "project",
        "groupId": "WD",
        "projectId": "pj01",
        "status": 2,
        "createTime": {
                "$gt": "20200330120000"
        },
        "applyTime": {
                "$gt": "20200330120000"
        },
    },
    "withColumns": [ "classes", "funcids" ]
}
```

请求参数说明

| 字段        |            | 说明                                               |      |
| ----------- | ---------- | -------------------------------------------------- | :--- |
| criteria    |            |                                                    |      |
|             | id         | 变更ID                                             |      |
|             | type       | 分类:集团级group,项目级project                     |      |
|             | groupId    | 集团id, type=group时必须传入该参数                 |      |
|             | projectId  | 项目id, type=project时必须传入该参数               |      |
|             | status     | 状态: 1待审核,2审核通过, 3审核不通过               |      |
|             | createTime | 提交时间                                           |      |
|             | creatUser  | 申请提交人                                         |      |
|             | applyTime  | 审核时间                                           |      |
|             | applyUser  | 申请审核人                                         |      |
| withColumns |            |                                                    |      |
|             | classes    | 返回申请的类型数据                                 |      |
|             | funcids    | 返回申请的类型的信息点数据,必须同时指定返回classes |      |



返回内容

```
{
	"result": "success",
	"data": [{
        "id": 123,
        "type": "group",
        "groupId": "WD",
        "projectId": "pj01",
        "note": "变更原因",
        "userId": "提交用户",
        "status": 2,
        "createTime": 1585014171013,
        "createUser": "f0bcc7a79f7043f9a16812b5f80580d2",
        "applyTime": 1585014190419,
        "applyUser": "f0bcc7a79f7043f9a16812b5f80580d2",
        "classes": [{
            "code": "类型编码",
            "name": "类型名称",
            "optType": "create/update",
            "aliasCode": "",
            "aliasName": "",
            "parentCode": "",
            "majorCode": "",
            "systemCode": "",
            "note": "",
            "funcids": [{
                "optType": "create/update",
                "code": "",
                "name": "",
                "firstTag": "",
                "secondTag": "",
                "unit": "",
                "dataType": "",
                "priority": "",
                "inputMode": "",
                "dataSource": "",
                "subFlag": false,
                "note": ""
            }]
        }]
    }
]}
```

返回内容说明

| 字段                    | 类型   | 说明                                 |      |
| ----------------------- | ------ | ------------------------------------ | ---- |
| status                  | int    | 状态: 1待审核,2审核通过, 3审核不通过 |      |
| createUser              | string | 申请人id                             |      |
| createTime              | long   | 申请提交时间                         |      |
| applyUser               | string | 审核人id, status=1时为空             |      |
| applyTime               | long   | 审核时间                             |      |
| classes.optType         | string | 操作类型: create新增,update更新      |      |
| classes.funcids.optType | string | 操作类型: create新增,update更新      |      |
| ...                     |        | 其他字段与申请提交的入参相同         |      |
|                         |        |                                      |      |
|                         |        |                                      |      |

#### 基础接口:批量添加应用订阅信息

请求地址

```
POST: /app/funcid/add?groupId=SN&projectId=Pj01&app=test&classCode=project
```

请求参数
```json
["ProjUnderArea","Group"]
```

| 参数名    | 说明                                    |   备注   |
| --------- | --------------------------------------- | ---- |
| classCode   | 类型编码                                | 必填 |
| groupId   | 集团id                                  | 必填 |
| projectId | 项目id                                  | 必填 |
| app     | 应用id| 必填 |
| json参数          |信息点列表                                         |  列表size大于0    |

返回参数

```
{
    "result": "success"
}
```

#### 基础接口:批量删除应用订阅信息

请求地址

```
POST: /app/funcid/remove?groupId=SN&projectId=Pj01&app=test&classCode=project
```

请求参数
```json
["ProjUnderArea","Group"]
```

| 参数名    | 说明                                    |   备注   |
| --------- | --------------------------------------- | ---- |
| classCode   | 类型编码                                | 必填 |
| groupId   | 集团id                                  | 必填 |
| projectId | 项目id                                  | 必填 |
| app     | 应用id| 必填 |
| json参数          |信息点列表                                         |  列表size大于0    |

返回参数

```
{
    "result": "success"
}
```

#### 基础接口:批量添加应用订阅类型

请求地址

```
POST: /app/class/add?groupId=SN&projectId=Pj01&app=test
```

请求参数
```json
["ProjUnderArea","Group"]
```

| 参数名    | 说明                                    |  备注    |
| --------- | --------------------------------------- | ---- |
| groupId   | 集团id                                  | 必填 |
| projectId | 项目id                                  | 必填 |
| app     | 应用id| 必填 |
| json参数          |类型列表                                         |  列表size大于0    |

返回参数

```
{
    "result": "success"
}
```
#### 基础接口:批量删除应用订阅类型

请求地址

```
POST: /app/class/remove?groupId=SN&projectId=Pj01&app=test
```

请求参数
```json
["ProjUnderArea","Group"]
```

| 参数名    | 说明                                    |   备注   |
| --------- | --------------------------------------- | ---- |
| groupId   | 集团id                                  | 必填 |
| projectId | 项目id                                  | 必填 |
| app     | 应用id| 必填 |
| json参数          |类型列表                                         |  列表size大于0    |

返回参数

```
{
    "result": "success"
}
```


#### 基础接口:批量添加方案订阅信息

请求地址

```
POST: /scheme/funcid/add?schemeId=test&classCode=project
```

请求参数
```json
["ProjUnderArea","Group"]
```

| 参数名    | 说明                                    |  备注    |
| --------- | --------------------------------------- | ---- |
| classCode   | 类型编码                                | 必填 |
| schemeId     | 方案id| 必填 |
| json参数          |信息点列表                                         |  列表size大于0    |

返回参数

```
{
    "result": "success"
}
```

#### 基础接口:批量删除方案订阅信息

请求地址

```
POST: /scheme/funcid/remove?projectId=Pj01&schemeId=test&classCode=project
```

请求参数
```json
["ProjUnderArea","Group"]
```

| 参数名    | 说明                                    |   备注   |
| --------- | --------------------------------------- | ---- |
| classCode   | 类型编码                                | 必填 |
| projectId | 项目id                                  | 必填 |
| schemeId     | 方案id| 必填 |
| json参数          |信息点列表                                         |  列表size大于0    |

返回参数

```
{
    "result": "success"
}
```

#### 基础接口:批量添加方案订阅类型

请求地址

```
POST: /scheme/class/add?schemeId=test
```

请求参数
```json
["ProjUnderArea","Group"]
```

| 参数名    | 说明                                    |   备注   |
| --------- | --------------------------------------- | ---- |
| schemeId     | 方案id| 必填 |
| json参数          |类型列表                                         |  列表size大于0    |

返回参数

```
{
    "result": "success"
}
```
#### 基础接口:批量删除方案订阅类型

请求地址

```
POST: /scheme/class/romove?schemeId=test
```

请求参数
```json
["ProjUnderArea","Group"]
```

| 参数名    | 说明                                    |    备注  |
| --------- | --------------------------------------- | ---- |
| schemeId     | 方案id| 必填 |
| json参数          |类型列表                                         |  列表size大于0    |

返回参数

```
{
    "result": "success"
}
```
