DepartmentAPIController(部门管理 API)¶
用户中心模块的部门域 CRUD/查询控制器,提供部门的创建、更新、查找、删除,以及按父部门、层级、名称、域、用户、第三方(微信/蓝信/钉钉)部门 ID、有效状态、模糊名称等多维度查询能力,并支持按域+上级+名称的复合分页查询与子部门数量统计。该控制器由 obpm-runtime、obpm-manager、obpm-kms 等宿主服务以 Feign 方式内部调用(DepartmentAPI 接口),属于后端服务间数据面接口。
- 控制器全限定名:
cn.myapps.usercenter.controller.DepartmentAPIController - 接口(Feign 契约):
cn.myapps.usercenter.controller.DepartmentAPI - Tag:部门管理
- 类级
@RequestMapping:${myapps.context-path.usercenter:}/department - 基址:
<host>/usercenter/department - 独立部署(
obpm-usercenter-war/obpm-usercenter-consul):server.servlet.context-path=/usercenter,占位符${myapps.context-path.usercenter:}缺省为空,故实际基址为<host>:<port>/usercenter/department(war 端口 8080,consul 端口 8088)。 - 统一部署(
obpm-lite):server.servlet.context-path=/,yml 显式配置myapps.context-path.usercenter=/usercenter,故实际基址同样为<host>:8888/usercenter/department。 - 接口类型:REST 资源
公共说明¶
鉴权¶
(据源码)usercenter 模块本身**不定义**任何安全过滤器或鉴权拦截器,仅注册 PersistenceHandlerInterceptor(用于 DAO 资源清理——事务提交与 Hibernate Session 关闭,不做权限判断)。本控制器 /department/** 路径下所有端点**不做用户级身份校验**——既不读取 accessToken,也不读取 adminToken/designerToken,控制器方法内也不调用任何 getUser() 之类方法。
usercenter 作为共享库被宿主服务加载后,会继承 obpm-common 提供的 CommonSecurityFilter(由 CommWebMvcConfig 以 @Bean 注册,URL 模式 /*,order=-1,详见 index.md「鉴权说明」),对 /department/** 的影响仅限:
- HTTP 方法限制:未携带合法
systemToken请求头时,仅允许GET/POST/HEAD/OPTIONS方法;直接发起PUT/DELETE/PATCH等请求会被CommonSecurityFilter以 HTTP405(HTML 错误页,无 JSON 体)拒绝。 systemToken放行:携带合法systemToken请求头(系统间 Feign 调用,JWT 内username固定为systemToken)的请求被标记pass=true并绕过上述方法限制——这是本控制器PUT /update、DELETE /remove/{id}在生产中正常工作的前提。
结论:本控制器的真实访问控制依赖**网络层隔离**(仅由可信的内部服务经 Feign 调用,附
systemToken请求头),并非用户令牌。终端用户不应直接访问这些端点。
响应结构¶
本控制器不使用统一 Resource 结构(与 ../index.md「统一响应结构」不同)。响应遵循以下规则:
| 情形 | HTTP 状态 | 响应体 |
|---|---|---|
返回值为 void 的方法(创建/更新/删除)成功 |
200 | 空响应体 |
| 返回值为领域对象/集合/包装类型的方法成功 | 200 | 直接序列化的对象 JSON(如 DepartmentPO、Collection<DepartmentPO>、DataPackage<DepartmentPO>、long),不包裹 errcode/errmsg/data/errors |
| 业务/系统异常 | 500 | {"errcode":500,"errmsg":"<异常信息>"}(由 obpm-common 的 CommonsExceptionResolver 全局异常处理器渲染,仅含 errcode/errmsg 两字段,无 data/errors) |
HTTP 方法不被允许(无 systemToken 的 PUT/DELETE) |
405 | HTML 错误页(由 CommonSecurityFilter 直接返回) |
| 系统启动中 | 500 | HTML 错误页(由 CommonSecurityFilter 直接返回) |
数据模型:DepartmentPO¶
返回的 DepartmentPO 继承自 AuthtimeValueObject,表示组织架构中具有上下级关系的节点(部门、职位、区域、城市等,统属一个根节点)。主要字段:id、name(部门名称)、superior(上级部门 DepartmentPO)、code(部门代码)、level(部门层级)、indexCode(索引代码,组成规则为「上级 indexCode + _ + 自身 Id」,顶级部门的 indexCode 即自身 id)、domain(所属企业域 DomainPO)、valid(有效状态,1=有效/0=无效,默认 1)、orderByNo(排序号)、weixinDeptId(企业微信部门 id)、lanxinDeptId(蓝信部门 id)、dingdingDeptId(钉钉部门 id)、fsDeptId(飞书部门 id)、field1field10(业务扩展字段)、field11field20(系统扩展字段)、fieldExtendsValues(列表扩展字段值集合,不映射到 Hibernate)、lastModifyTime(最后修改时间,@JsonIgnore 不序列化)。
分页结构:DataPackage<DepartmentPO>¶
queryByDoaminAndSuperiorAndName 返回 cn.myapps.common.data.DataPackage<DepartmentPO>,标准字段为 datas(当前页数据集合)、rowCount(总行数)、pageNo(当前页码)、linesPerPage(每页行数)等。
注:
queryByDomain/{domainId}虽接收page/lines分页参数,但返回类型为Collection<DepartmentPO>(非DataPackage),即返回当前页集合而非带分页元数据的包装。
1. 创建部门¶
创建新的部门信息。事务保护:失败回滚。
- 接口类型:REST 资源
- 请求方式:
POST - 请求路径:
/create(完整:<host>/usercenter/department/create) - 鉴权:内部(建议经
systemToken的 Feign 调用;直接调用因 POST 方法不被CommonSecurityFilter拦截故技术上无需 token,但本控制器为内部数据面接口) - Tag:部门管理
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| body | body | DepartmentPO |
是 | 部门信息,通常包含 name、level、superior(上级部门)、domain(所属域)等 |
请求示例¶
POST /usercenter/department/create HTTP/1.1
Content-Type: application/json
systemToken: <系统间 JWT>
{
"name": "研发中心",
"level": 1,
"domain": "<域ID>",
"valid": 1
}
响应¶
结构:成功为**空响应体**(返回类型 void);失败为 {"errcode":500,"errmsg":"<异常信息>"},HTTP 500。
成功示例:(HTTP 200,空响应体)
失败示例:
2. 更新部门信息¶
更新现有部门信息。事务保护:失败回滚。
- 接口类型:REST 资源
- 请求方式:
PUT - 请求路径:
/update(完整:<host>/usercenter/department/update) - 鉴权:内部(
PUT方法需携带合法systemToken请求头,否则被CommonSecurityFilter以 HTTP405拒绝) - Tag:部门管理
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| body | body | DepartmentPO |
是 | 待更新部门(须含主键 id),可携带需更新的字段 |
请求示例¶
PUT /usercenter/department/update HTTP/1.1
Content-Type: application/json
systemToken: <系统间 JWT>
{
"id": "__DEPT001",
"name": "研发中心-new",
"level": 1
}
响应¶
结构:成功为**空响应体**(返回类型 void);失败为 {"errcode":500,"errmsg":"<异常信息>"},HTTP 500。若未带 systemToken,HTTP 405(HTML 错误页)。
成功示例:(HTTP 200,空响应体)
失败示例:
3. 根据 ID 查找部门¶
根据部门 ID 查找单个部门。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/find/{id}(完整:<host>/usercenter/department/find/{id}) - 鉴权:内部
- Tag:部门管理
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| id | path | string | 是 | 部门 ID |
请求示例¶
响应¶
结构:成功为 DepartmentPO 对象 JSON(不包裹 Resource);未找到时由 DAO 行为决定(通常返回 null 或抛异常进入 CommonsExceptionResolver)。
成功示例:
失败示例:
4. 根据 ID 删除部门¶
根据部门 ID 删除部门。事务保护:失败回滚。
- 接口类型:REST 资源
- 请求方式:
DELETE - 请求路径:
/remove/{id}(完整:<host>/usercenter/department/remove/{id}) - 鉴权:内部(
DELETE方法需携带合法systemToken请求头,否则被CommonSecurityFilter以 HTTP405拒绝) - Tag:部门管理
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| id | path | string | 是 | 部门 ID |
请求示例¶
响应¶
结构:成功为**空响应体**(返回类型 void);失败为 {"errcode":500,"errmsg":"<异常信息>"},HTTP 500。若未带 systemToken,HTTP 405(HTML 错误页)。
成功示例:(HTTP 200,空响应体)
失败示例:
5. 获取指定父部门的所有子部门¶
根据父部门 ID 查询其下所有子部门集合。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/getDatasByParent/{parentId}(完整:<host>/usercenter/department/getDatasByParent/{parentId}) - 鉴权:内部
- Tag:部门管理
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| parentId | path | string | 是 | 父部门 ID |
请求示例¶
响应¶
结构:成功为 Collection<DepartmentPO> JSON 数组(不包裹 Resource)。
成功示例:
失败示例:
6. 根据层级获取部门¶
根据部门层级和域 ID 查询该层级下的部门集合。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/getDepartmentByLevel/{domainId}(完整:<host>/usercenter/department/getDepartmentByLevel/{domainId}) - 鉴权:内部
- Tag:部门管理
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainId | path | string | 是 | 域 ID |
| level | query | int | 是 | 部门层级 |
请求示例¶
响应¶
结构:成功为 Collection<DepartmentPO> JSON 数组(不包裹 Resource)。
成功示例:
失败示例:
7. 根据部门名称查询部门¶
根据部门名称和域 ID 查询匹配的部门集合。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/getDepartmentByName/{domainId}(完整:<host>/usercenter/department/getDepartmentByName/{domainId}) - 鉴权:内部
- Tag:部门管理
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainId | path | string | 是 | 域 ID |
| name | query | string | 是 | 部门名称 |
请求示例¶
响应¶
结构:成功为 Collection<DepartmentPO> JSON 数组(不包裹 Resource)。
成功示例:
失败示例:
8. 获取指定域的根部门¶
根据域 ID 获取该域的根部门(顶级部门)。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/getRootDepartmentByDomainId/{domainId}(完整:<host>/usercenter/department/getRootDepartmentByDomainId/{domainId}) - 鉴权:内部
- Tag:部门管理
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainId | path | string | 是 | 域 ID |
请求示例¶
响应¶
结构:成功为 DepartmentPO 对象 JSON(不包裹 Resource);未找到时由 DAO 行为决定。
成功示例:
失败示例:
9. 根据域 ID 和父部门查询部门¶
根据域 ID 与父部门 ID 查询该域下指定父部门的子部门集合。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/queryByDomainAndParent/{domainId}(完整:<host>/usercenter/department/queryByDomainAndParent/{domainId}) - 鉴权:内部
- Tag:部门管理
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainId | path | string | 是 | 域 ID |
| parent | query | string | 是 | 父部门 ID |
请求示例¶
GET /usercenter/department/queryByDomainAndParent/__DMN001?parent=__DEPT001 HTTP/1.1
systemToken: <系统间 JWT>
响应¶
结构:成功为 Collection<DepartmentPO> JSON 数组(不包裹 Resource)。
成功示例:
[
{ "id": "__DEPT002", "name": "研发一部", "superior": { "id": "__DEPT001" }, "domain": { "id": "__DMN001" } }
]
失败示例:
10. 获取子部门数量¶
根据父部门 ID 统计其下子部门的数量。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/getChildrenCount(完整:<host>/usercenter/department/getChildrenCount) - 鉴权:内部
- Tag:部门管理
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| parent | query | string | 是 | 父部门 ID |
请求示例¶
响应¶
结构:成功为 long(裸数字,不包裹 Resource)。
成功示例:
失败示例:
11. 根据域 ID 分页查询部门¶
根据域 ID 分页查询该域下的部门集合。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/queryByDomain/{domainId}(完整:<host>/usercenter/department/queryByDomain/{domainId}) - 鉴权:内部
- Tag:部门管理
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainId | path | string | 是 | 域 ID |
| page | query | int | 是 | 页码(1 起) |
| lines | query | int | 是 | 每页条数 |
请求示例¶
响应¶
结构:成功为 Collection<DepartmentPO> JSON 数组(当前页数据,不包裹 Resource;返回类型非 DataPackage,故不带分页元数据)。
成功示例:
失败示例:
12. 根据名称和层级查询部门¶
根据父部门 ID、部门名称、层级和域 ID 查询单个匹配的部门。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/getDepartmentByNameAndLevel/{domainId}(完整:<host>/usercenter/department/getDepartmentByNameAndLevel/{domainId}) - 鉴权:内部
- Tag:部门管理
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainId | path | string | 是 | 域 ID |
| parentId | query | string | 否 | 父部门 ID(required=false,缺省不限) |
| name | query | string | 是 | 部门名称 |
| level | query | int | 是 | 部门层级 |
请求示例¶
GET /usercenter/department/getDepartmentByNameAndLevel/__DMN001?parentId=__DEPT001&name=研发一部&level=2 HTTP/1.1
systemToken: <系统间 JWT>
响应¶
结构:成功为 DepartmentPO 对象 JSON(不包裹 Resource);未找到时由 DAO 行为决定。
成功示例:
{
"id": "__DEPT002",
"name": "研发一部",
"level": 2,
"superior": { "id": "__DEPT001" },
"domain": { "id": "__DMN001" }
}
失败示例:
13. 根据域 ID、上级部门和名称查询部门¶
按域 ID、上级部门 ID、名称等多条件复合分页查询部门;可通过 order 排序、valid 过滤有效状态,并透传附加查询条件 Map。
- 接口类型:REST 资源
- 请求方式:
POST - 请求路径:
/queryByDoaminAndSuperiorAndName/{domainId}(完整:<host>/usercenter/department/queryByDoaminAndSuperiorAndName/{domainId}) - 鉴权:内部
- Tag:部门管理
注:路径中的
Doamin为源码原始拼写(非Domain),调用时须保持一致。
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainId | path | string | 是 | 域 ID |
| map | body | Map<String, Object> |
是 | 附加查询条件映射(透传至 DAO) |
| superiorId | query | string | 否 | 上级部门 ID(required=false,缺省不限) |
| name | query | string | 否 | 部门名称(required=false,缺省不限) |
| order | query | string | 否 | 排序方式(required=false,缺省默认) |
| valid | query | Integer | 否 | 是否有效(required=false,1=有效/0=无效,缺省不限) |
| page | query | int | 是 | 页码(1 起) |
| lines | query | int | 是 | 每页条数 |
请求示例¶
POST /usercenter/department/queryByDoaminAndSuperiorAndName/__DMN001?superiorId=__DEPT001&name=研发&order=asc&valid=1&page=1&lines=20 HTTP/1.1
Content-Type: application/json
systemToken: <系统间 JWT>
{ "extraKey": "extraValue" }
响应¶
结构:成功为 DataPackage<DepartmentPO> 对象 JSON(不包裹 Resource),含 datas(当前页部门集合)、rowCount、pageNo、linesPerPage 等字段。
成功示例:
{
"datas": [
{ "id": "__DEPT002", "name": "研发一部", "level": 2, "valid": 1 }
],
"rowCount": 1,
"pageNo": 1,
"linesPerPage": 20
}
失败示例:
14. 根据用户 ID 查询关联部门¶
根据用户 ID 查询该用户关联的所有部门集合。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/queryByUser(完整:<host>/usercenter/department/queryByUser) - 鉴权:内部
- Tag:部门管理
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| userId | query | string | 是 | 用户 ID |
请求示例¶
响应¶
结构:成功为 Collection<DepartmentPO> JSON 数组(不包裹 Resource)。
成功示例:
失败示例:
15. 根据蓝信部门 ID 查询部门¶
根据蓝信部门 ID 和域 ID 查询匹配的部门集合。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/queryByDomainAndLanxinDept/{domainId}(完整:<host>/usercenter/department/queryByDomainAndLanxinDept/{domainId}) - 鉴权:内部
- Tag:部门管理
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainId | path | string | 是 | 域 ID |
| lanxinDeptId | query | int | 是 | 蓝信部门 ID |
请求示例¶
GET /usercenter/department/queryByDomainAndLanxinDept/__DMN001?lanxinDeptId=1001 HTTP/1.1
systemToken: <系统间 JWT>
响应¶
结构:成功为 Collection<DepartmentPO> JSON 数组(不包裹 Resource)。
成功示例:
失败示例:
16. 根据微信部门 ID 查询部门¶
根据企业微信部门 ID 和域 ID 查询匹配的部门集合。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/queryByDomainAndWeixinDept/{domainId}(完整:<host>/usercenter/department/queryByDomainAndWeixinDept/{domainId}) - 鉴权:内部
- Tag:部门管理
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainId | path | string | 是 | 域 ID |
| weinxinDeptId | query | string | 是 | 微信部门 ID(参数名 weinxinDeptId 为源码原始拼写) |
请求示例¶
GET /usercenter/department/queryByDomainAndWeixinDept/__DMN001?weinxinDeptId=wx1001 HTTP/1.1
systemToken: <系统间 JWT>
响应¶
结构:成功为 Collection<DepartmentPO> JSON 数组(不包裹 Resource)。
成功示例:
失败示例:
17. 根据钉钉部门 ID 查询部门¶
根据钉钉部门 ID 和域 ID 查询匹配的部门集合。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/queryByDomainAndDingdingDept/{domainId}(完整:<host>/usercenter/department/queryByDomainAndDingdingDept/{domainId}) - 鉴权:内部
- Tag:部门管理
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainId | path | string | 是 | 域 ID |
| dingdingDeptId | query | string | 是 | 钉钉部门 ID |
请求示例¶
GET /usercenter/department/queryByDomainAndDingdingDept/__DMN001?dingdingDeptId=dd1001 HTTP/1.1
systemToken: <系统间 JWT>
响应¶
结构:成功为 Collection<DepartmentPO> JSON 数组(不包裹 Resource)。
成功示例:
[
{ "id": "__DEPT001", "name": "研发中心", "dingdingDeptId": "dd1001", "domain": { "id": "__DMN001" } }
]
失败示例:
18. 根据部门名称模糊查询¶
根据域 ID 和部门名称(模糊匹配)查询部门集合。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/queryByDomainLikeName/{domainId}(完整:<host>/usercenter/department/queryByDomainLikeName/{domainId}) - 鉴权:内部
- Tag:部门管理
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainId | path | string | 是 | 域 ID |
| name | query | string | 是 | 部门名称(模糊匹配) |
请求示例¶
响应¶
结构:成功为 Collection<DepartmentPO> JSON 数组(不包裹 Resource)。
成功示例:
[
{ "id": "__DEPT001", "name": "研发中心", "domain": { "id": "__DMN001" } },
{ "id": "__DEPT002", "name": "研发一部", "domain": { "id": "__DMN001" } }
]
失败示例:
19. 根据有效状态查询部门¶
根据域 ID 和有效状态查询该域下的部门集合。
- 接口类型:REST 资源
- 请求方式:
GET - 请求路径:
/queryByDomainAndValid/{domainId}(完整:<host>/usercenter/department/queryByDomainAndValid/{domainId}) - 鉴权:内部
- Tag:部门管理
请求参数¶
| 参数名 | 位置 | 类型 | 必填 | 说明 |
|---|---|---|---|---|
| domainId | path | string | 是 | 域 ID |
| valid | query | int | 是 | 有效状态(0=无效,1=有效) |
请求示例¶
响应¶
结构:成功为 Collection<DepartmentPO> JSON 数组(不包裹 Resource)。
成功示例:
失败示例: