Просмотр исходного кода

Merge branch 'master' of http://121.40.98.15:3001/kym/charge-java

# Conflicts:
#	miniapp/src/main/java/com/kym/miniapp/controller/ChargerController.java
#	miniapp/src/main/java/com/kym/miniapp/utils/MybatisPlusGeneratorForMiniApp.java
skyline 2 лет назад
Родитель
Сommit
bb118adaf0

+ 29 - 0
common/src/main/java/com/kym/common/config/WebContextConfig.java

@@ -0,0 +1,29 @@
+package com.kym.common.config;
+
+import com.kym.common.filter.RequestLogFilter;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+
+
+
+
+
+
+
+
+
+@Configuration
+public class WebContextConfig {
+
+    @Bean
+    public FilterRegistrationBean<RequestLogFilter> addFilters() {
+        FilterRegistrationBean<RequestLogFilter> bean = new FilterRegistrationBean<>();
+        bean.setFilter(new RequestLogFilter());
+        bean.addUrlPatterns("/*");
+        bean.setName("request log filter");
+        bean.setOrder(0);
+        return bean;
+    }
+}

+ 6 - 0
common/src/main/java/com/kym/common/exception/BaseException.java

@@ -32,4 +32,10 @@ public class BaseException extends RuntimeException {
         // TODO: 2023-07-04 args cause 处理 
         // TODO: 2023-07-04 args cause 处理 
     }
     }
 
 
+    BaseException(int code,String message) {
+        this.code = code;
+        this.message = message;
+    }
+
+
 }
 }

+ 4 - 0
common/src/main/java/com/kym/common/exception/BusinessException.java

@@ -22,5 +22,9 @@ public class BusinessException extends BaseException {
     public BusinessException(IResponseCode responseEnum, Object[] args, String message, Throwable cause) {
     public BusinessException(IResponseCode responseEnum, Object[] args, String message, Throwable cause) {
         super(responseEnum, args, message, cause);
         super(responseEnum, args, message, cause);
     }
     }
+
+    public BusinessException(int code,String message) {
+        super(code,message);
+    }
 }
 }
 
 

+ 80 - 0
common/src/main/java/com/kym/common/filter/RequestLogFilter.java

@@ -0,0 +1,80 @@
+package com.kym.common.filter;
+
+import cn.hutool.core.lang.UUID;
+import com.kym.common.utils.IPUtils;
+import jakarta.servlet.Filter;
+import jakarta.servlet.FilterChain;
+import jakarta.servlet.FilterConfig;
+import jakarta.servlet.ServletException;
+import jakarta.servlet.ServletRequest;
+import jakarta.servlet.ServletResponse;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.slf4j.MDC;
+
+import java.io.IOException;
+
+
+
+
+
+
+
+
+
+
+/**
+ * 权限过滤器
+ *
+ * @author yaop
+ */
+public class RequestLogFilter implements Filter {
+
+    private Logger logger = LoggerFactory.getLogger(RequestLogFilter.class);
+
+    private String IP = "ip";
+    private String SEQ = "seq";
+
+
+    @Override
+    public void init(FilterConfig filterConfig) {
+        logger.info("RequestLogFilter init...");
+    }
+
+    @Override
+    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
+        HttpServletRequest request = (HttpServletRequest) servletRequest;
+        HttpServletResponse response = (HttpServletResponse) servletResponse;
+        response.setHeader("Access-Control-Allow-Origin", "*");
+        // 解决预请求(发送2次请求),此问题也可在 nginx 中作相似设置解决。
+        response.setHeader("Access-Control-Allow-Headers", "*");
+        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
+        response.setHeader("Access-Control-Max-Age", "3600");
+        //options请求是由浏览器发起确认是否访问可达,无数据传输
+        if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {
+            filterChain.doFilter(request, response);
+            return;
+        }
+        String ip = IPUtils.getIpAddr(request);
+        String seq = UUID.fastUUID().toString(true);
+        MDC.put(IP, ip);
+        MDC.put(SEQ, seq);
+
+        logger.info("request>>>uri:{}", request.getRequestURI());
+        try {
+            filterChain.doFilter(request, response);
+        } finally {
+            MDC.remove(IP);
+            MDC.remove(SEQ);
+        }
+    }
+
+
+    @Override
+    public void destroy() {
+        logger.info("RequestLogFilter destroy()...");
+    }
+
+}

