first commit

This commit is contained in:
2026-01-27 14:03:02 +08:00
commit f20694754f
805 changed files with 92805 additions and 0 deletions

42
fuint-framework/pom.xml Normal file
View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>fuint</artifactId>
<groupId>com.fuint</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>fuint-framework</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>com.fuint</groupId>
<artifactId>fuint-utils</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.fuint</groupId>
<artifactId>fuint-repository</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,11 @@
package com.fuint.framework;
/**
* Created by FSQ
* CopyRight https://www.fuint.cn
*/
public class FrameworkConstants {
public static final int HTTP_RESPONSE_CODE_SUCCESS = 200;
}

View File

@ -0,0 +1,16 @@
package com.fuint.framework.annoation;
import java.lang.annotation.*;
/**
* 操作日志记录注解
*
* Created by FSQ
* CopyRight https://www.fuint.cn
*/
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperationServiceLog {
String description() default "";
}

View File

@ -0,0 +1,65 @@
package com.fuint.framework.dto;
import java.io.OutputStream;
import java.util.Map;
/**
* 导出Excel文件DTO
*
* Created by FSQ
* CopyRight https://www.fuint.cn
*/
public class ExcelExportDto {
/**
* 模板文件名称
*/
private String srcTemplateFileName;
/**
* 模板文件所在resource路径
*/
private String srcPath;
/**
* 数据
*/
private Map dataMap;
/**
* 输出流
*/
private OutputStream out;
public String getSrcTemplateFileName() {
return srcTemplateFileName;
}
public void setSrcTemplateFileName(String srcTemplateFileName) {
this.srcTemplateFileName = srcTemplateFileName;
}
public Map getDataMap() {
return dataMap;
}
public void setDataMap(Map dataMap) {
this.dataMap = dataMap;
}
public OutputStream getOut() {
return out;
}
public void setOut(OutputStream out) {
this.out = out;
}
public String getSrcPath() {
return srcPath;
}
public void setSrcPath(String srcPath) {
this.srcPath = srcPath;
}
}

View File

@ -0,0 +1,71 @@
package com.fuint.framework.exception;
/**
* 业务检查异常
*
* Created by FSQ
* CopyRight https://www.fuint.cn
*/
public class BusinessCheckException extends Exception {
private static final long serialVersionUID = 1L;
private Throwable rootCause;
public BusinessCheckException(String arg0) {
super(arg0);
this.errorKey = arg0;
rootCause = this;
}
public BusinessCheckException() {
super();
}
public BusinessCheckException(String s, Throwable e) {
this(s);
if (e instanceof BusinessCheckException) {
rootCause = ((BusinessCheckException) e).rootCause;
} else {
rootCause = e;
}
}
public BusinessCheckException(Throwable e) {
this("", e);
}
public Throwable getRootCause() {
return rootCause;
}
private String errorKey;
public String getErrorKey() {
return errorKey;
}
private String[] errorParam;
private Object[] errorObjectParam;
public Object[] getErrorObjectParam() {
return errorObjectParam;
}
public void setErrorObjectParam(Object[] errorObjectParam) {
this.errorObjectParam = errorObjectParam;
}
public BusinessCheckException(String key, Object[] objectParam) {
this(key);
this.errorObjectParam = objectParam;
}
public String[] getErrorParam() {
return errorParam;
}
public void setErrorParam(String[] errorParam) {
this.errorParam = errorParam;
}
}

View File

@ -0,0 +1,71 @@
package com.fuint.framework.exception;
/**
* 业务运行异常
*
* Created by FSQ
* CopyRight https://www.fuint.cn
*/
public class BusinessRuntimeException extends RuntimeException {
private static final long serialVersionUID = 1L;
private Throwable rootCause;
public BusinessRuntimeException(String arg0) {
super(arg0);
this.errorKey = arg0;
rootCause = this;
}
public BusinessRuntimeException() {
super();
}
public BusinessRuntimeException(String s, Throwable e) {
this(s);
if (e instanceof BusinessRuntimeException) {
rootCause = ((BusinessRuntimeException) e).rootCause;
} else {
rootCause = e;
}
}
public BusinessRuntimeException(Throwable e) {
this("", e);
}
public Throwable getRootCause() {
return rootCause;
}
private String errorKey;
public String getErrorKey() {
return errorKey;
}
private String[] errorParam;
private Object[] errorObjectParam;
public Object[] getErrorObjectParam() {
return errorObjectParam;
}
public void setErrorObjectParam(Object[] errorObjectParam) {
this.errorObjectParam = errorObjectParam;
}
public BusinessRuntimeException(String key, Object[] objectParam) {
this(key);
this.errorObjectParam = objectParam;
}
public String[] getErrorParam() {
return errorParam;
}
public void setErrorParam(String[] errorParam) {
this.errorParam = errorParam;
}
}

