org.projectlombok
lombok
diff --git a/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/exception/BadRequestException.java b/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/exception/BadRequestException.java
new file mode 100644
index 0000000..19266a7
--- /dev/null
+++ b/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/exception/BadRequestException.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2019-2025 Zheng Jie
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.fuyuanshen.common.core.exception;
+
+import lombok.Getter;
+import org.springframework.http.HttpStatus;
+
+import static org.springframework.http.HttpStatus.BAD_REQUEST;
+
+/**
+ * @author Zheng Jie
+ * @date 2018-11-23
+ * 统一异常处理
+ */
+@Getter
+public class BadRequestException extends RuntimeException{
+
+ private Integer status = BAD_REQUEST.value();
+
+ public BadRequestException(String msg){
+ super(msg);
+ }
+
+ public BadRequestException(HttpStatus status,String msg){
+ super(msg);
+ this.status = status.value();
+ }
+}
diff --git a/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/exception/EntityExistException.java b/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/exception/EntityExistException.java
new file mode 100644
index 0000000..648c078
--- /dev/null
+++ b/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/exception/EntityExistException.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2019-2025 Zheng Jie
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.fuyuanshen.common.core.exception;
+
+import org.springframework.util.StringUtils;
+
+/**
+ * @author Zheng Jie
+ * @date 2018-11-23
+ */
+public class EntityExistException extends RuntimeException {
+
+ public EntityExistException(Class clazz, String field, String val) {
+ super(EntityExistException.generateMessage(clazz.getSimpleName(), field, val));
+ }
+
+ private static String generateMessage1(String entity, String field, String val) {
+ return StringUtils.capitalize(entity) + " with " + field + " " + val + " existed";
+ }
+
+ private static String generateMessage(String entity, String field, String val) {
+ return field + " :" + val + " 已存在";
+ }
+
+}
\ No newline at end of file
diff --git a/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/exception/EntityNotFoundException.java b/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/exception/EntityNotFoundException.java
new file mode 100644
index 0000000..841dcb8
--- /dev/null
+++ b/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/exception/EntityNotFoundException.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2019-2025 Zheng Jie
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.fuyuanshen.common.core.exception;
+
+import org.springframework.util.StringUtils;
+
+/**
+ * @author Zheng Jie
+ * @date 2018-11-23
+ */
+public class EntityNotFoundException extends RuntimeException {
+
+ public EntityNotFoundException(Class clazz, String field, String val) {
+ super(EntityNotFoundException.generateMessage(clazz.getSimpleName(), field, val));
+ }
+
+ private static String generateMessage(String entity, String field, String val) {
+ return StringUtils.capitalize(entity)
+ + " with " + field + " "+ val + " does not exist";
+ }
+}
\ No newline at end of file
diff --git a/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/exception/handler/ApiError.java b/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/exception/handler/ApiError.java
new file mode 100644
index 0000000..9243976
--- /dev/null
+++ b/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/exception/handler/ApiError.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2019-2025 Zheng Jie
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.fuyuanshen.common.core.exception.handler;
+
+import lombok.Data;
+
+/**
+ * @author Zheng Jie
+ * @date 2018-11-23
+ */
+@Data
+public class ApiError {
+
+ private Integer status = 400;
+ private Long timestamp;
+ private String message;
+
+ private ApiError() {
+ timestamp = System.currentTimeMillis();
+ }
+
+ public static ApiError error(String message){
+ ApiError apiError = new ApiError();
+ apiError.setMessage(message);
+ return apiError;
+ }
+
+ public static ApiError error(Integer status, String message){
+ ApiError apiError = new ApiError();
+ apiError.setStatus(status);
+ apiError.setMessage(message);
+ return apiError;
+ }
+}
+
+
diff --git a/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/utils/CloseUtil.java b/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/utils/CloseUtil.java
new file mode 100644
index 0000000..809d77c
--- /dev/null
+++ b/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/utils/CloseUtil.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2019-2025 Zheng Jie
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.fuyuanshen.common.core.utils;
+
+import java.io.Closeable;
+
+/**
+ * @author Zheng Jie
+ * @description 用于关闭各种连接,缺啥补啥
+ * @date 2021-03-05
+ **/
+public class CloseUtil {
+
+ public static void close(Closeable closeable) {
+ if (null != closeable) {
+ try {
+ closeable.close();
+ } catch (Exception e) {
+ // 静默关闭
+ }
+ }
+ }
+
+ public static void close(AutoCloseable closeable) {
+ if (null != closeable) {
+ try {
+ closeable.close();
+ } catch (Exception e) {
+ // 静默关闭
+ }
+ }
+ }
+}
diff --git a/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/utils/file/FileUtil.java b/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/utils/file/FileUtil.java
new file mode 100644
index 0000000..cebd84c
--- /dev/null
+++ b/fys-common/fys-common-core/src/main/java/com/fuyuanshen/common/core/utils/file/FileUtil.java
@@ -0,0 +1,413 @@
+/*
+ * Copyright 2019-2025 Zheng Jie
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.fuyuanshen.common.core.utils.file;
+
+import cn.hutool.core.io.IoUtil;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.poi.excel.BigExcelWriter;
+import cn.hutool.poi.excel.ExcelUtil;
+import com.fuyuanshen.common.core.exception.BadRequestException;
+import com.fuyuanshen.common.core.utils.CloseUtil;
+import jakarta.servlet.ServletOutputStream;
+import jakarta.servlet.http.HttpServletRequest;
+import jakarta.servlet.http.HttpServletResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.poi.util.IOUtils;
+import org.apache.poi.xssf.streaming.SXSSFSheet;
+import org.springframework.web.multipart.MultipartFile;
+import java.io.*;
+import java.nio.file.Files;
+import java.security.MessageDigest;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/**
+ * File工具类,扩展 hutool 工具包
+ *
+ * @author Zheng Jie
+ * @date 2018-12-27
+ */
+@Slf4j
+public class FileUtil extends cn.hutool.core.io.FileUtil {
+
+ /**
+ * 系统临时目录
+ *
+ * windows 包含路径分割符,但Linux 不包含,
+ * 在windows \\==\ 前提下,
+ * 为安全起见 同意拼装 路径分割符,
+ *
+ * java.io.tmpdir
+ * windows : C:\Users/xxx\AppData\Local\Temp\
+ * linux: /temp
+ *
+ */
+ public static final String SYS_TEM_DIR = System.getProperty("java.io.tmpdir") + File.separator;
+ /**
+ * 定义GB的计算常量
+ */
+ private static final int GB = 1024 * 1024 * 1024;
+ /**
+ * 定义MB的计算常量
+ */
+ private static final int MB = 1024 * 1024;
+ /**
+ * 定义KB的计算常量
+ */
+ private static final int KB = 1024;
+
+ /**
+ * 格式化小数
+ */
+ private static final DecimalFormat DF = new DecimalFormat("0.00");
+
+ public static final String IMAGE = "图片";
+ public static final String TXT = "文档";
+ public static final String MUSIC = "音乐";
+ public static final String VIDEO = "视频";
+ public static final String OTHER = "其他";
+
+
+ /**
+ * MultipartFile转File
+ */
+ public static File toFile(MultipartFile multipartFile) {
+ // 获取文件名
+ String fileName = multipartFile.getOriginalFilename();
+ // 获取文件后缀
+ String prefix = "." + getExtensionName(fileName);
+ File file = null;
+ try {
+ // 用uuid作为文件名,防止生成的临时文件重复
+ file = new File(SYS_TEM_DIR + IdUtil.simpleUUID() + prefix);
+ // MultipartFile to File
+ multipartFile.transferTo(file);
+ } catch (IOException e) {
+ log.error(e.getMessage(), e);
+ }
+ return file;
+ }
+
+ /**
+ * 获取文件扩展名,不带 .
+ */
+ public static String getExtensionName(String filename) {
+ if ((filename != null) && (!filename.isEmpty())) {
+ int dot = filename.lastIndexOf('.');
+ if ((dot > -1) && (dot < (filename.length() - 1))) {
+ return filename.substring(dot + 1);
+ }
+ }
+ return filename;
+ }
+
+ /**
+ * Java文件操作 获取不带扩展名的文件名
+ */
+ public static String getFileNameNoEx(String filename) {
+ if ((filename != null) && (!filename.isEmpty())) {
+ int dot = filename.lastIndexOf('.');
+ if (dot > -1) {
+ return filename.substring(0, dot);
+ }
+ }
+ return filename;
+ }
+
+ /**
+ * 文件大小转换
+ */
+ public static String getSize(long size) {
+ String resultSize;
+ if (size / GB >= 1) {
+ //如果当前Byte的值大于等于1GB
+ resultSize = DF.format(size / (float) GB) + "GB ";
+ } else if (size / MB >= 1) {
+ //如果当前Byte的值大于等于1MB
+ resultSize = DF.format(size / (float) MB) + "MB ";
+ } else if (size / KB >= 1) {
+ //如果当前Byte的值大于等于1KB
+ resultSize = DF.format(size / (float) KB) + "KB ";
+ } else {
+ resultSize = size + "B ";
+ }
+ return resultSize;
+ }
+
+ /**
+ * inputStream 转 File
+ */
+ static File inputStreamToFile(InputStream ins, String name){
+ File file = new File(SYS_TEM_DIR + name);
+ if (file.exists()) {
+ return file;
+ }
+ OutputStream os = null;
+ try {
+ os = Files.newOutputStream(file.toPath());
+ int bytesRead;
+ int len = 8192;
+ byte[] buffer = new byte[len];
+ while ((bytesRead = ins.read(buffer, 0, len)) != -1) {
+ os.write(buffer, 0, bytesRead);
+ }
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ } finally {
+ CloseUtil.close(os);
+ CloseUtil.close(ins);
+ }
+ return file;
+ }
+
+ /**
+ * 将文件名解析成文件的上传路径
+ */
+ public static File upload(MultipartFile file, String filePath) {
+ Date date = new Date();
+ SimpleDateFormat format = new SimpleDateFormat("yyyyMMddhhmmssS");
+ // 过滤非法文件名
+ String name = getFileNameNoEx(verifyFilename(file.getOriginalFilename()));
+ String suffix = getExtensionName(file.getOriginalFilename());
+ String nowStr = "-" + format.format(date);
+ try {
+ String fileName = name + nowStr + "." + suffix;
+ String path = filePath + fileName;
+ // getCanonicalFile 可解析正确各种路径
+ File dest = new File(path).getCanonicalFile();
+ // 检测是否存在目录
+ if (!dest.getParentFile().exists()) {
+ if (!dest.getParentFile().mkdirs()) {
+ System.out.println("was not successful.");
+ }
+ }
+ // 文件写入
+ file.transferTo(dest);
+ return dest;
+ } catch (Exception e) {
+ log.error(e.getMessage(), e);
+ }
+ return null;
+ }
+
+ /**
+ * 导出excel
+ */
+ public static void downloadExcel(List
+