瀏覽代碼

人脸照片功能代码上传

huzhe 1 年之前
父節點
當前提交
554df30765

+ 30 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/utils/file/FileUtils.java

@@ -1,12 +1,16 @@
 package org.dromara.common.core.utils.file;
 
 import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.lang.UUID;
+import cn.hutool.core.util.StrUtil;
 import jakarta.servlet.http.HttpServletResponse;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 
 import java.net.URLEncoder;
 import java.nio.charset.StandardCharsets;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
 
 /**
  * 文件处理工具类
@@ -40,4 +44,30 @@ public class FileUtils extends FileUtil {
         String encode = URLEncoder.encode(s, StandardCharsets.UTF_8);
         return encode.replaceAll("\\+", "%20");
     }
+
+    /**
+     * 根据旧文件名生成新文件名,使用 uuid 生成
+     * @param oldName 旧文件名
+     * @return 新文件名
+     */
+    public static String getNewFileName(String oldName){
+
+        //1.旧名称判空(这里使用了 hutools)
+        if (StrUtil.isEmpty(oldName)){
+            return null;
+        }
+
+        //2.正则匹配获取文件后缀
+        Pattern sufixPattern = Pattern.compile(".*(\\..*)");
+        Matcher matcher = sufixPattern.matcher(oldName);
+
+        //3.UUID 生成文件新名称(这里使用了 hutools)
+        String newFileName = UUID.randomUUID().toString();
+        if (matcher.find()){
+            newFileName += matcher.group(1);
+        }
+
+        //4.返回新名称
+        return newFileName;
+    }
 }

+ 5 - 0
ruoyi-common/ruoyi-common-web/src/main/java/org/dromara/common/web/config/ResourcesConfig.java

@@ -1,6 +1,7 @@
 package org.dromara.common.web.config;
 
 import org.dromara.common.web.handler.GlobalExceptionHandler;
+import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.autoconfigure.AutoConfiguration;
 import org.springframework.context.annotation.Bean;
 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
