ruoyi-admin/src/main/java/com/ruoyi/web/controller/common/CommonController.java
@@ -1,14 +1,26 @@ package com.ruoyi.web.controller.common; import java.io.File; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.websocket.server.PathParam; import com.ruoyi.common.annotation.Anonymous; import com.ruoyi.common.utils.RenamedMultipartFile; import com.ruoyi.common.utils.uuid.UUID; import com.ruoyi.service.DownLoadFileService; import lombok.Data; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -31,8 +43,7 @@ */ @RestController @RequestMapping("/common") public class CommonController { public class CommonController { private static final Logger log = LoggerFactory.getLogger(CommonController.class); @Autowired @@ -42,6 +53,9 @@ private DownLoadFileService downLoadFileService; private static final String FILE_DELIMETER = ","; private static final Pattern CHINESE_PATTERN = Pattern.compile("[\u4e00-\u9fa5]"); // @GetMapping("/downloadFile") // public void fileDownload(@PathParam("path") String path, HttpServletResponse response) @@ -66,8 +80,6 @@ // log.error("下载文件失败", e); // } // } // /** @@ -113,10 +125,8 @@ * 通用上传请求(单个) */ @PostMapping("/upload") public AjaxResult uploadFile(@RequestParam("uploadFile") MultipartFile file,String fname) throws Exception { try { public AjaxResult uploadFile(@RequestParam("uploadFile") MultipartFile file, String fname) throws Exception { try { // 上传文件路径 String filePath = RuoYiConfig.getUploadPath(); // 上传并返回新文件名称 @@ -134,12 +144,11 @@ ajax.put("msg","操作成功"); ajax.put("data",data); return ajax; } catch (Exception e) { } catch (Exception e) { return AjaxResult.error(e.getMessage()); } } /** * 通用上传请求(多个) @@ -190,16 +199,235 @@ } /** * 通用上传请求(多个) 将中文修改为其他 */ @PostMapping("/noChinese/uploads") public AjaxResult noChineseUploadFiles(@RequestParam("files") List<MultipartFile> files) throws Exception { //System.out.println("99999999999999999999999990000000000000000"); try { // 上传文件路径 String filePath = RuoYiConfig.getUploadPath(); List<String> urls = new ArrayList<String>(); List<String> fileNames = new ArrayList<String>(); List<String> newFileNames = new ArrayList<String>(); List<String> originalFilenames = new ArrayList<String>(); for (MultipartFile file : files) { originalFilenames.add(file.getOriginalFilename()); String safeFilename = generateSafeFilename(file.getOriginalFilename()); MultipartFile renamedFile = new RenamedMultipartFile(file, safeFilename); String lastName=""; String fileName = FileUploadUtils.upload(filePath, renamedFile, lastName); String url = serverConfig.getUrl() + fileName; urls.add(url); fileNames.add(fileName); newFileNames.add(FileUtils.getName(fileName)); } AjaxResult ajax = AjaxResult.success(); ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER)); ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER)); ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER)); ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER)); return ajax; } catch (Exception e) { return AjaxResult.error(e.getMessage()); } } /** * 生成安全文件名(只替换中文部分) */ private String generateSafeFilename(String originalName) { if (originalName == null) { return ""; } // 1. 获取文件扩展名 String extension = ""; int dotIndex = originalName.lastIndexOf('.'); if (dotIndex > 0) { extension = originalName.substring(dotIndex); originalName = originalName.substring(0, dotIndex); } // 2. 只替换中文部分 StringBuilder safeName = new StringBuilder(); Matcher matcher = CHINESE_PATTERN.matcher(originalName); int lastEnd = 0; while (matcher.find()) { // 添加非中文部分 safeName.append(originalName, lastEnd, matcher.start()); // 添加随机字符串替换中文 safeName.append(generateRandomString(4)); lastEnd = matcher.end(); } // 添加剩余部分 safeName.append(originalName.substring(lastEnd)); String noSpaceName = safeName.toString().replaceAll("\\s", ""); // 3. 添加扩展名 return noSpaceName + extension; } /** * 生成随机字符串(字母+数字) */ private String generateRandomString(int length) { String uuid = UUID.randomUUID().toString().replace("-", ""); return uuid.substring(0, Math.min(length, uuid.length())); } @PostMapping("/uploads1") public AjaxResult uploadFiles1(@RequestParam("files") List<MultipartFile> files) { try { String filePath = RuoYiConfig.getUploadPath(); List<String> urls = new ArrayList<>(); List<String> fileNames = new ArrayList<>(); List<String> newFileNames = new ArrayList<>(); List<String> originalFilenames = new ArrayList<>(); List<String> httpSafePaths = new ArrayList<>(); for (MultipartFile file : files) { // 1. 上传文件 String fileName = FileUploadUtils.upload(filePath, file, ""); String originalFilename = file.getOriginalFilename(); // 2. 获取HTTP安全路径 String httpSafePath = toHttpPath(fileName); // 3. 构建完整URL(确保有斜杠分隔) String baseUrl = serverConfig.getUrl(); if (!baseUrl.endsWith("/") && !httpSafePath.startsWith("/")) { baseUrl += "/"; } String url = baseUrl + httpSafePath; urls.add(url); fileNames.add(fileName); newFileNames.add(FileUtils.getName(fileName)); originalFilenames.add(originalFilename); httpSafePaths.add(httpSafePath); } AjaxResult ajax = AjaxResult.success(); ajax.put("urls", StringUtils.join(urls, FILE_DELIMETER)); ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMETER)); ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMETER)); ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMETER)); ajax.put("httpSafePaths", StringUtils.join(httpSafePaths, FILE_DELIMETER)); return ajax; } catch (Exception e) { return AjaxResult.error(e.getMessage()); } } /** * 将包含中文的文件路径转换为 HTTP 安全的 URL 路径 */ public String toHttpPath(String filePath) { try { // 1. 标准化路径 Path normalizedPath = Paths.get(filePath).normalize(); // 2. 统一使用正斜杠 String pathStr = normalizedPath.toString().replace("\\", "/"); // 3. 分割路径组件 String[] parts = pathStr.split("/"); StringBuilder encodedPath = new StringBuilder(); // 4. 对每个组件单独编码并处理空格 for (String part : parts) { if (!part.isEmpty()) { // 编码并替换空格为 %20 String encodedPart = URLEncoder.encode(part, StandardCharsets.UTF_8.name()) .replace("+", "%20"); encodedPath.append("/").append(encodedPart); } } // 5. 处理绝对路径和相对路径 return filePath.startsWith("/") || filePath.startsWith("\\") ? encodedPath.toString() : encodedPath.substring(1); } catch (UnsupportedEncodingException e) { throw new RuntimeException("UTF-8 encoding not supported", e); } } /** * 从 HTTP URL 路径还原原始中文路径 */ @PostMapping("/getFileName") public String extractFileName(@RequestBody String httpPath) { try { // 1. 处理空值 if (httpPath == null || httpPath.trim().isEmpty()) { return ""; } // 2. 移除URL协议、域名和查询参数 String pathOnly = httpPath; // 移除协议和域名 if (pathOnly.contains("://")) { pathOnly = pathOnly.substring(pathOnly.indexOf("://") + 3); pathOnly = pathOnly.substring(pathOnly.indexOf('/')); } // 移除查询参数(如 ?token=123) int queryStart = pathOnly.indexOf('?'); if (queryStart > 0) { pathOnly = pathOnly.substring(0, queryStart); } // 3. URL解码 String decodedPath = URLDecoder.decode(pathOnly, StandardCharsets.UTF_8.name()); // 4. 提取文件名(处理Windows路径) decodedPath = decodedPath.replace("\\", "/"); // 获取最后一个非空路径组件 int lastSlash = decodedPath.lastIndexOf('/'); String fileName = (lastSlash >= 0 && lastSlash < decodedPath.length() - 1) ? decodedPath.substring(lastSlash + 1) : decodedPath; // 5. 处理特殊情况(如结尾斜杠) if (fileName.isEmpty()) { // 尝试获取倒数第二个组件 int prevSlash = decodedPath.lastIndexOf('/', lastSlash - 1); if (prevSlash >= 0) { fileName = decodedPath.substring(prevSlash + 1, lastSlash); } } return fileName; } catch (UnsupportedEncodingException e) { throw new RuntimeException("UTF-8 encoding not supported", e); } } /** * 本地资源通用下载 */ @GetMapping("/download/resource") public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response) throws Exception { try { if (!FileUtils.checkAllowDownload(resource)) { throws Exception { try { if (!FileUtils.checkAllowDownload(resource)) { throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource)); } // 本地资源路径 @@ -211,10 +439,9 @@ response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); FileUtils.setAttachmentResponseHeader(response, downloadName); FileUtils.writeBytes(downloadPath, response.getOutputStream()); } catch (Exception e) { } catch (Exception e) { log.error("下载文件失败", e); } } } ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java
@@ -4,10 +4,7 @@ import java.time.LocalDateTime; import java.time.ZoneId; import java.time.temporal.ChronoUnit; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Set; import java.util.*; import com.ruoyi.common.annotation.Anonymous; import com.ruoyi.framework.web.domain.server.Sys; @@ -96,8 +93,8 @@ LocalDateTime startDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime(); long daysPassed = ChronoUnit.DAYS.between(startDateTime, LocalDateTime.now()); return AjaxResult.success("试用提醒:您还有 " + (7L - daysPassed) + " 天的试用天数"); }else return AjaxResult.success("尊敬的会员用户,您好!欢迎来到本嘟嘟家网"); return AjaxResult.success(daysPassed > 7 ? "您的试用期已经结束,请付费继续使用":"您还有 " + (7L - daysPassed) + " 天的试用天数"); }else return AjaxResult.success("尊敬的会员用户,您好!"); } ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysUserController.java
@@ -537,6 +537,8 @@ if(same){ zInfoUserService.setUserInfoSame(infoUser); marrySelfService.setMarryInfoSame(infoUser,marrySelf.getId()); } // 5.5.1 更新配偶关联信息 ruoyi-admin/src/main/java/com/ruoyi/web/controller/zhang/MarrySelfController.java
@@ -75,13 +75,19 @@ sysUser.setSex(marryInfoDto.getSpouseSex().equals("男") ? "0" : "1"); userService.updateUser(sysUser); } List<ZInfoUser> byUaidToFaid = zInfoUserService.findByUaidToFaid(infoBysysId.getUaid()); for (ZInfoUser zInfoUser1:byUaidToFaid){ marryInfoDto.setUid(zInfoUser1.getSysId()); marrySelfService.updateData(marryInfoDto); } }} catch (Exception e) { e.printStackTrace(); System.out.println("报错"+e.getMessage()); return AjaxResult.error("更新失败"); } return AjaxResult.success( marrySelfService.updateData(marryInfoDto)); return AjaxResult.success( ); } //导出 ruoyi-common/src/main/java/com/ruoyi/common/utils/RenamedMultipartFile.java
New file @@ -0,0 +1,57 @@ package com.ruoyi.common.utils; import java.io.File; import java.io.IOException; import java.io.InputStream; import org.springframework.web.multipart.MultipartFile; public class RenamedMultipartFile implements MultipartFile { private final MultipartFile originalFile; private final String newFilename; public RenamedMultipartFile(MultipartFile file, String newFilename) { this.originalFile = file; this.newFilename = newFilename; } @Override public String getName() { return originalFile.getName(); } @Override public String getOriginalFilename() { return newFilename; // 返回新文件名 } @Override public String getContentType() { return originalFile.getContentType(); } @Override public boolean isEmpty() { return originalFile.isEmpty(); } @Override public long getSize() { return originalFile.getSize(); } @Override public byte[] getBytes() throws IOException { return originalFile.getBytes(); } @Override public InputStream getInputStream() throws IOException { return originalFile.getInputStream(); } @Override public void transferTo(File dest) throws IOException, IllegalStateException { originalFile.transferTo(dest); } } zhang-content/src/main/java/com/ruoyi/domain/Physcial.java
@@ -32,7 +32,7 @@ */ @TableId(value = "id", type = IdType.AUTO) private Long id; private String fileName; /** * 年度报告 */ zhang-content/src/main/java/com/ruoyi/domain/TravelDetail.java
@@ -35,6 +35,8 @@ @TableId(value = "id", type = IdType.AUTO) private Long id; private String fileName; /** * 对应的统计表的id */ zhang-content/src/main/java/com/ruoyi/domain/ZIdea.java
@@ -28,6 +28,9 @@ @TableId(value = "id", type = IdType.AUTO) private Long id; private String fileName; private Long uid; @Excel(name = "时间",dateFormat = "yyyy-MM-dd") zhang-content/src/main/java/com/ruoyi/domain/ZProperty.java
@@ -28,6 +28,7 @@ @TableId(value = "id", type = IdType.AUTO) private Long id; private String fileName; /** * 本人id */ zhang-content/src/main/java/com/ruoyi/domain/ZSecret.java
@@ -32,6 +32,7 @@ private Long id; private Long userId; private String fileName; /** * 创建时间 zhang-content/src/main/java/com/ruoyi/domain/ZSelfNote.java
@@ -29,6 +29,9 @@ @TableId(value = "id", type = IdType.AUTO) private Long id; private String fileName; /** * 用户id */ zhang-content/src/main/java/com/ruoyi/domain/ZYearInfo.java
@@ -30,6 +30,8 @@ @TableId(value = "id", type = IdType.AUTO) private Long id; private String fileName; /** * 年度健康表id */ zhang-content/src/main/java/com/ruoyi/domain/ZfClean.java
@@ -28,6 +28,8 @@ @TableId(value = "id", type = IdType.AUTO) private Long id; private String fileName; /** * 0:保洁,1:收纳 */ zhang-content/src/main/java/com/ruoyi/domain/ZfCollection.java
@@ -31,6 +31,7 @@ @TableId(value = "id", type = IdType.AUTO) private Integer id; private String fileName; /** * 类别 */ zhang-content/src/main/java/com/ruoyi/domain/ZfContact.java
@@ -30,6 +30,8 @@ @TableId(value = "id", type = IdType.AUTO) private Long id; private String fileName; /** * 家人姓名 */ zhang-content/src/main/java/com/ruoyi/domain/ZfDoctor.java
@@ -30,6 +30,8 @@ @TableId(value = "id", type = IdType.AUTO) private Long id; private String fileName; /** * 病的类型 */ zhang-content/src/main/java/com/ruoyi/domain/ZfEconomy.java
@@ -31,6 +31,8 @@ @TableId(value = "id", type = IdType.AUTO) private Long id; private String fileName; /** * 0:基金、1:台账 */ zhang-content/src/main/java/com/ruoyi/domain/ZfEquipment.java
@@ -79,6 +79,8 @@ private String url; private String fileName; @Excel(name = "是否注销",readConverterExp = "0=正常,1=已注销") private Integer status; zhang-content/src/main/java/com/ruoyi/domain/ZfEvent.java
@@ -43,6 +43,8 @@ @Excel(name="参与本次大事的人物名字") private String people; private String fileName; /** * 地点 */ zhang-content/src/main/java/com/ruoyi/domain/ZfPet.java
@@ -31,6 +31,7 @@ @TableId(value = "id", type = IdType.AUTO) private String id; private String fileName; /** * 宠物号码 */ zhang-content/src/main/java/com/ruoyi/domain/ZfPetNote.java
@@ -30,6 +30,9 @@ @TableId(value = "id", type = IdType.AUTO) private Long id; private String fileName; /** * 宠物id */ zhang-content/src/main/java/com/ruoyi/domain/ZfProperty.java
@@ -30,6 +30,9 @@ @TableId(type = IdType.AUTO) private Integer id; private String fileName; /** 资产类型 */ @Excel(name = "资产类型") private String type; zhang-content/src/main/java/com/ruoyi/service/MarrySelfService.java
@@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.domain.MarrySelf; import com.ruoyi.domain.ZInfoUser; import com.ruoyi.domain.dto.MarryInfoDto; /** @@ -12,6 +13,9 @@ * @Version 1.0.0 **/ public interface MarrySelfService extends IService<MarrySelf> { void setMarryInfoSame(ZInfoUser zInfoUser, Long id); AjaxResult getInfo(); Boolean updateData(MarryInfoDto marryInfoDto); zhang-content/src/main/java/com/ruoyi/service/impl/MarrySelfServiceImpl.java
@@ -21,6 +21,7 @@ import javax.annotation.Resource; import java.util.List; import java.util.Objects; import java.util.stream.Collectors; /** @@ -41,6 +42,37 @@ // @Resource // MarrySelfService marrySelfService; @Override public void setMarryInfoSame(ZInfoUser zInfoUser,Long id){ List<ZInfoUser> byUaidToFaid = zInfoUserService.findByUaidToFaid(zInfoUser.getUaid()); List<Long> resultIds = byUaidToFaid.stream() .map(ZInfoUser::getSysId) .filter(sysId -> !Objects.equals(sysId, zInfoUser.getSysId())) .collect(Collectors.toList()); if (resultIds.size() != 0){ LambdaQueryWrapper<MarrySelf> marrySelfLQW = new LambdaQueryWrapper<>(); marrySelfLQW.eq(MarrySelf::getUid,resultIds.get(0)); MarrySelf myself = getOne(marrySelfLQW); MarrySelf newUser = new MarrySelf(); // 拷贝所有属性 org.springframework.beans.BeanUtils.copyProperties(myself, newUser); newUser.setUid(zInfoUser.getSysId()); newUser.setId(id); System.out.println("ddddd"+newUser); this.updateById(newUser); } } @Override