diff --git a/src/main/java/com/yunhai/userbase/controller/oapi/GroupController.java b/src/main/java/com/yunhai/userbase/controller/oapi/GroupController.java
new file mode 100644
index 0000000..e9bb1e4
--- /dev/null
+++ b/src/main/java/com/yunhai/userbase/controller/oapi/GroupController.java
@@ -0,0 +1,63 @@
+package com.yunhai.userbase.controller.oapi;
+
+import com.yunhai.platform.utils.model.BoaGroup;
+import com.yunhai.userbase.config.Config;
+import com.yunhai.userbase.service.ISysGroupService;
+import org.springframework.beans.factory.annotation.Autowired;
+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.List;
+
+/**
+ * 组织架构开放接口:供其他业务服务经 yh-app-auth 签名调用({@code /oapi/group/...})。
+ *
+ * 路径复用 {@link Config#OPEN_API_PATH} 统一前缀,与基础平台 {@code DefaultUserCenterClient}
+ * 硬编码的契约严格一致:
+ * {@code GET /oapi/group/tree}、{@code /byId?groupId=&withSub=}、{@code /list?ids=&withSub=}。
+ * 接口本身不做验签——签名由 {@code OpenApiAuthEnforceConfiguration} 在过滤器层强制要求,
+ * 未带 {@code X-App-Key/X-Timestamp/X-Signature} 的请求直接 401。
+ */
+@RestController
+@RequestMapping(Config.OPEN_API_PATH + "group/")
+public class GroupController {
+
+ @Autowired
+ private ISysGroupService sysGroupService;
+
+ /**
+ * 获取整个平台的组树(从根节点开始,children 递归嵌套全部后代)。
+ */
+ @GetMapping("tree")
+ public BoaGroup tree() {
+ return sysGroupService.getGroups();
+ }
+
+ /**
+ * 获取单个组;withSub=true 时递归挂上全部子孙(整棵子树)。
+ *
+ * @param groupId 组ID(必填)
+ * @param withSub 是否展开子节点,缺省 false
+ * @return 组节点;不存在返回 null
+ */
+ @GetMapping("byId")
+ public BoaGroup byId(@RequestParam("groupId") Integer groupId,
+ @RequestParam(value = "withSub", required = false) Boolean withSub) {
+ return sysGroupService.getGroupById(groupId, withSub);
+ }
+
+ /**
+ * 批量获取组;ids 逗号/空格分隔,按入参顺序返回,不存在的跳过。
+ *
+ * @param ids 组ID列表(逗号/空格分隔)
+ * @param withSub 是否展开子节点,缺省 false
+ * @return 组节点列表(按入参顺序;不存在的跳过)
+ */
+ @GetMapping("list")
+ public List list(@RequestParam("ids") String ids,
+ @RequestParam(value = "withSub", required = false) Boolean withSub) {
+ return sysGroupService.getGroupList(ids, withSub);
+ }
+}