在 b369527 之上增量移植 FL2.0 后端能力,不改既有线级停发/指派预览/流程图入口:
- 部门目录:FlowDepartmentController(/admin/department/{groups,options,resolve,members})
+ UserBaseDepartmentDirectory(先按会话校域解析引用,再读成员;目录不可用 fail-closed)
- 退回重提 D14:POST /oapi/flow/instance/{instanceId}/resubmit,仅原提交人 CAS 路径放行,
OAPI 侧 submitterId 路径继续 fail-closed
- 授权管理:/api/flow/admin/usage-grant/{schoolList,summary}(校域取管理员会话,无 schId 入参)
- 来源主体:解析器派生 ub-app:{applicationInfo.id},不再读取 UserBase 的 sourcePrincipalId 字段
- 回调来源策略:SELF 身份强校验;NULL 来源不广播;复合幂等键 (event_id,reg_id)
- 测试夹具:许可/主体/开通桩按新契约修正,FlowEngineIT/FormalApplyCommandIT/
CallbackDispatchIT/OapiFlowContractIT 共 117 例在真实 MySQL 8 通过
不含:FlSourceAuthorizationTest(其断言的两个 Repository 派生方法属另一实现线)
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
package com.yunhai.flowcenter.controller.api;
|
||||
|
||||
import com.yunhai.flowcenter.service.FlowAdminGuard;
|
||||
import com.yunhai.flowcenter.service.UserBaseDepartmentDirectory;
|
||||
import com.yunhai.platform.openapi.base.model.DepartmentEntry;
|
||||
import com.yunhai.platform.openapi.base.model.DepartmentGroup;
|
||||
import com.yunhai.platform.openapi.base.model.DepartmentRef;
|
||||
import com.yunhai.platform.utils.model.BoaUser;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 部门目录读端点(C1/C4,2026-10-29):流程编辑器"选择部门"、候选人预览与已存引用的名称回显
|
||||
* 统一以 UserBase 新部门目录为权威来源,不再读写 FL 本地科室。
|
||||
*
|
||||
* <p>校域一律由 {@link FlowAdminGuard#requireAdmin} 从 CAS 会话派生,前端没有可越界的 schId 入口;
|
||||
* 全部只读,不接受写操作,也不回落本地 {@code flw_dept}。</p>
|
||||
*/
|
||||
@RestController
|
||||
@RequestMapping("/api/flow/admin/department")
|
||||
@RequiredArgsConstructor
|
||||
public class FlowDepartmentController {
|
||||
|
||||
private final FlowAdminGuard adminGuard;
|
||||
private final UserBaseDepartmentDirectory directory;
|
||||
|
||||
/** 第一级「部门组」:系统组织(SYSTEM)+ 该校自定义分类(CUSTOM) */
|
||||
@GetMapping("/groups")
|
||||
public List<DepartmentGroup> groups(BoaUser user) {
|
||||
return directory.groups(adminGuard.requireAdmin(user, null));
|
||||
}
|
||||
|
||||
/**
|
||||
* 第二级可选部门。
|
||||
*
|
||||
* @param type SYSTEM / CUSTOM(可空=两类都返回)
|
||||
* @param categoryId 仅 CUSTOM 有效
|
||||
* @param withChildren 仅 SYSTEM 有效,true 时扁平带回下级(前端按 parentId 重建层级)
|
||||
*/
|
||||
@GetMapping("/options")
|
||||
public List<DepartmentEntry> options(BoaUser user,
|
||||
@RequestParam(value = "type", required = false) String type,
|
||||
@RequestParam(value = "categoryId", required = false) Integer categoryId,
|
||||
@RequestParam(value = "withChildren", required = false) Boolean withChildren) {
|
||||
return directory.options(adminGuard.requireAdmin(user, null), type, categoryId, withChildren);
|
||||
}
|
||||
|
||||
/**
|
||||
* 已持久化引用的名称/状态回显(含停用与软删,走 UserBase 的 resolve-batch 历史口径)。
|
||||
* 编辑已有流程时用,避免"停用部门"在编辑器里显示成空白。
|
||||
*/
|
||||
@GetMapping("/resolve")
|
||||
public List<DepartmentEntry> resolve(BoaUser user,
|
||||
@RequestParam(value = "type", required = false) String type,
|
||||
@RequestParam(value = "departmentId", required = false) Integer departmentId) {
|
||||
Long schId = adminGuard.requireAdmin(user, null);
|
||||
List<DepartmentRef> refs = new ArrayList<>();
|
||||
if (departmentId != null) {
|
||||
refs.add(new DepartmentRef(schId.intValue(), type, departmentId));
|
||||
}
|
||||
return directory.resolve(schId, refs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 部门成员预览(C4:只读预览,不是发起授权)。
|
||||
*
|
||||
* @param scope select(缺省,新指派严档)/ history(既有实例历史解析宽档)
|
||||
*/
|
||||
@GetMapping("/members")
|
||||
public List<BoaUser> members(BoaUser user,
|
||||
@RequestParam("type") String type,
|
||||
@RequestParam("departmentId") Integer departmentId,
|
||||
@RequestParam(value = "scope", required = false) String scope) {
|
||||
Long school = adminGuard.requireAdmin(user, null);
|
||||
return directory.membersAtSchool(school, type, departmentId, scope);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user