View File

@ -0,0 +1,106 @@
package com.fuint.framework.exception;
import com.fuint.framework.web.ResponseObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import javax.servlet.http.HttpServletRequest;
/**
* 全局异常处理器
*
* Created by FSQ
* CopyRight https://www.fuint.cn
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 请求方式不支持
*/
@ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public ResponseObject handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, HttpServletRequest request) {
String requestURI = request.getRequestURI();
log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
return new ResponseObject(201, e.getMessage(), null);
}
/**
* 业务异常
*/
@ExceptionHandler(BusinessCheckException.class)
public ResponseObject handleServiceException(BusinessCheckException e) {
log.error(e.getMessage(), e);
return new ResponseObject(201, e.getMessage(), null);
}
/**
* 请求路径中缺少必需的路径变量
*/
@ExceptionHandler(MissingPathVariableException.class)
public ResponseObject handleMissingPathVariableException(MissingPathVariableException e, HttpServletRequest request) {
String requestURI = request.getRequestURI();
log.error("请求路径中缺少必需的路径变量'{}',发生系统异常.", requestURI, e);
return new ResponseObject(201, String.format("请求路径中缺少必需的路径变量[%s]", e.getVariableName()), null);
}
/**
* 请求参数类型不匹配
*/
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public ResponseObject handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request) {
String requestURI = request.getRequestURI();
log.error("请求参数类型不匹配'{}',发生系统异常.", requestURI, e);
return new ResponseObject(201, String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), e.getValue()), null);
}
/**
* 拦截未知的运行时异常
*/
@ExceptionHandler(RuntimeException.class)
public ResponseObject handleRuntimeException(RuntimeException e, HttpServletRequest request) {
String requestURI = request.getRequestURI();
log.error("请求地址'{}',发生未知异常.", requestURI, e);
e.printStackTrace();
return new ResponseObject(201, e.getMessage(), null);
}
/**
* 系统异常
*/
@ExceptionHandler(Exception.class)
public ResponseObject handleException(Exception e, HttpServletRequest request) {
String requestURI = request.getRequestURI();
log.error("请求地址'{}',发生系统异常.", requestURI, e);
e.printStackTrace();
return new ResponseObject(201, e.getMessage(), null);
}
/**
* 自定义验证异常
*/
@ExceptionHandler(BindException.class)
public ResponseObject handleBindException(BindException e) {
log.error(e.getMessage(), e);
String message = e.getAllErrors().get(0).getDefaultMessage();
return new ResponseObject(201,message, null);
}
/**
* 自定义验证异常
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public Object handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
log.error(e.getMessage(), e);
String message = e.getBindingResult().getFieldError().getDefaultMessage();
return new ResponseObject(201,message, null);
}
}

View File

@ -0,0 +1,97 @@
package com.fuint.framework.pagination;
import java.io.Serializable;
import java.util.Map;
/**
* 分页实体对象
*
* Created by FSQ
* CopyRight https://www.fuint.cn
*/
public class PaginationRequest implements Serializable {
private static final long serialVersionUID = -344484321130132260L;
/**
* 当前页码
*/
private int currentPage;
/**
* 每页大小
*/
private int pageSize;
/**
* 排序字段
*/
private String[] sortColumn;
/**
* 排序类型
*/
private String sortType;
/**
* 分页查询参数
*/
private Map<String, Object> searchParams;
// 默认构造函数
public PaginationRequest() {
this.currentPage = 1;
this.pageSize = 20;
}
public PaginationRequest(Integer pageNumber, Integer pageSize) {
this.currentPage = pageNumber;
this.pageSize = pageSize;
}
public PaginationRequest(Integer pageNumber, Integer pageSize, Map<String, Object> searchParams) {
this.currentPage = pageNumber;
this.pageSize = pageSize;
this.searchParams = searchParams;
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public String[] getSortColumn() {
return sortColumn;
}
public void setSortColumn(String sortColumn) {
this.sortColumn = new String[]{sortColumn};
}
public void setSortColumn(String[] sortColumns) {
this.sortColumn = sortColumns;
}
public String getSortType() {
return sortType;
}
public void setSortType(String sortType) {
this.sortType = sortType;
}
public Map<String, Object> getSearchParams() {
return searchParams;
}
public void setSearchParams(Map<String, Object> searchParams) {
this.searchParams = searchParams;
}
}

View File

@ -0,0 +1,167 @@
package com.fuint.framework.pagination;
import org.springframework.data.domain.Page;
import java.io.Serializable;
import java.util.List;
/**
* 分页请求响应结果对象
*
* @param <T>
* Created by FSQ
* CopyRight https://www.fuint.cn
*/
public class PaginationResponse<T> implements Serializable {
private static final long serialVersionUID = 1115676724739520700L;
/**
* 当前页码
*/
private int currentPage;
/**
* 每页大小
*/
private int pageSize;
/**
* 总页数
*/
private int totalPages;
private int numberOfElements;
/**
* 总记录数
*/
private long totalElements;
/**
* 是否有上一页
*/
private boolean hasPreviousPage;
/**
* 是否是第一页
*/
private boolean isFirstPage;
/**
* 是否有下一页
*/
private boolean hasNextPage;
/**
* 是否是最后一页
*/
private boolean isLastPage;
/**
* 是否有内容
*/
private boolean hasContent;
/**
* 结果集合
*/
private List<T> content;
/**
* 构造方法
*/
public <T> PaginationResponse(final Page<T> page, final Class<? extends T> clz) {
this.currentPage = page.getNumber();
this.pageSize = page.getSize();
this.totalPages = page.getTotalPages();
this.numberOfElements = page.getNumberOfElements();
this.totalElements = page.getTotalElements();
this.hasPreviousPage = page.hasPrevious();
this.isFirstPage = page.isFirst();
this.hasNextPage = page.hasNext();
this.isLastPage = page.isLast();
if (page.getContent() != null && page.getContent().size() > 0) {
this.hasContent = true;
}
}
public int getCurrentPage() {
return currentPage;
}
public void setCurrentPage(int currentPage) {
this.currentPage = currentPage;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public int getTotalPages() {
return totalPages;
}
public void setTotalPages(int totalPages) {
this.totalPages = totalPages;
}
public int getNumberOfElements() {
return numberOfElements;
}
public void setNumberOfElements(int numberOfElements) {
this.numberOfElements = numberOfElements;
}
public long getTotalElements() {
return totalElements;
}
public void setTotalElements(long totalElements) {
this.totalElements = totalElements;
}
public boolean isHasPreviousPage() {
return hasPreviousPage;
}
public void setHasPreviousPage(boolean hasPreviousPage) {
this.hasPreviousPage = hasPreviousPage;
}
public boolean isFirstPage() {
return isFirstPage;
}
public void setFirstPage(boolean isFirstPage) {
this.isFirstPage = isFirstPage;
}
public boolean isHasNextPage() {
return hasNextPage;
}
public void setHasNextPage(boolean hasNextPage) {
this.hasNextPage = hasNextPage;
}
public boolean isLastPage() {
return isLastPage;
}
public void setLastPage(boolean isLastPage) {
this.isLastPage = isLastPage;
}
public boolean isHasContent() {
return hasContent;
}
public void setHasContent(boolean hasContent) {
this.hasContent = hasContent;
}
public List<T> getContent() {
return content;
}
public void setContent(List<T> content) {
this.content = content;
}
}

View File

@ -0,0 +1,21 @@
package com.fuint.framework.service;
import com.fuint.framework.dto.ExcelExportDto;
/**
* 导出Excel文件业务接口
*
* Created by FSQ
* CopyRight https://www.fuint.cn
*/
public interface ExportService {
/**
* 直接导出本地文件
*
* @param data srcPath 文件相对路径
* srcTemplateFileName 文件名称
* out 输出流
*/
void exportLocalFile(ExcelExportDto data) throws Exception;
}

View File

@ -0,0 +1,68 @@
package com.fuint.framework.service;
import com.fuint.framework.dto.ExcelExportDto;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
/**
* 导出Excel文件业务实现类
*
* Created by FSQ
* CopyRight https://www.fuint.cn
*/
@Service
public class ExportServiceImpl implements ExportService {
private static final Logger logger = LoggerFactory.getLogger(ExportServiceImpl.class);
private static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
@Override
public void exportLocalFile(ExcelExportDto data) throws Exception {
// 下载本地文件
InputStream inStream = null;
try {
String fileName = data.getSrcTemplateFileName();
// 读到流中s
inStream = new FileInputStream(data.getSrcPath() + File.separator + fileName);// 文件的存放路径
// 循环取出流中的数据
byte[] b = new byte[100];
int len;
while ((len = inStream.read(b)) > 0) {
data.getOut().write(b, 0, len);
}
inStream.close();
data.getOut().flush();
data.getOut().close();
// 设置输出的格式
} catch (FileNotFoundException e) {
logger.error("ExportServiceImpl.exportLocalFile{}", e);
throw e;
} catch (IOException e) {
logger.error("ExportServiceImpl.exportLocalFile{}", e);
throw e;
} finally {
try {
if (null != inStream) {
inStream.close();
}
} catch (IOException e) {
logger.error("ExportServiceImpl.exportLocalFile{}", e);
}
if (null != data.getOut()) {
try {
data.getOut().close();
} catch (IOException e) {
logger.error("ExportServiceImpl.exportLocalFile{}", e);
}
}
}
}
}

View File

@ -0,0 +1,78 @@
package com.fuint.framework.web;
import com.fuint.framework.FrameworkConstants;
import com.fuint.utils.PropertiesUtil;
/**
* 控制器基类
*
* Created by FSQ
* CopyRight https://www.fuint.cn
*/
public class BaseController {
/**
* 获取成功返回结果
*
* @param data
* @return
*/
public ResponseObject getSuccessResult(Object data) {
return new ResponseObject(FrameworkConstants.HTTP_RESPONSE_CODE_SUCCESS, "操作成功", data);
}
/**
* 获取成功返回结果
*
* @param message
* @param data
* @return
*/
public ResponseObject getSuccessResult(String message, Object data) {
return new ResponseObject(FrameworkConstants.HTTP_RESPONSE_CODE_SUCCESS, message, data);
}
/**
* 获取成功返回结果
*
* @param code
* @param message
* @param data
* @return
*/
public ResponseObject getSuccessResult(int code, String message, Object data) {
return new ResponseObject(code, message, data);
}
/**
* 获取错返回结果(无参数替换)
*
* @param errorCode
* @return
*/
public ResponseObject getFailureResult(int errorCode) {
return new ResponseObject(errorCode, PropertiesUtil.getResponseErrorMessageByCode(errorCode), null);
}
/**
* 获取错返回结果(带参数替换)
*
* @param errorCode
* @param message
* @return
*/
public ResponseObject getFailureResult(int errorCode, String message) {
return new ResponseObject(errorCode, message, null);
}
/**
* 获取错返回结果(带参数替换)
*
* @param errorCode
* @param message
* @return
*/
public ResponseObject getFailureResult(int errorCode, String message, Object data) {
return new ResponseObject(errorCode, message, data);
}
}

View File

@ -0,0 +1,55 @@
package com.fuint.framework.web;
/**
* 返回数据结构
*
* Created by FSQ
*
* CopyRight https://www.fuint.cn
*/
public class ResponseObject {
private Integer code;
private String message;
private Object data;
public ResponseObject(Integer code, String message, Object data) {
this.code = code;
this.message = message;
this.data = data;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String msg) {
this.message = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder("ResponseObject{");
sb.append("code=").append(code);
sb.append(", message='").append(message).append('\'');
sb.append(", data=").append(data);
sb.append('}');
return sb.toString();
}
}