Ver Fonte

完善日志及系统配置及上传接口

tsurumure há 7 meses atrás
pai
commit
1ce44dc487

+ 6 - 3
db/sys_common.sql

@@ -9,14 +9,17 @@ CREATE TABLE `sys_common` (
     PRIMARY KEY (`id`),
     `id` BIGINT NOT NULL COMMENT 'ID',
     `name` VARCHAR(100) NOT NULL COMMENT '配置名称',
+    `description` VARCHAR(500) COMMENT '配置描述',
+    `tag` VARCHAR(100) COMMENT '配置键',
     `value` TEXT COMMENT '配置值',
     `value_type` VARCHAR(20) DEFAULT 'text' COMMENT '配置值类型 (Text, Textarea, Number, Radio, Checkbox, Select)',
     `value_option` TEXT COMMENT '配置值选项 (除文本框外必填)',
-    `tag` VARCHAR(20) NOT NULL COMMENT '标识',
+    `category` VARCHAR(20) NOT NULL COMMENT '分类',
     `sort` INT DEFAULT '1' COMMENT '排序',
     `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间'
 ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='系统配置表';
 
-INSERT INTO sys_common(id, name, value, value_type, value_option, tag, sort) VALUES
-    (1, '单文件上传大小限制(MB)', 100, 'Number', null, 'upload', 1)
+INSERT INTO sys_common(id, name, description, tag, value, value_type, value_option, category, sort) VALUES
+    (1, '单文件上传大小限制(MB)', null, 'UPLOAD_MAX_SIZE_MB', 100, 'Number', null, 'UPLOAD', 2),
+    (2, '是否启用文件MD5查重', '已存在的文件不再上传', 'UPLOAD_MD5_DUPLICATE', 1, 'Radio', null, 'UPLOAD', 1)
 ;

+ 39 - 1
src/main/java/com/backendsys/modules/common/aspect/SysLogAspect.java

@@ -11,8 +11,11 @@ import org.aspectj.lang.annotation.Pointcut;
 import org.aspectj.lang.reflect.MethodSignature;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
 
 import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.List;
 
 /**
  * 系统日志,切面处理类
@@ -61,7 +64,8 @@ public class SysLogAspect {
 
 		// 请求参数
 		Object[] args = joinPoint.getArgs();
-		String params = new Gson().toJson(args);
+//		String params = new Gson().toJson(args);
+		String params = getParams(joinPoint.getArgs());
 		sysLogEntity.setParams(params);
 
 		sysLogEntity.setIp(httpRequestUtil.getIpAddr());
@@ -70,4 +74,38 @@ public class SysLogAspect {
 		// 保存系统日志
 		sysLogDao.insert(sysLogEntity);
 	}
+
+	// 过滤 MultipartFile 类型
+	private String getParams(Object[] args) {
+		if (args == null || args.length == 0) {
+			return "";
+		}
+		List<Object> filteredArgs = new ArrayList<>();
+		for (Object arg : args) {
+			if (arg instanceof MultipartFile) {
+				// 对于 MultipartFile,只记录文件名和大小
+				MultipartFile file = (MultipartFile) arg;
+				filteredArgs.add(new MultipartFileInfo(file.getOriginalFilename(), file.getSize()));
+			} else {
+				filteredArgs.add(arg);
+			}
+		}
+		return new Gson().toJson(filteredArgs);
+	}
+
+	// 辅助类,用于记录 MultipartFile 的基本信息
+	private static class MultipartFileInfo {
+		private String originalFilename;
+		private long size;
+		public MultipartFileInfo(String originalFilename, long size) {
+			this.originalFilename = originalFilename;
+			this.size = size;
+		}
+		public String getOriginalFilename() {
+			return originalFilename;
+		}
+		public long getSize() {
+			return size;
+		}
+	}
 }

+ 0 - 1
src/main/java/com/backendsys/modules/system/controller/SysAuthController.java

@@ -36,7 +36,6 @@ public class SysAuthController {
     public void getCaptcha(HttpServletResponse response) throws IOException {
         sysAuthService.renderCaptcha(response);
     }
-    @SysLog("系统用户登录 (用户名)")
     @Operation(summary = "系统用户登录 (用户名)")
     @PostMapping(value = "/api/system/auth/login")
     public Result systemLogin(@Validated(SysAuth.Login.class) @RequestBody SysAuth sysAuth) {

+ 2 - 2
src/main/java/com/backendsys/modules/system/controller/SysCommonController.java

@@ -27,8 +27,8 @@ public class SysCommonController {
     @Operation(summary = "获取系统配置列表")
     @PreAuthorize("@sr.hasPermission('6.1')")
     @GetMapping("/api/system/common/getCommonList")
-    public Result getCommonList(String tag) {
-        return Result.success().put("data", sysCommonService.selectCommonList(tag));
+    public Result getCommonList(String category) {
+        return Result.success().put("data", sysCommonService.selectCommonList(category));
     }
 
     @Operation(summary = "获取系统配置详情")

+ 6 - 3
src/main/java/com/backendsys/modules/system/entity/SysCommon.java

@@ -24,13 +24,16 @@ public class SysCommon {
     @NotEmpty(message = "配置名称不能为空", groups = { Update.class })
     @Size(max = 20, message = "配置名称长度不超过 {max} 个字符", groups = { Update.class })
     private String name;
+    @Size(max = 500, message = "配置描述长度不超过 {max} 个字符", groups = { Update.class })
+    private String description;
+    private String tag;
     private String value;
     @RangeStringArray(message="配置值类型取值有误,范围应是(Text, Textarea, Number, Radio, Checkbox, Select)", value = { "Text", "Textarea", "Number", "Radio", "Checkbox", "Select" }, groups = { Update.class })
     private String value_type;
     private String value_option;
-    @NotEmpty(message = "标识不能为空", groups = { Update.class })
-    @Size(max = 20, message = "标识长度不超过 {max} 个字符", groups = { Update.class })
-    private String tag;
+    @NotEmpty(message = "分类不能为空", groups = { Update.class })
+    @Size(max = 20, message = "分类长度不超过 {max} 个字符", groups = { Update.class })
+    private String category;
     private Integer sort;
     private String create_time;
 

+ 2 - 2
src/main/java/com/backendsys/modules/system/service/SysCommonService.java

@@ -8,13 +8,13 @@ import java.util.Map;
 public interface SysCommonService {
 
     // 获取系统配置列表
-    PageEntity selectCommonList(String tag);
+    PageEntity selectCommonList(String category);
     // 获取系统配置详情
     SysCommon selectCommonDetail(SysCommon sysCommon);
     // 编辑系统配置
     Map<String, Object> updateCommon(SysCommon sysCommon);
 
     // 获取系统配置值
-    Object getCommonValue(Long id);
+    Object getCommonByTag(String tag);
 
 }

+ 6 - 7
src/main/java/com/backendsys/modules/system/service/impl/SysCommonServiceImpl.java

@@ -25,11 +25,11 @@ public class SysCommonServiceImpl implements SysCommonService {
      * 获得系统配置列表
      */
     @Override
-    public PageEntity selectCommonList(String tag) {
+    public PageEntity selectCommonList(String category) {
         PageUtils.startPage();  // 分页
 
         LambdaQueryWrapper<SysCommon> wrapper = new LambdaQueryWrapper<>();
-        if (StrUtil.isNotEmpty(tag)) wrapper.eq(SysCommon::getTag, tag);
+        if (StrUtil.isNotEmpty(category)) wrapper.eq(SysCommon::getCategory, category);
 
         wrapper.orderByDesc(SysCommon::getSort);
         List<SysCommon> list = sysCommonDao.selectList(wrapper);
@@ -51,11 +51,10 @@ public class SysCommonServiceImpl implements SysCommonService {
      */
     @Override
     public Map<String, Object> updateCommon(SysCommon sysCommon) {
-
         SysCommon detail = sysCommonDao.selectById(sysCommon.getId());
         if (detail == null) throw new CustException("系统配置不存在");
-
-        return Map.of("id", sysCommonDao.updateCommon(sysCommon));
+        sysCommonDao.updateCommon(sysCommon);
+        return Map.of("id", sysCommon.getId());
     }
 
 
@@ -63,9 +62,9 @@ public class SysCommonServiceImpl implements SysCommonService {
 
     // 获取系统配置值
     @Override
-    public Object getCommonValue(Long id) {
+    public Object getCommonByTag(String tag) {
         LambdaQueryWrapper<SysCommon> wrapper = new LambdaQueryWrapper<>();
-        wrapper.eq(SysCommon::getId, id);
+        wrapper.eq(SysCommon::getTag, tag);
         SysCommon sysCommon = sysCommonDao.selectOne(wrapper);
         return (sysCommon != null) ? sysCommon.getValue() : null;
     }

+ 83 - 45
src/main/java/com/backendsys/modules/upload/service/impl/SysUploadServiceImpl.java

@@ -1,5 +1,6 @@
 package com.backendsys.modules.upload.service.impl;
 
+import cn.hutool.core.convert.Convert;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.io.file.FileNameUtil;
 import cn.hutool.crypto.digest.DigestUtil;
@@ -7,6 +8,7 @@ import com.backendsys.exception.CustException;
 import com.backendsys.modules.common.config.security.utils.HttpRequestUtil;
 import com.backendsys.modules.sdk.douyincloud.tos.service.DouyinTosService;
 import com.backendsys.modules.sdk.tencentcloud.cos.service.TencentCosService;
+import com.backendsys.modules.system.service.SysCommonService;
 import com.backendsys.modules.upload.dao.SysUploadDao;
 import com.backendsys.modules.upload.entity.SysUpload;
 import com.backendsys.modules.upload.entity.SysUploadResult;
@@ -16,9 +18,7 @@ import com.backendsys.utils.response.PageInfoResult;
 import com.backendsys.utils.v2.PageUtils;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
-import com.qcloud.cos.model.UploadResult;
 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;
 
@@ -33,15 +33,16 @@ public class SysUploadServiceImpl implements SysUploadService {
     @Autowired
     private HttpRequestUtil httpRequestUtil;
 
-    @Autowired
-    private SysUploadDao sysUploadDao;
-
     @Autowired
     private TencentCosService tencentCosService;
-
     @Autowired
     private DouyinTosService douyinTosService;
 
+    @Autowired
+    private SysUploadDao sysUploadDao;
+    @Autowired
+    private SysCommonService sysCommonService;
+
     /**
      * 获取上传文件列表
      */
@@ -52,65 +53,102 @@ public class SysUploadServiceImpl implements SysUploadService {
         return new PageInfoResult(list).toEntity();
     }
 
+    // [方法] 上传事件
+    private SysUpload uploadEvent(MultipartFile multipartFile, Long category_id, Integer target) {
+        try {
+            SysUploadResult uploadResult = new SysUploadResult();
+
+            // target: 上传目标 (-1:本地, 1:腾讯云, 2:阿里云, 3.抖音云)
+            if (target == 1) {
+                // [腾讯云-上传对象]
+                uploadResult = tencentCosService.putObject(multipartFile, null);
+            }
+            if (target == 3) {
+                // [抖音云-上传对象]
+                uploadResult = douyinTosService.putObject(multipartFile, null);
+            }
+
+            // [新增] 上传文件记录
+            SysUpload sysUploadEntity = new SysUpload();
+            sysUploadEntity.setCategory_id(category_id);
+            sysUploadEntity.setRequest_id(uploadResult.getRequest_id());
+            sysUploadEntity.setUser_id(httpRequestUtil.getUserId());
+            sysUploadEntity.setObject_key(uploadResult.getKey());
+            sysUploadEntity.setName(FileNameUtil.getName(uploadResult.getKey()));
+            sysUploadEntity.setContent_type(multipartFile.getContentType());
+            sysUploadEntity.setUrl(uploadResult.getDomain() + "/" + uploadResult.getKey());
+            sysUploadEntity.setSize(multipartFile.getSize());
+            sysUploadEntity.setMd5(uploadResult.getE_tag().replace("\"", ""));
+            sysUploadEntity.setTarget(target);
+            sysUploadEntity.setCreate_time(DateUtil.now());
+            sysUploadEntity.setUpdate_time(DateUtil.now());
+            sysUploadDao.insert(sysUploadEntity);
+
+            return sysUploadEntity;
+
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
     /**
      * 上传文件 (单文件大小不超过 n)
      * - target: 上传目标 (-1:本地, 1:腾讯云, 2:阿里云, 3.抖音云)
      */
     @Override
     public SysUpload uploadSmall(MultipartFile multipartFile, Long category_id, Integer target) {
-        try {
 
-            if (target == null) throw new CustException("target 上传目标不能为空 (-1:本地, 1:腾讯云, 2:阿里云, 3.抖音云)");
+        if (target == null) throw new CustException("target 上传目标不能为空 (-1:本地, 1:腾讯云, 2:阿里云, 3.抖音云)");
 
-            // 判断文件是否超过大小
-            long MAX_SIZE = 100L * 1024 * 1024; // 100MB
-            if (multipartFile.getSize() > MAX_SIZE) {
-                throw new CustException("上传文件不能大于 " + MAX_SIZE / 1024 / 1024 + " MB,请使用大文件上传功能");
-            }
+        // [系统配置] 单文件上传大小限制(MB)
+        Long UPLOAD_MAX_SIZE_MB = Convert.toLong(sysCommonService.getCommonByTag("UPLOAD_MAX_SIZE_MB"));
+        System.out.println("[系统配置] 单文件上传大小限制(MB): " + UPLOAD_MAX_SIZE_MB);
 
-            // 根据文件MD5 判断是否上传过文件 (如果上传过,则仅更新记录,不再上传文件)
-            String md5 = DigestUtil.md5Hex(multipartFile.getInputStream());
-            SysUpload sysUploadEntity = sysUploadDao.selectOne(new LambdaQueryWrapper<SysUpload>().eq(SysUpload::getMd5, md5));
-            if (sysUploadEntity == null) {
+        // 判断文件是否超过大小
+        Long MAX_SIZE = UPLOAD_MAX_SIZE_MB * 1024 * 1024;
+        if (multipartFile.getSize() > MAX_SIZE) {
+            throw new CustException("上传文件不能大于 " + MAX_SIZE / 1024 / 1024 + " MB,请使用大文件上传功能");
+        }
 
-                SysUploadResult uploadResult = new SysUploadResult();
+        try {
 
-                // target: 上传目标 (-1:本地, 1:腾讯云, 2:阿里云, 3.抖音云)
-                if (target == 1) {
-                    // [腾讯云-上传对象]
-                    uploadResult = tencentCosService.putObject(multipartFile, null);
+            // [系统配置] 是否启用文件MD5查重
+            Boolean UPLOAD_MD5_DUPLICATE = Convert.toBool(sysCommonService.getCommonByTag("UPLOAD_MD5_DUPLICATE"));
+            System.out.println("[系统配置] 是否启用文件MD5查重: " + UPLOAD_MD5_DUPLICATE);
+            if (UPLOAD_MD5_DUPLICATE) {
+                // - 是
+                // 根据文件MD5 判断是否上传过文件
+                // - 如果上传过,则仅更新记录,不再上传文件,仅更新文件分类
+                // - 如果存在
+                String md5 = DigestUtil.md5Hex(multipartFile.getInputStream());
+                List<SysUpload> sysUploadEntityList = sysUploadDao.selectList(new LambdaQueryWrapper<SysUpload>().eq(SysUpload::getMd5, md5));
+                if (sysUploadEntityList != null && sysUploadEntityList.size() > 1) {
+                    throw new CustException("存在 " + sysUploadEntityList.size() + " 个相同Md5 (" + md5 + ") 的文件,请先排重后再上传");
                 }
-                if (target == 3) {
-                    // [抖音云-上传对象]
-                    uploadResult = douyinTosService.putObject(multipartFile, null);
+
+                SysUpload sysUploadEntity = (sysUploadEntityList != null) ? sysUploadEntityList.get(0) : null;
+                if (sysUploadEntity == null) {
+                    // [方法] 上传事件
+                    sysUploadEntity = uploadEvent(multipartFile, category_id, target);
+                } else {
+                    // [更新] 上传文件记录 (更换文件分类)
+                    sysUploadEntity.setCategory_id(category_id);
+                    sysUploadEntity.setUpdate_time(DateUtil.now());
+                    sysUploadDao.updateById(sysUploadEntity);
                 }
+                return sysUploadEntity;
 
-                // [新增] 上传文件记录
-                sysUploadEntity = new SysUpload();
-                sysUploadEntity.setCategory_id(category_id);
-                sysUploadEntity.setRequest_id(uploadResult.getRequest_id());
-                sysUploadEntity.setUser_id(httpRequestUtil.getUserId());
-                sysUploadEntity.setObject_key(uploadResult.getKey());
-                sysUploadEntity.setName(FileNameUtil.getName(uploadResult.getKey()));
-                sysUploadEntity.setContent_type(multipartFile.getContentType());
-                sysUploadEntity.setUrl(uploadResult.getDomain() + "/" + uploadResult.getKey());
-                sysUploadEntity.setSize(multipartFile.getSize());
-                sysUploadEntity.setMd5(uploadResult.getE_tag());
-                sysUploadEntity.setTarget(target);
-                sysUploadEntity.setCreate_time(DateUtil.now());
-                sysUploadEntity.setUpdate_time(DateUtil.now());
-                sysUploadDao.insert(sysUploadEntity);
             } else {
-                // [更新] 上传文件记录 (更换文件分类)
-                sysUploadEntity.setCategory_id(category_id);
-                sysUploadEntity.setUpdate_time(DateUtil.now());
-                sysUploadDao.updateById(sysUploadEntity);
+                // - 否
+                // [方法] 上传事件
+                SysUpload sysUploadEntity = uploadEvent(multipartFile, category_id, target);
+                return sysUploadEntity;
             }
-            return sysUploadEntity;
 
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
+
     }
 
     /**

+ 4 - 3
src/main/resources/mapper/system/SysCommonDao.xml

@@ -8,7 +8,7 @@
 <!--        COALESCE(value, '') value,-->
 <!--        value_type,-->
 <!--        COALESCE(value_option, '') value_option,-->
-<!--        tag,-->
+<!--        category,-->
 <!--        COALESCE(sort, '') sort,-->
 <!--        create_time-->
 <!--    </sql>-->
@@ -19,7 +19,7 @@
 <!--        <result property="value" column="value" />-->
 <!--        <result property="value_type" column="value_type" />-->
 <!--        <result property="value_option" column="value_option" />-->
-<!--        <result property="tag" column="tag" />-->
+<!--        <result property="category" column="category" />-->
 <!--        <result property="sort" column="sort" javaType="java.lang.Integer" />-->
 <!--        <result property="create_time" column="create_time" />-->
 <!--    </resultMap>-->
@@ -29,10 +29,11 @@
         UPDATE sys_common SET
         <trim suffixOverrides="," suffix=" ">
             <if test="name != null and name != ''">name = #{name},</if>
+            <if test="description != null and description != ''">description = #{description},</if>
             <if test="value != null and value != ''">value = #{value},</if>
             <if test="value_type != null and value_type != ''">value_type = #{value_type},</if>
             <if test="value_option != null and value_option != ''">value_option = #{value_option},</if>
-            <if test="tag != null and tag != ''">tag = #{tag},</if>
+            <if test="category != null and category != ''">category = #{category},</if>
             <if test="sort != null and sort != ''">sort = #{sort},</if>
         </trim>
         WHERE id = #{id};