@@ -49,4 +49,6 @@ yh:
|
||||
100617: 2a3b4c5d6e7f8091a2b3c4d5e6f70819
|
||||
|
||||
# 上传文件落容器卷,compose 里挂到宿主机 ./upload-data
|
||||
FILE_PATH: /data/upload
|
||||
# 键名必须是 file.upload-path(Java 端 @Value 按此读取;旧 FILE_PATH 顶层键不生效)
|
||||
file:
|
||||
upload-path: /data/upload
|
||||
|
||||
@@ -67,6 +67,7 @@ public class BaseApiController {
|
||||
public List<Map<String, Object>> getUserMod(BoaUser authUserWithDept) {
|
||||
Integer schId = authUserWithDept.getCurrentRole() != null
|
||||
? authUserWithDept.getCurrentRole().getSchId() : null;
|
||||
|
||||
return userCenterService.getUserModuleTree(authUserWithDept.getId(), schId);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 班级管理接口-教师(bschclass {@code /oapi/DbClass/GetSchteaList} 响应项)。
|
||||
* 班级管理接口-教师(userclass {@code /oapi/DbClass/GetSchteaList} 响应项)。
|
||||
* 对应 C# BestSchool.Entity.Model.SchTeaList。
|
||||
*/
|
||||
public class SchTeaList {
|
||||
|
||||
@@ -5,14 +5,14 @@ import com.yunhai.notice.model.SchTeaList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 班级管理(bschclass)开放接口客户端。
|
||||
* 基址取配置 {@code yh.open.bschclass},当前仅提供教师查询,后续班级/年级等接口按需追加。
|
||||
* 班级管理(userclass)开放接口客户端。
|
||||
* 基址取配置 {@code yh.open.userclass},当前仅提供教师查询,后续班级/年级等接口按需追加。
|
||||
*/
|
||||
public interface IClassService {
|
||||
|
||||
/**
|
||||
* 获取指定学校全部教师(含所属组 GroupIds)。
|
||||
* 对应 bschclass 开放接口:GET {@code {bschclass}/oapi/DbClass/GetSchteaList?Group={schId}}
|
||||
* 对应 userclass 开放接口:GET {@code {userclass}/oapi/DbClass/GetSchteaList?Group={schId}}
|
||||
*
|
||||
* @param schId 学校ID(即用户当前身份的 schId)
|
||||
*/
|
||||
|
||||
@@ -16,7 +16,7 @@ public interface IUserCenterService {
|
||||
* <p>组装规则(从原 BaseApiController.getSchoolAll 下沉):</p>
|
||||
* <ol>
|
||||
* <li>userbase 读取当前学校整棵组树(getGroupById(schId, withSub=true)),剔除学生组(type=8)及其子组;</li>
|
||||
* <li>bschclass 获取该校全部教师(/oapi/DbClass/GetSchteaList?Group=schId),按 GroupIds 挂到对应组下,
|
||||
* <li>userclass(班级管理)获取该校全部教师(/oapi/DbClass/GetSchteaList?Group=schId),按 GroupIds 挂到对应组下,
|
||||
* 无有效组(如所属组全被剔除)的教师兜底挂学校根节点;</li>
|
||||
* <li>扁平节点按 pid 递归组装为树(空组剔除,同 C# FormatUserTree)。</li>
|
||||
* </ol>
|
||||
|
||||
@@ -20,17 +20,17 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 班级管理(bschclass)开放接口实现。
|
||||
* bschclass 为开放接口(无需应用签名),使用独立 RestTemplate 直连。
|
||||
* 班级管理(userclass)开放接口实现。
|
||||
* userclass 为开放接口(无需应用签名),使用独立 RestTemplate 直连。
|
||||
*/
|
||||
@Service
|
||||
public class ClassService implements IClassService {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(ClassService.class);
|
||||
|
||||
/** 班级管理服务基址,如 http://base.yunhaixingtong.com/bschclass */
|
||||
@Value("${yh.open.bschclass:}")
|
||||
private String bschClassHost;
|
||||
/** 班级管理服务基址,如 http://base.yunhaixingtong.com/userclass */
|
||||
@Value("${yh.open.userclass:}")
|
||||
private String userClassHost;
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
|
||||
@@ -43,10 +43,10 @@ public class ClassService implements IClassService {
|
||||
|
||||
@Override
|
||||
public List<SchTeaList> getSchTeaList(int schId) {
|
||||
if (!StringUtils.hasText(bschClassHost)) {
|
||||
throw new BizException(ErrorCode.INTERNAL_SERVER_ERROR, "班级管理接口未配置(yh.open.bschclass)");
|
||||
if (!StringUtils.hasText(userClassHost)) {
|
||||
throw new BizException(ErrorCode.INTERNAL_SERVER_ERROR, "班级管理接口未配置(yh.open.userclass)");
|
||||
}
|
||||
String url = bschClassHost + "/oapi/DbClass/GetSchteaList?Group=" + schId;
|
||||
String url = userClassHost + "/oapi/DbClass/GetSchteaList?Group=" + schId;
|
||||
try {
|
||||
ResponseEntity<List<SchTeaList>> resp = restTemplate.exchange(
|
||||
url, HttpMethod.GET, null,
|
||||
|
||||
@@ -58,6 +58,15 @@ public class FileService implements IFileService {
|
||||
|
||||
private static final String DEFAULT_APP_TYPE = "notice";
|
||||
|
||||
/**
|
||||
* 解析存储绝对路径。uploadPath 需以绝对路径配置(生产容器内 /data/upload);
|
||||
* 若误配为相对路径,此处统一锚定到进程工作目录——否则 MultipartFile.transferTo
|
||||
* 会把相对目标解析到 Tomcat multipart 临时目录,与后续读取(按工作目录解析)分裂。
|
||||
*/
|
||||
private Path resolvePath(String relative) {
|
||||
return Paths.get(uploadPath, relative).toAbsolutePath().normalize();
|
||||
}
|
||||
|
||||
// ============================ 上传 ============================
|
||||
|
||||
@Override
|
||||
@@ -83,7 +92,7 @@ public class FileService implements IFileService {
|
||||
String relativePath = (appType == null ? DEFAULT_APP_TYPE : appType) + "/" + dateDir + "/" + savedName;
|
||||
|
||||
// 物理写入
|
||||
Path fullPath = Paths.get(uploadPath, relativePath);
|
||||
Path fullPath = resolvePath(relativePath);
|
||||
try {
|
||||
Files.createDirectories(fullPath.getParent());
|
||||
file.transferTo(fullPath.toFile());
|
||||
@@ -150,7 +159,7 @@ public class FileService implements IFileService {
|
||||
private void writeFile(Integer fileId, HttpServletResponse response, boolean inline) {
|
||||
UpFile file = upFileRepository.findById(fileId)
|
||||
.orElseThrow(() -> new BizException(ErrorCode.FORBIDDEN, "文件不存在: " + fileId));
|
||||
Path fullPath = Paths.get(uploadPath, file.getFileName());
|
||||
Path fullPath = resolvePath(file.getFileName());
|
||||
if (!Files.exists(fullPath)) {
|
||||
throw new BizException(ErrorCode.FORBIDDEN, "物理文件不存在: " + file.getFileName());
|
||||
}
|
||||
@@ -218,7 +227,7 @@ public class FileService implements IFileService {
|
||||
UpFile file = upFileRepository.findById(fileId)
|
||||
.orElseThrow(() -> new BizException(ErrorCode.FORBIDDEN, "文件不存在: " + fileId));
|
||||
// 删物理文件
|
||||
Path fullPath = Paths.get(uploadPath, file.getFileName());
|
||||
Path fullPath = resolvePath(file.getFileName());
|
||||
try {
|
||||
Files.deleteIfExists(fullPath);
|
||||
} catch (Exception e) {
|
||||
@@ -243,7 +252,7 @@ public class FileService implements IFileService {
|
||||
try (ZipOutputStream zos = new ZipOutputStream(response.getOutputStream())) {
|
||||
Set<String> used = new HashSet<>();
|
||||
for (UpFile f : files) {
|
||||
Path p = Paths.get(uploadPath, f.getFileName());
|
||||
Path p = resolvePath(f.getFileName());
|
||||
if (!Files.exists(p)) {
|
||||
log.warn("[downloadZip] 物理文件缺失,跳过: {}", f.getFileName());
|
||||
continue;
|
||||
|
||||
@@ -50,7 +50,7 @@ public class UserCenterService implements IUserCenterService {
|
||||
}
|
||||
flattenGroup(root, 0, flatNodes);
|
||||
|
||||
// 2. bschclass 全部教师,按 GroupIds 挂到对应组下;无有效组的兜底挂学校根节点
|
||||
// 2. userclass(班级管理)全部教师,按 GroupIds 挂到对应组下;无有效组的兜底挂学校根节点
|
||||
Set<Integer> treeGroupIds = new HashSet<>();
|
||||
for (Map<String, Object> node : flatNodes) {
|
||||
treeGroupIds.add((Integer) node.get("id"));
|
||||
|
||||
@@ -68,5 +68,5 @@ yh:
|
||||
enabled: true
|
||||
base-host: http://base.yunhaixingtong.com
|
||||
user-center-url: http://base.yunhaixingtong.com/userbase
|
||||
# 班级管理(bschclass)服务基址
|
||||
bschclass: http://base.yunhaixingtong.com/bschclass
|
||||
# 班级管理(userclass)服务基址(原 bschclass 路由已下线)
|
||||
userclass: http://base.yunhaixingtong.com/userclass
|
||||
|
||||
Reference in New Issue
Block a user