139 lines
5.7 KiB
Java
139 lines
5.7 KiB
Java
package com.yunhai.userbase.controller.oapi;
|
|
|
|
import com.yunhai.platform.utils.model.BoaGroup;
|
|
import com.yunhai.platform.utils.model.BoaModule;
|
|
import com.yunhai.platform.utils.model.BoaUser;
|
|
import com.yunhai.userbase.config.Config;
|
|
import com.yunhai.userbase.model.groupauthz.UserPermissionAppVo;
|
|
import com.yunhai.userbase.model.groupauthz.UserPermissionCategoryVo;
|
|
import com.yunhai.userbase.model.groupauthz.UserPermissionModuleVo;
|
|
import com.yunhai.userbase.service.IGroupAuthzService;
|
|
import com.yunhai.userbase.service.UserCenterService;
|
|
import org.springframework.beans.BeanUtils;
|
|
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.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.List;
|
|
|
|
/**
|
|
* 用户中心开放接口:供其他业务服务经 yh-app-auth 签名调用({@code /oapi/user/...})。<br>
|
|
* <br>
|
|
* 路径复用 {@link Config#OPEN_API_PATH} 统一前缀,与基础平台 {@code DefaultUserCenterClient}
|
|
* 硬编码的契约严格一致:
|
|
* {@code GET /oapi/user/byId?id=}、{@code /byLoginName?loginName=}、{@code /byPhone?phone=}、
|
|
* {@code /oapi/user/modules?userId=&schId=}。<br>
|
|
* 接口本身不做验签——签名由 {@code OpenApiAuthEnforceConfiguration} 在过滤器层强制要求,
|
|
* 未带 {@code X-App-Key/X-Timestamp/X-Signature} 的请求直接 401。
|
|
*/
|
|
@RestController
|
|
@RequestMapping(Config.OPEN_API_PATH + "user/")
|
|
public class UserController {
|
|
|
|
@Autowired
|
|
private UserCenterService userCenterService;
|
|
|
|
@Autowired
|
|
private IGroupAuthzService groupAuthzService;
|
|
|
|
@GetMapping("byId")
|
|
public BoaUser byId(@RequestParam("id") Integer id) {
|
|
return userCenterService.getUserInfoWithDeptById(id);
|
|
}
|
|
|
|
@GetMapping("byLoginName")
|
|
public BoaUser byLoginName(@RequestParam("loginName") String loginName) {
|
|
if (loginName == null || loginName.trim().isEmpty()) {
|
|
return null;
|
|
}
|
|
return userCenterService.getUserInfoWithDeptByAccount(loginName);
|
|
}
|
|
|
|
@GetMapping("byPhone")
|
|
public BoaUser byPhone(@RequestParam("phone") String phone) {
|
|
if (phone == null || phone.trim().isEmpty()) {
|
|
return null;
|
|
}
|
|
return userCenterService.getUserInfoWithDeptByPhone(phone);
|
|
}
|
|
|
|
/**
|
|
* 查询用户在指定学校下的已授权模块列表。<br>
|
|
* 若 {@code schId} 为 null 时,自动取用户的主学校;若仍无主学校信息,退化为取用户主归属组(groups 第 0 个)。
|
|
*
|
|
* @param userId 用户ID(必填)
|
|
* @param schId 学校ID/组ID(可选;为 null 时按上述规则推断)
|
|
* @return 扁平化的已授权模块列表(含基础平台统一 BoaModule 模型);无权限时返回空列表
|
|
*/
|
|
@GetMapping("modules")
|
|
public List<BoaModule> modules(@RequestParam("userId") Integer userId,
|
|
@RequestParam(value = "schId", required = false) Integer schId) {
|
|
if (userId == null) {
|
|
return Collections.emptyList();
|
|
}
|
|
Integer effectiveGroupId = resolveEffectiveGroupId(userId, schId);
|
|
// 注意:超管即使没有学校/归属组,service.findUserPermissionTree 内部也会走超管短路返回全部权限,
|
|
// 因此这里不能因 effectiveGroupId 为 null 直接返回空,否则超管在 oapi/user/modules 永远拿不到权限;
|
|
// 普通用户无组/无学校时,findUserPermissionTree 同样会返回空列表,行为一致。
|
|
List<UserPermissionCategoryVo> tree = groupAuthzService.findUserPermissionTree(effectiveGroupId, userId);
|
|
if (tree == null || tree.isEmpty()) {
|
|
return Collections.emptyList();
|
|
}
|
|
List<BoaModule> result = new ArrayList<>();
|
|
for (UserPermissionCategoryVo category : tree) {
|
|
if (category.getApps() == null)
|
|
continue;
|
|
for (UserPermissionAppVo appVo : category.getApps()) {
|
|
String icon = appVo.getPcIcon();
|
|
collectModules(appVo.getModules(), icon, result);
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* 递归收集已授权模块树到扁平列表,并把应用 PC 图标作为模块的 icon 兜底(BoaModule.icon)。
|
|
*/
|
|
private void collectModules(List<UserPermissionModuleVo> modules,
|
|
String appIcon,
|
|
List<BoaModule> collector) {
|
|
if (modules == null || modules.isEmpty()) {
|
|
return;
|
|
}
|
|
for (UserPermissionModuleVo m : modules) {
|
|
BoaModule bm = new BoaModule();
|
|
BeanUtils.copyProperties(m, bm);
|
|
bm.setIcon(appIcon);
|
|
collector.add(bm);
|
|
collectModules(m.getChildren(), appIcon, collector);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 按「schId 为空时」解析出用户主学校/主组作为模块查询的上下文组ID。
|
|
*/
|
|
private Integer resolveEffectiveGroupId(Integer userId, Integer schId) {
|
|
if (schId != null) {
|
|
return schId;
|
|
}
|
|
BoaUser boa = userCenterService.getUserInfoWithDeptById(userId);
|
|
if (boa == null) {
|
|
return null;
|
|
}
|
|
BoaGroup school = boa.getSchool();
|
|
if (school != null && school.getId() != null) {
|
|
return school.getId();
|
|
}
|
|
List<BoaGroup> groups = boa.getGroups();
|
|
if (groups != null && !groups.isEmpty()) {
|
|
BoaGroup main = groups.get(0);
|
|
return main == null ? null : main.getId();
|
|
}
|
|
return null;
|
|
}
|
|
}
|