diff --git a/docker/application-prod.yml b/docker/application-prod.yml
index c1d799a..1717aaa 100644
--- a/docker/application-prod.yml
+++ b/docker/application-prod.yml
@@ -52,8 +52,6 @@ yh:
FILE_PATH: /data/upload
FILE_WEB_PATH: http://home.yunhaixingtong.com/userhome/upload/
UPLOAD_WEB_PATH_HTTP: http://home.yunhaixingtong.com/userhome/upload/file/
-# 学校配置接口基址(prod 由 Nacos 覆盖)
-SCH_CONF_URL: ""
logging:
level:
diff --git a/src/main/java/com/yunhai/userhome/config/WebMvcConfig.java b/src/main/java/com/yunhai/userhome/config/WebMvcConfig.java
index 1574063..a101bfc 100644
--- a/src/main/java/com/yunhai/userhome/config/WebMvcConfig.java
+++ b/src/main/java/com/yunhai/userhome/config/WebMvcConfig.java
@@ -42,5 +42,9 @@ public class WebMvcConfig implements WebMvcConfigurer {
// logo 子目录:/upload/logo/** → ${FILE_PATH}/logo/
registry.addResourceHandler("/upload/logo/**")
.addResourceLocations("file:" + basePath + "logo/");
+
+ // tempUpload 子目录(应用模板):/upload/tempUpload/** → ${FILE_PATH}/tempUpload/
+ registry.addResourceHandler("/upload/tempUpload/**")
+ .addResourceLocations("file:" + basePath + "tempUpload/");
}
}
diff --git a/src/main/java/com/yunhai/userhome/controller/api/AppSettingController.java b/src/main/java/com/yunhai/userhome/controller/api/AppSettingController.java
new file mode 100644
index 0000000..7dbdd43
--- /dev/null
+++ b/src/main/java/com/yunhai/userhome/controller/api/AppSettingController.java
@@ -0,0 +1,243 @@
+package com.yunhai.userhome.controller.api;
+
+import com.yunhai.platform.apistd.BizException;
+import com.yunhai.platform.utils.exception.ErrorCode;
+import com.yunhai.platform.utils.model.BoaUser;
+import com.yunhai.userhome.config.Config;
+import com.yunhai.userhome.entity.AppCategory;
+import com.yunhai.userhome.entity.UserCurrentRole;
+import com.yunhai.userhome.service.IAppCategoryService;
+import com.yunhai.userhome.service.IUserCurrentRoleService;
+import com.yunhai.userhome.utils.FileUtil;
+import com.yunhai.userhome.utils.OtherUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.core.io.InputStreamResource;
+import org.springframework.data.domain.Page;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
+import org.springframework.http.ResponseEntity;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Optional;
+import java.util.UUID;
+
+/**
+ * 应用设置控制器(自 systemsetting AppSettingController + SysController 迁移,1:1 对齐)。
+ *
+ *
与原版差异点:写操作(应用 CRUD / UpdateResDate / 模板上传保存)校验调用者
+ * 为超管(type==1)或校管理员(roleId∈{2,5,7})——原版任何登录用户可写,因新入口仅管理员可见,收紧。
+ * 查询(分页列表 / FindAppCategory / GetTempList / downloadTemp)登录即可。
+ */
+@RestController
+@RequestMapping(Config.API_PATH)
+public class AppSettingController {
+
+ @Value("${FILE_PATH:./upload/}")
+ private String FILE_PATH;
+
+ @Value("${FILE_WEB_PATH:}")
+ private String FILE_WEB_PATH;
+
+ @Autowired
+ private IAppCategoryService appCategoryService;
+
+ @Autowired
+ private IUserCurrentRoleService userCurrentRoleService;
+
+ // ==================== 应用类别 CRUD ====================
+
+ /** 新增/编辑应用(JSON body,1:1 对齐原 SaveAppCategory) */
+ @PostMapping(value = "SaveAppCategory", produces = "application/json")
+ public void saveAppCategory(BoaUser authUserWithDept, @RequestBody AppCategory appCategory) {
+ checkAdmin(authUserWithDept);
+ if (appCategory.getCDate() == null) appCategory.setCDate(new Date());
+ if (appCategory.getResDate() == null) appCategory.setResDate(new Date());
+ appCategory.setCId(authUserWithDept.getId());
+ appCategoryService.save(appCategory);
+ }
+
+ @PostMapping(value = "DelAppCategory", produces = "application/json")
+ public void delAppCategory(BoaUser authUserWithDept, Integer id) {
+ checkAdmin(authUserWithDept);
+ appCategoryService.deleteById(id);
+ }
+
+ @GetMapping(value = "GetAppCategoryList")
+ public Map getAppCategoryList(BoaUser authUserWithDept, Integer page, Integer count,
+ @RequestParam(value = "roleType") Integer roleType,
+ @RequestParam(value = "name", required = false) String name) {
+ Page data = appCategoryService.findPageList(page, count, roleType, name);
+ Map map = new HashMap();
+ map.put("total", data.getTotalElements());
+ map.put("list", data.getContent());
+ return map;
+ }
+
+ @GetMapping(value = "FindAppCategory")
+ public Optional findAppCategory(BoaUser authUserWithDept, Integer id) {
+ return appCategoryService.findById(id);
+ }
+
+ @PostMapping(value = "UpdateResDate", produces = "application/json")
+ public void updateResDate(BoaUser authUserWithDept, Integer id) {
+ checkAdmin(authUserWithDept);
+ appCategoryService.updateResDate(id);
+ }
+
+ // ==================== 模板管理(对齐原 SysController) ====================
+
+ /** 上传模板压缩包(zip/rar),解压覆盖到 tempUpload/<appModId>/,删除压缩包 */
+ @PostMapping(value = "tempUpload", produces = "application/json")
+ public void tempUpload(BoaUser authUserWithDept, @RequestParam("file") MultipartFile file, Integer appModId) {
+ checkAdmin(authUserWithDept);
+ if (file == null || file.isEmpty()) {
+ throw new BizException(ErrorCode.CUSTOM, "请选择上传文件");
+ }
+ String originalName = file.getOriginalFilename();
+ String ext = originalName == null ? "" : originalName.substring(originalName.lastIndexOf(".")).toLowerCase(Locale.ROOT);
+ if (!".zip".equals(ext) && !".rar".equals(ext)) {
+ throw new BizException(ErrorCode.CUSTOM, "仅支持 zip/rar 格式");
+ }
+ // 不走图片 5MB 校验(模板包允许更大,依赖 multipart 配置),存到 tempUpload 子目录
+ String uploadPath = FILE_PATH + "/tempUpload/";
+ File fl = new File(uploadPath);
+ if (!fl.exists()) fl.mkdirs();
+ String fileName = FileUtil.uploadFile(file, uploadPath);
+ String filePath = "/upload/tempUpload/" + fileName;
+
+ File unzipFiles = new File(FILE_PATH + "/tempUpload/" + appModId);
+ if (!unzipFiles.exists()) unzipFiles.mkdirs();
+ else FileUtil.delAllFile(unzipFiles.getPath());
+ File zipFile = new File(filePath.replace("/upload", FILE_PATH));
+ try {
+ FileUtil.zipDecompress(zipFile, unzipFiles);
+ } catch (Exception e) {
+ throw new BizException(ErrorCode.CUSTOM, e.getMessage());
+ } finally {
+ zipFile.delete();
+ }
+ }
+
+ /** 模板文件列表(name + 访问 path) */
+ @GetMapping(value = "GetTempList")
+ public List