RuoYi
2025-06-06 c86bfa92432bde3c1e3ea6891cf5c43c2e99cd3d
用户头像更换后移除旧头像文件
13 files modified
161 ■■■■ changed files
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteFileService.java 11 ●●●●● patch | view | raw | blame | history
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteFileFallbackFactory.java 6 ●●●●● patch | view | raw | blame | history
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/FileUtils.java 10 ●●●● patch | view | raw | blame | history
ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/controller/SysFileController.java 24 ●●●●● patch | view | raw | blame | history
ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/FastDfsSysFileServiceImpl.java 22 ●●●●● patch | view | raw | blame | history
ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/ISysFileService.java 8 ●●●●● patch | view | raw | blame | history
ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/LocalSysFileServiceImpl.java 15 ●●●●● patch | view | raw | blame | history
ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/MinioSysFileServiceImpl.java 22 ●●●●● patch | view | raw | blame | history
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysProfileController.java 11 ●●●● patch | view | raw | blame | history
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java 8 ●●●● patch | view | raw | blame | history
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java 8 ●●●● patch | view | raw | blame | history
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java 12 ●●●● patch | view | raw | blame | history
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml 4 ●●●● patch | view | raw | blame | history
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteFileService.java
@@ -2,7 +2,9 @@
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.core.constant.ServiceNameConstants;
@@ -26,4 +28,13 @@
     */
    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public R<SysFile> upload(@RequestPart(value = "file") MultipartFile file);
    /**
     * 删除文件
     *
     * @param fileUrl 文件地址
     * @return 结果
     */
    @DeleteMapping(value = "/delete", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
    public R<Boolean> delete(@RequestParam("fileUrl") String fileUrl);
}
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteFileFallbackFactory.java
@@ -30,6 +30,12 @@
            {
                return R.fail("上传文件失败:" + throwable.getMessage());
            }
            @Override
            public R<Boolean> delete(String fileUrl)
            {
                return R.fail("删除文件失败:" + throwable.getMessage());
            }
        };
    }
}
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/FileUtils.java
@@ -114,20 +114,20 @@
    }
    /**
     * 检查文件是否可下载
     * 校验文件路径合法性(安全性与扩展名)
     * 
     * @param resource 需要下载的文件
     * @param fileUrl 待校验的文件地址
     * @return true 正常 false 非法
     */
    public static boolean checkAllowDownload(String resource)
    public static boolean validateFilePath(String fileUrl)
    {
        // 禁止目录上跳级别
        if (StringUtils.contains(resource, ".."))
        if (StringUtils.contains(fileUrl, ".."))
        {
            return false;
        }
        // 判断是否在允许下载的文件规则内
        return ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource));
        return ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(fileUrl));
    }
    /**
ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/controller/SysFileController.java
@@ -3,10 +3,12 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.file.FileUtils;
import com.ruoyi.file.service.ISysFileService;
import com.ruoyi.system.api.domain.SysFile;
@@ -45,4 +47,26 @@
            return R.fail(e.getMessage());
        }
    }
    /**
     * 文件删除请求
     */
    @DeleteMapping("delete")
    public R<Boolean> delete(String fileUrl)
    {
        try
        {
            if (!FileUtils.validateFilePath(fileUrl))
            {
                throw new Exception(StringUtils.format("资源文件({})非法,不允许删除。 ", fileUrl));
            }
            sysFileService.deleteFile(fileUrl);
            return R.ok();
        }
        catch (Exception e)
        {
            log.error("删除文件失败", e);
            return R.fail(e.getMessage());
        }
    }
}
ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/FastDfsSysFileServiceImpl.java
@@ -1,11 +1,11 @@
package com.ruoyi.file.service;
import java.io.InputStream;
import com.alibaba.nacos.common.utils.IoUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.alibaba.nacos.common.utils.IoUtils;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.ruoyi.common.core.utils.file.FileTypeUtils;
@@ -53,4 +53,24 @@
            IoUtils.closeQuietly(inputStream);
        }
    }
    /**
     * FastDFS文件删除接口
     *
     * @param fileUrl 文件访问URL
     * @throws Exception
     */
    @Override
    public void deleteFile(String fileUrl) throws Exception
    {
        try
        {
            StorePath storePath = StorePath.parseFromUrl(fileUrl);
            storageClient.deleteFile(storePath.getGroup(), storePath.getPath());
        }
        catch (Exception e)
        {
            throw new RuntimeException("FastDfs Failed to delete file: ", e);
        }
    }
}
ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/ISysFileService.java
@@ -17,4 +17,12 @@
     * @throws Exception
     */
    public String uploadFile(MultipartFile file) throws Exception;
    /**
     * 文件删除接口
     *
     * @param fileUrl 文件访问URL
     * @throws Exception
     */
    public void deleteFile(String fileUrl) throws Exception;
}
ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/LocalSysFileServiceImpl.java
@@ -4,6 +4,8 @@
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.file.FileUtils;
import com.ruoyi.file.utils.FileUploadUtils;
/**
@@ -47,4 +49,17 @@
        String url = domain + localFilePrefix + name;
        return url;
    }
    /**
     * 本地文件删除接口
     *
     * @param fileUrl 文件访问URL
     * @throws Exception
     */
    @Override
    public void deleteFile(String fileUrl) throws Exception
    {
        String localFile = StringUtils.substringAfter(fileUrl, localFilePrefix);
        FileUtils.deleteFile(localFilePath + localFile);
    }
}
ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/MinioSysFileServiceImpl.java
@@ -5,10 +5,12 @@
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.alibaba.nacos.common.utils.IoUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.file.config.MinioConfig;
import com.ruoyi.file.utils.FileUploadUtils;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
/**
 * Minio 文件存储
@@ -57,4 +59,24 @@
            IoUtils.closeQuietly(inputStream);
        }
    }
    /**
     * Minio文件删除接口
     *
     * @param fileUrl 文件访问URL
     * @throws Exception
     */
    @Override
    public void deleteFile(String fileUrl) throws Exception
    {
        try
        {
            String minioFile = StringUtils.substringAfter(fileUrl, minioConfig.getBucketName());
            client.removeObject(RemoveObjectArgs.builder().bucket(minioConfig.getBucketName()).object(minioFile).build());
        }
        catch (Exception e)
        {
            throw new RuntimeException("Minio Failed to delete file", e);
        }
    }
}
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysProfileController.java
@@ -100,7 +100,7 @@
        String oldPassword = params.get("oldPassword");
        String newPassword = params.get("newPassword");
        LoginUser loginUser = SecurityUtils.getLoginUser();
        String userName = loginUser.getUsername();
        Long userId = loginUser.getUserid();
        String password = loginUser.getSysUser().getPassword();
        if (!SecurityUtils.matchesPassword(oldPassword, password))
        {
@@ -111,7 +111,7 @@
            return error("新密码不能与旧密码相同");
        }
        newPassword = SecurityUtils.encryptPassword(newPassword);
        if (userService.resetUserPwd(userName, newPassword) > 0)
        if (userService.resetUserPwd(userId, newPassword) > 0)
        {
            // 更新缓存用户密码&密码最后更新时间
            loginUser.getSysUser().setPwdUpdateDate(DateUtils.getNowDate());
@@ -143,8 +143,13 @@
                return error("文件服务异常,请联系管理员");
            }
            String url = fileResult.getData().getUrl();
            if (userService.updateUserAvatar(loginUser.getUsername(), url))
            if (userService.updateUserAvatar(loginUser.getUserid(), url))
            {
                String oldAvatarUrl = loginUser.getSysUser().getAvatar();
                if (StringUtils.isNotEmpty(oldAvatarUrl))
                {
                    remoteFileService.delete(oldAvatarUrl);
                }
                AjaxResult ajax = AjaxResult.success();
                ajax.put("imgUrl", url);
                // 更新缓存用户头像
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysUserMapper.java
@@ -70,20 +70,20 @@
    /**
     * 修改用户头像
     * 
     * @param userName 用户名
     * @param userId 用户ID
     * @param avatar 头像地址
     * @return 结果
     */
    public int updateUserAvatar(@Param("userName") String userName, @Param("avatar") String avatar);
    public int updateUserAvatar(@Param("userId") Long userId, @Param("avatar") String avatar);
    /**
     * 重置用户密码
     * 
     * @param userName 用户名
     * @param userId 用户ID
     * @param password 密码
     * @return 结果
     */
    public int resetUserPwd(@Param("userName") String userName, @Param("password") String password);
    public int resetUserPwd(@Param("userId") Long userId, @Param("password") String password);
    /**
     * 通过用户ID删除用户
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserService.java
@@ -155,11 +155,11 @@
    /**
     * 修改用户头像
     * 
     * @param userName 用户名
     * @param userId 用户ID
     * @param avatar 头像地址
     * @return 结果
     */
    public boolean updateUserAvatar(String userName, String avatar);
    public boolean updateUserAvatar(Long userId, String avatar);
    /**
     * 重置用户密码
@@ -172,11 +172,11 @@
    /**
     * 重置用户密码
     * 
     * @param userName 用户名
     * @param userId 用户ID
     * @param password 密码
     * @return 结果
     */
    public int resetUserPwd(String userName, String password);
    public int resetUserPwd(Long userId, String password);
    /**
     * 通过用户ID删除用户
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserServiceImpl.java
@@ -344,14 +344,14 @@
    /**
     * 修改用户头像
     * 
     * @param userName 用户名
     * @param userId 用户ID
     * @param avatar 头像地址
     * @return 结果
     */
    @Override
    public boolean updateUserAvatar(String userName, String avatar)
    public boolean updateUserAvatar(Long userId, String avatar)
    {
        return userMapper.updateUserAvatar(userName, avatar) > 0;
        return userMapper.updateUserAvatar(userId, avatar) > 0;
    }
    /**
@@ -369,14 +369,14 @@
    /**
     * 重置用户密码
     * 
     * @param userName 用户名
     * @param userId 用户ID
     * @param password 密码
     * @return 结果
     */
    @Override
    public int resetUserPwd(String userName, String password)
    public int resetUserPwd(Long userId, String password)
    {
        return userMapper.resetUserPwd(userName, password);
        return userMapper.resetUserPwd(userId, password);
    }
    /**
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysUserMapper.xml
@@ -202,11 +202,11 @@
    </update>
    
    <update id="updateUserAvatar" parameterType="SysUser">
         update sys_user set avatar = #{avatar} where user_name = #{userName}
         update sys_user set avatar = #{avatar} where user_id = #{userId}
    </update>
    
    <update id="resetUserPwd" parameterType="SysUser">
         update sys_user set pwd_update_date = sysdate(), password = #{password} where user_name = #{userName}
         update sys_user set pwd_update_date = sysdate(), password = #{password} where user_id = #{userId}
    </update>
    
    <delete id="deleteUserById" parameterType="Long">