@@ -15,6 +16,8 @@ import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 @AutoConfiguration
 public class ResourcesConfig implements WebMvcConfigurer {
 
+    @Value("${upload.upload-path}/")
+    private String uploadPath;
     @Override
     public void addInterceptors(InterceptorRegistry registry) {
 
@@ -22,6 +25,8 @@ public class ResourcesConfig implements WebMvcConfigurer {
 
     @Override
     public void addResourceHandlers(ResourceHandlerRegistry registry) {
+        registry.addResourceHandler("/upload/**").addResourceLocations("file:" + uploadPath);
+        WebMvcConfigurer.super.addResourceHandlers(registry);
     }
 
     /**

+ 71 - 0
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/payment/controller/PtUserAccountController.java

@@ -1,7 +1,13 @@
 package org.dromara.backstage.payment.controller;
 
+import java.io.File;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
 import java.util.List;
 
+import cn.hutool.core.io.FileUtil;
 import cn.hutool.core.lang.tree.Tree;
 import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
@@ -17,8 +23,13 @@ import org.dromara.backstage.payment.domain.vo.PtUserAccount4SelectVo;
 import org.dromara.backstage.payment.domain.vo.PtUserAccountInfoVo;
 import org.dromara.backstage.payment.service.IPtBagService;
 import org.dromara.common.core.utils.StreamUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.core.utils.file.FileUtils;
+import org.dromara.common.core.utils.file.MimeTypeUtils;
 import org.dromara.common.satoken.utils.LoginHelper;
 import org.dromara.system.api.RemoteDeptService;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.http.MediaType;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.validation.annotation.Validated;
 import org.dromara.common.idempotent.annotation.RepeatSubmit;
@@ -34,6 +45,7 @@ import org.dromara.backstage.payment.domain.vo.PtUserAccountVo;
 import org.dromara.backstage.payment.domain.bo.PtUserAccountBo;
 import org.dromara.backstage.payment.service.IPtUserAccountService;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.springframework.web.multipart.MultipartFile;
 
 /**
  * 一卡通账户
@@ -54,6 +66,21 @@ public class PtUserAccountController extends BaseController {
 
     @DubboReference
     private final RemoteDeptService remoteDeptService;
+
+    @Value("${upload.upload-path}/")
+    private String uploadPath;
+    @Value("${upload.image.user}/")
+    private String userPath;
+
+    /**
+     * 日期路径格式
+     */
+    private final String datePathFormat = "yyyy/MM/dd/";
+
+    /**
+     * 日期格式
+     */
+    private final SimpleDateFormat sdf = new SimpleDateFormat(datePathFormat);
     /**
      * 查询一卡通账户列表
      */
@@ -114,6 +141,50 @@ public class PtUserAccountController extends BaseController {
         return toAjax(ptUserAccountService.updateByBo(bo));
     }
 
+    /**
+     * 上传人脸照片
+     */
+    @SaCheckPermission("payment:ptUserAccount:edit")
+    @Log(title = "一卡通账户", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PostMapping(value = "/avatar", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+    public R<String> avatar(@RequestPart("file") MultipartFile file,
+                            @RequestParam("userId") Long userId) throws IOException {
+        if (!file.isEmpty()) {
+            String extension = FileUtil.extName(file.getOriginalFilename());
+            if (!StringUtils.equalsAnyIgnoreCase(extension, MimeTypeUtils.IMAGE_EXTENSION)) {
+                return R.fail("文件格式不正确,请上传" + Arrays.toString(MimeTypeUtils.IMAGE_EXTENSION) + "格式");
+            }
+            //1.获取日期字符串
+            String formatDate = sdf.format(new Date());
+
+            //2.获取新文件名
+            String newFileName = FileUtils.getNewFileName(file.getOriginalFilename());
+
+            //3.保存图片
+
+            //3.1 判断文件夹是否存在,不存在则创建
+            String imageDirPath = uploadPath + userPath + formatDate;
+            File imageDir = new File(imageDirPath);
+            if (!imageDir.exists()){
+                imageDir.mkdirs();
+            }
+
+            //3.2 拼接文件完整路径
+            String imageFilePath = imageDirPath + newFileName;
+
+            //3.3 保存照片
+            file.transferTo(new File(imageDir.getAbsoluteFile(), newFileName));
+
+            //4.保存图片路径到数据库
+            String photoUrl = userPath + formatDate + newFileName;
+            ptUserAccountService.updateByBo(PtUserAccountBo.builder().userId(userId).photo(photoUrl).build());
+
+            return R.ok("上传图片成功");
+        }
+        return R.fail("上传图片异常,请联系管理员");
+    }
+
     /**
      * 删除一卡通账户
      *

+ 28 - 1
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/payment/domain/bo/PtUserAccountBo.java

@@ -1,5 +1,6 @@
 package org.dromara.backstage.payment.domain.bo;
 
+import cn.hutool.core.util.DesensitizedUtil;
 import org.dromara.backstage.payment.domain.PtUserAccount;
 import org.dromara.common.mybatis.core.domain.BaseEntity;
 import org.dromara.common.core.validate.AddGroup;
@@ -198,5 +199,31 @@ public class PtUserAccountBo extends BaseEntity {
      */
     private String userType;
 
-
+    // 构建器类
+    public static class Builder {
+        private Long userId;
+        private String photo;
+
+        public Builder() {}
+
+        public Builder userId(Long userId) {
+            this.userId = userId;
+            return this;
+        }
+
+        public Builder photo(String photo) {
+            this.photo = photo;
+            return this;
+        }
+
+        public PtUserAccountBo build() {
+            PtUserAccountBo bo = new PtUserAccountBo();
+            bo.userId = this.userId;
+            bo.photo = this.photo;
+            return bo;
+        }
+    }
+    public static Builder builder() {
+        return new Builder();
+    }
 }

+ 1 - 1
ruoyi-modules/ruoyi-backstage/src/main/java/org/dromara/backstage/payment/service/impl/PtUserAccountServiceImpl.java

@@ -74,7 +74,7 @@ public class PtUserAccountServiceImpl implements IPtUserAccountService {
     public TableDataInfo<PtUserAccount4SelectVo> queryPageList4Select(PtUserAccountBo bo, PageQuery pageQuery) {
         // 方法1. 使用子查询,使得where 后 只有一个表(效率会低点) 方法2. 使用queryWrapper 自己指定字段,字段名带表别名
         QueryWrapper<PtUserAccount> wrapper = buildQueryWrapper(bo, "u");
-        wrapper.orderByAsc("u.dept_id").orderByAsc("u.real_name");
+        wrapper.orderByAsc("u.dept_id").orderByAsc("u.user_id");
         Page<PtUserAccount4SelectVo> result = baseMapper.customPageList(pageQuery.build(), wrapper);
         return TableDataInfo.build(result);
     }