+ 234 - 0
common/src/main/java/com/kym/common/utils/CommUtil.java

@@ -0,0 +1,234 @@
+package com.kym.common.utils;
+
+import com.kym.common.constant.ResponseEnum;
+import com.kym.common.exception.BusinessException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.lang.reflect.Array;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * 通用工具类
+ */
+public class CommUtil {
+
+    private static Logger logger = LoggerFactory.getLogger(CommUtil.class);
+
+    private CommUtil() {
+    }
+
+    /**
+     * 断言
+     *
+     * @param expected
+     * @param error
+     * @param code
+     */
+    public static void asserts(boolean expected, String error, int code) {
+        if (!expected) {
+            throw new BusinessException(code, error);
+        }
+    }
+
+    /**
+     * 断言
+     *
+     * @param expected
+     * @param error
+     */
+    public static void asserts(boolean expected, String error) {
+        if (!expected) {
+            throw new BusinessException(ResponseEnum.FAILED.getCode(), error);
+        }
+    }
+
+
+    /**
+     * 断言
+     *
+     * @param expected
+     * @param msgEnum
+     */
+    public static void asserts(boolean expected, ResponseEnum msgEnum) {
+        if (!expected) {
+            throw new BusinessException(msgEnum);
+        }
+    }
+
+    /**
+     * privatmitive
+     * 判断一个对象是否是基础数据类型或String
+     */
+    public static boolean isBasicType(Object obj) {
+        if (obj instanceof String) {
+            return true;
+        } else if (obj instanceof Integer) {
+            return true;
+        } else if (obj instanceof Short) {
+            return true;
+        } else if (obj instanceof Float) {
+            return true;
+        } else if (obj instanceof Double) {
+            return true;
+        } else if (obj instanceof Byte) {
+            return true;
+        } else if (obj instanceof Boolean) {
+            return true;
+        } else if (obj instanceof Long) {
+            return true;
+        } else {
+            return obj instanceof Character;
+        }
+    }
+
+    public static boolean isNotEmptyAndNull(Object value) {
+        if (null == value) {
+            return false;
+        }
+        if (isBasicType(value)) {
+            return !isEmptyOrNull(value.toString());
+        } else {
+            if (value instanceof Array) {
+                return Array.getLength(value) != 0;
+            } else if (value instanceof Collection) {
+                return !((Collection<?>) value).isEmpty();
+            } else if (value instanceof Map) {
+                return !((Map<?, ?>) value).isEmpty();
+            } else {
+                return !isEmptyOrNull(value.toString());
+            }
+        }
+    }
+
+    /**
+     * 判断集合是否为空
+     */
+    public static boolean isEmptyOrNull(Collection<?> collection) {
+        return null == collection || collection.isEmpty();
+    }
+
+
+    /**
+     * 判断集合是否为空
+     */
+    public static boolean isEmptyOrNull(List<Object> args) {
+        if (null == args || args.isEmpty()) {
+            return true;
+        }
+        for (Object arg : args) {
+            if (isEmptyOrNull(arg)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 判断Map是否为空
+     */
+    public static boolean isEmptyOrNull(Map<?, ?> map) {
+        return null == map || map.isEmpty();
+    }
+
+    /**
+     * 判断数组是否为空
+     */
+    public static boolean isEmptyOrNull(Object[] array) {
+        return null == array || array.length == 0 || isEmptyOrNull(array[0]);
+    }
+
+    /**
+     * 判断字符串是否为空
+     */
+    public static boolean isEmptyOrNull(String value) {
+        return null == value || value.length() == 0 || value.trim().length() == 0;
+    }
+
+    /**
+     * 判断对象是否为空
+     */
+    public static boolean isEmptyOrNull(Object value) {
+        if (null == value) {
+            return true;
+        }
+        if (isBasicType(value)) {
+            return isEmptyOrNull(value.toString());
+        } else {
+            if (value.getClass().isArray()) {
+                return Array.getLength(value) == 0;
+            } else if (value instanceof Collection) {
+                return ((Collection<?>) value).isEmpty();
+            } else if (value instanceof Map) {
+                return ((Map<?, ?>) value).isEmpty();
+            } else {
+                return isEmptyOrNull(value.toString());
+            }
+        }
+    }
+
+
+    /**
+     * 集合过滤空转List
+     *
+     * @param iterable
+     * @param <T>
+     * @return
+     */
+    public static <T> List<T> null2List(Iterable<T> iterable) {
+        List<T> list = new ArrayList<>();
+        if (isEmptyOrNull(iterable)) {
+            return list;
+        }
+
+        for (T next : iterable) {
+            if (!isEmptyOrNull(next)) {
+                list.add(next);
+            }
+        }
+
+        return list;
+    }
+
+    /**
+     * 判断是否为脚本类可执行文件
+     *
+     * @param suffix
+     * @return
+     */
+    public static boolean isExecutable(String suffix) {
+        if (isEmptyOrNull(suffix)) return false;
+        List<String> forbidSuffixs = List.of("sh", "bat", "exe", "msi", "py");
+        return forbidSuffixs.contains(suffix.toLowerCase());
+    }
+
+
+    /**
+     * 对象转Long
+     *
+     * @param s
+     * @return
+     */
+    public static Long null2Long(Object s) {
+        long v = 0L;
+        if (null != s) {
+            try {
+                v = Long.parseLong(s.toString());
+            } catch (Exception e) {
+                logger.error("null2Long error :{}", s);
+            }
+        }
+        return v;
+    }
+
+    public static String null2String(Object val) {
+        if(isEmptyOrNull(val)){
+            return "";
+        }
+        return val.toString().trim();
+    }
+}

+ 6 - 0
entity/src/main/java/com/kym/entity/common/SimpleVo.java

@@ -0,0 +1,6 @@
+package com.kym.entity.common;
+
+public class SimpleVo {
+    public Long id;
+    public String name;
+}

+ 69 - 0
entity/src/main/java/com/kym/entity/miniapp/Attachment.java

@@ -0,0 +1,69 @@
+package com.kym.entity.miniapp;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+/**
+ * <p>
+ * 附件
+ * </p>
+ *
+ * @author zuy
+ * @since 2023-08-12
+ */
+@Getter
+@Setter
+@TableName("t_attachment")
+public class Attachment implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * ID
+     */
+    private Long id;
+
+    /**
+     * uuid
+     */
+    private String uuid;
+
+    /**
+     * 文件名
+     */
+    private String name;
+
+    /**
+     * 文件大小
+     */
+    private Long size;
+
+    /**
+     * 上传人ID
+     */
+    private Long uploadBy;
+
+    /**
+     * 上传人
+     */
+    private String uploadName;
+
+    /**
+     * 是否删除
+     */
+    private Boolean isDelete;
+
+    /**
+     * 创建时间
+     */
+    private LocalDateTime createTime;
+
+    /**
+     * 更新时间
+     */
+    private LocalDateTime updateTime;
+}

+ 16 - 0
mapper/src/main/java/com/kym/mapper/miniapp/AttachmentMapper.java

@@ -0,0 +1,16 @@
+package com.kym.mapper.miniapp;
+
+import com.kym.entity.miniapp.Attachment;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ * 附件 Mapper 接口
+ * </p>
+ *
+ * @author zuy
+ * @since 2023-08-12
+ */
+public interface AttachmentMapper extends BaseMapper<Attachment> {
+
+}

+ 23 - 0
mapper/src/main/resources/mappers/miniapp/AttachmentMapper.xml

@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.kym.mapper.miniapp.AttachmentMapper">
+
+    <!-- 通用查询映射结果 -->
+    <resultMap id="BaseResultMap" type="com.kym.entity.miniapp.Attachment">
+        <result column="id" property="id" />
+        <result column="uuid" property="uuid" />
+        <result column="name" property="name" />
+        <result column="size" property="size" />
+        <result column="upload_by" property="uploadBy" />
+        <result column="upload_name" property="uploadName" />
+        <result column="is_delete" property="isDelete" />
+        <result column="create_time" property="createTime" />
+        <result column="update_time" property="updateTime" />
+    </resultMap>
+
+    <!-- 通用查询结果列 -->
+    <sql id="Base_Column_List">
+        id, uuid, name, size, upload_by, upload_name, is_delete, create_time, update_time
+    </sql>
+
+</mapper>

+ 18 - 0
miniapp/src/main/java/com/kym/miniapp/controller/AttachmentController.java

@@ -0,0 +1,18 @@
+package com.kym.miniapp.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * <p>
+ * 附件 前端控制器
+ * </p>
+ *
+ * @author zuy
+ * @since 2023-08-12
+ */
+@RestController
+@RequestMapping("/attachment")
+public class AttachmentController {
+
+}

+ 1 - 0
miniapp/src/main/java/com/kym/miniapp/controller/ChargerController.java

@@ -155,5 +155,6 @@ public class ChargerController {
     EnResponse notificationChargeOrderInfo(@RequestBody JSONObject json) {
     EnResponse notificationChargeOrderInfo(@RequestBody JSONObject json) {
         return new EnResponse(enNotifyService.handleNotificationChargeOrderInfo(json));
         return new EnResponse(enNotifyService.handleNotificationChargeOrderInfo(json));
     }
     }
+    
 
 
 }
 }

+ 26 - 1
miniapp/src/main/java/com/kym/miniapp/controller/FileController.java

@@ -1,14 +1,39 @@
 package com.kym.miniapp.controller;
 package com.kym.miniapp.controller;
 
 
+import cn.hutool.core.io.FileUtil;
+import com.kym.common.R;
+import com.kym.common.annotation.SysLog;
+import com.kym.common.utils.CommUtil;
+import com.kym.entity.miniapp.Attachment;
+import com.kym.service.miniapp.AttachmentService;
+import jakarta.annotation.Resource;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+
 
 
 /**
 /**
  * @author skyline
  * @author skyline
  * @description 文件上传
  * @description 文件上传
  * @date 2023-07-29 10:54
  * @date 2023-07-29 10:54
  */
  */
-@RestController("/api/file")
+@RestController
+@RequestMapping("/api/file")
 public class FileController {
 public class FileController {
 
 
+    @Resource
+    private AttachmentService attachmentService;
+
+    @SysLog("文件上传")
+    @PostMapping("/upload")
+    public R<?> upload(MultipartFile file) throws IOException {
+        var fileName = file.getOriginalFilename();
+        CommUtil.asserts(!CommUtil.isExecutable(FileUtil.getSuffix(fileName)),"上传文件类型不支持");
+        Attachment attachment = attachmentService.upload(file);
+        return R.success(attachment);
+    }
 
 
 }
 }

+ 6 - 0
miniapp/src/main/resources/application.yml

@@ -121,3 +121,9 @@ en-plus:
   # 最小充电余额(分)
   # 最小充电余额(分)
   charge-min-amount: 200
   charge-min-amount: 200
 
 
+#文件上传配置
+upload:
+  file:
+   storage: file_storage  #文件存放地址
+   size: 20  #最大上传Mb
+

+ 8 - 2
miniapp/src/main/resources/logback-spring.xml

@@ -4,7 +4,7 @@
     <!--引用默认日志配置-->
     <!--引用默认日志配置-->
     <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
     <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
     <!--使用默认的控制台日志输出实现-->
     <!--使用默认的控制台日志输出实现-->
-    <include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
+<!--    <include resource="org/springframework/boot/logging/logback/console-appender.xml"/>-->
     <!--应用名称-->
     <!--应用名称-->
     <springProperty scope="context" name="APP_NAME" source="spring.application.name" defaultValue="springBoot"/>
     <springProperty scope="context" name="APP_NAME" source="spring.application.name" defaultValue="springBoot"/>
     <!--日志文件保存路径-->
     <!--日志文件保存路径-->
@@ -15,6 +15,12 @@
     <!--是否开启LogStash插件内部日志-->
     <!--是否开启LogStash插件内部日志-->
     <!--    <springProperty name="ENABLE_INNER_LOG" scope="context" source="logstash.enableInnerLog" defaultValue="false"/>-->
     <!--    <springProperty name="ENABLE_INNER_LOG" scope="context" source="logstash.enableInnerLog" defaultValue="false"/>-->
 
 
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>%d{HH:mm:ss.SSS}|%thread|%-5level|%logger{36}|%X{ip}|%X{seq}|%msg%n</pattern>
+        </encoder>
+    </appender>
+
     <!--DEBUG日志输出到文件-->
     <!--DEBUG日志输出到文件-->
     <appender name="FILE_DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
     <appender name="FILE_DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
         <!--输出DEBUG以上级别日志-->
         <!--输出DEBUG以上级别日志-->
@@ -177,7 +183,7 @@
 <!--    </appender>-->
 <!--    </appender>-->
 
 
     <!--控制框架输出日志-->
     <!--控制框架输出日志-->
-    <logger name="org.slf4j" level="INFO"/>
+<!--    <logger name="org.slf4j" level="INFO"/>-->
     <logger name="springfox" level="INFO"/>
     <logger name="springfox" level="INFO"/>
     <logger name="io.swagger" level="INFO"/>
     <logger name="io.swagger" level="INFO"/>
     <logger name="org.springframework" level="INFO"/>
     <logger name="org.springframework" level="INFO"/>

+ 21 - 0
service/src/main/java/com/kym/service/miniapp/AttachmentService.java

@@ -0,0 +1,21 @@
+package com.kym.service.miniapp;
+
+import com.kym.entity.miniapp.Attachment;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+
+
+/**
+ * <p>
+ * 附件 服务类
+ * </p>
+ *
+ * @author zuy
+ * @since 2023-08-12
+ */
+public interface AttachmentService extends IService<Attachment> {
+
+    Attachment upload(MultipartFile file) throws IOException;
+}

+ 68 - 0
service/src/main/java/com/kym/service/miniapp/impl/AttachmentServiceImpl.java

@@ -0,0 +1,68 @@
+package com.kym.service.miniapp.impl;
+
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.lang.UUID;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.kym.common.utils.CommUtil;
+import com.kym.entity.miniapp.Attachment;
+import com.kym.mapper.miniapp.AttachmentMapper;
+import com.kym.service.miniapp.AttachmentService;
+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 java.io.File;
+import java.io.IOException;
+
+
+/**
+ * <p>
+ * 附件 服务实现类
+ * </p>
+ *
+ * @author zuy
+ * @since 2023-08-12
+ */
+@Service
+public class AttachmentServiceImpl extends ServiceImpl<AttachmentMapper, Attachment> implements AttachmentService {
+
+    @Value("${upload.file.storage}")
+    private String fileStoragePath;
+
+    @Value("${upload.file.size}")
+    private int fileSize;
+
+    @Autowired
+    private AttachmentMapper attachmentMapper;
+
+    @Override
+    public Attachment upload(MultipartFile file) throws IOException {
+        String fileName = file.getOriginalFilename();
+        StpUtil.checkLogin();
+        long size = file.getSize();
+        CommUtil.asserts((long) fileSize << 20 > size, "文件超出上传大小");
+        Long userId = CommUtil.null2Long(StpUtil.getSession().get("userId"));
+
+        Attachment attachment = new Attachment();
+        attachment.setName(fileName);
+        attachment.setSize(file.getSize());
+        attachment.setUuid(UUID.fastUUID().toString(true) + "." + FileUtil.getSuffix(fileName));
+        attachment.setUploadBy(userId);
+        attachment.setUploadName(CommUtil.null2String(StpUtil.getSession().get("username")));
+        attachment.setIsDelete(false);
+
+        String applicationPath = System.getProperty("user.dir");
+
+        File dir = new File(applicationPath,fileStoragePath);
+        if(!dir.exists()){
+            CommUtil.asserts(dir.mkdirs(),"文件上传异常");
+        }
+        File storeFile = new File(dir,attachment.getUuid());
+        file.transferTo(storeFile);
+
+        attachmentMapper.insert(attachment);
+        return attachment;
+    }
+}