首次提交,新增导入,去重,分配地址,修改人员状态信息

parent 519040f2

Too many changes to show.

To preserve performance only 1000 of 1000+ files are displayed.

# Compiled class file
*.class
# Log file
*.log
# BlueJ files
*.ctxt
# Mobile Tools for Java (J2ME)
.mtj.tmp/
target
# Package Files #
*.jar
*.war
*.ear
*.zip
*.tar.gz
*.rar
*.iml
.idea
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
\ No newline at end of file
# dqms
# 基础框架
大碶街道基础数据分析系统
\ No newline at end of file
### 基础说明
对Admin和API的权限做了整合。
### 代码生成器
生成代码前注意替换```hmit-generatir```模块下```generator.properties```中的 moduleName的
```demo``` 和 tablePrefix 的 ```tb_```值为对应内容。
### 国标商密
加密组件配置在 common 包下,默认集成了 SM2 和 SM4,使用 SMUtil 即可。
- 修改依赖,如果需要在其他系统中集成,后端代码可直接复制包 ```io.hmit.common.utils.sm```,
并在 pom.xml 下添加如下依赖。 前端代码请参考前端框架。
```
<!-- 国密 -->
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-ext-jdk15to18</artifactId>
<version>1.71</version>
</dependency>
```
- 修改完后对 hmit-admin 模块下的 qcloud 依赖,把包```bcprov-jdk15on```排除(相同包下同类名称导致冲突无法使用)。
```
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>${qcloud.cos.version}</version>
<exclusions>
<exclusion>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
```
- 具体加密部分需要修改的,可以直接使用全局搜索查找 ```/* SM 登录加密 */``` ,即可查询到需要修改的内容。
### 登录锁定
默认登录账号密码错误 5 次对账号锁定 30 分钟。具体时间和次数可以通过设置 UserLockServiceImpl 类来修改,
在 admin 模块的 application.yml 配置文件中的 ```hmit.login.lock``` 设置项可以选择开启或关闭。
**需要注意的是,如果设置锁定时间大于 30 分钟,需要修改 servlet 的 session 超时时间。**
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
version: '2'
services:
hmit-admin:
image: hmit/hmit-admin
ports:
- "8080:8080"
environment:
- spring.profiles.active=dev
hmit-api:
image: hmit/hmit-api
ports:
- "8081:8081"
environment:
- spring.profiles.active=dev
\ No newline at end of file
FROM java:8
EXPOSE 8080
VOLUME /tmp
ADD hmit-admin.jar /app.jar
RUN bash -c 'touch /app.jar'
ENTRYPOINT ["java","-jar","/app.jar"]
<?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>
<groupId>io.hmit</groupId>
<artifactId>dqms</artifactId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>hmit-admin</artifactId>
<packaging>jar</packaging>
<properties>
<quartz.version>2.3.0</quartz.version>
<qiniu.version>[7.2.0, 7.2.99]</qiniu.version>
<aliyun.oss.version>2.8.3</aliyun.oss.version>
<aliyun.core.version>3.2.2</aliyun.core.version>
<aliyun.dysmsapi.version>1.1.0</aliyun.dysmsapi.version>
<qcloud.cos.version>5.4.4</qcloud.cos.version>
<qcloud.qcloudsms.version>1.0.5</qcloud.qcloudsms.version>
<fastdfs.version>1.26.2</fastdfs.version>
<freemarker.version>2.3.28</freemarker.version>
<activiti.version>5.22.0</activiti.version>
<kaptcha.version>0.0.9</kaptcha.version>
</properties>
<dependencies>
<dependency>
<groupId>io.hmit</groupId>
<artifactId>hmit-common</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>io.hmit</groupId>
<artifactId>hmit-dynamic-datasource</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz</artifactId>
<version>${quartz.version}</version>
<exclusions>
<exclusion>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
</exclusion>
<exclusion>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP-java6</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>${qiniu.version}</version>
</dependency>
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>${aliyun.oss.version}</version>
</dependency>
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>${qcloud.cos.version}</version>
<exclusions>
<exclusion>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>${aliyun.core.version}</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>${aliyun.dysmsapi.version}</version>
</dependency>
<dependency>
<groupId>com.github.qcloudsms</groupId>
<artifactId>qcloudsms</artifactId>
<version>${qcloud.qcloudsms.version}</version>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>${freemarker.version}</version>
</dependency>
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>${fastdfs.version}</version>
</dependency>
<!-- activiti -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-basic</artifactId>
<version>${activiti.version}</version>
<exclusions>
<exclusion>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-explorer</artifactId>
<version>${activiti.version}</version>
<exclusions>
<exclusion>
<artifactId>vaadin</artifactId>
<groupId>com.vaadin</groupId>
</exclusion>
<exclusion>
<artifactId>dcharts-widget</artifactId>
<groupId>org.vaadin.addons</groupId>
</exclusion>
<exclusion>
<artifactId>activiti-simple-workflow</artifactId>
<groupId>org.activiti</groupId>
</exclusion>
<exclusion>
<artifactId>slf4j-log4j12</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-diagram-rest</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-modeler</artifactId>
<version>${activiti.version}</version>
</dependency>
<!-- end activiti -->
<dependency>
<groupId>com.github.axet</groupId>
<artifactId>kaptcha</artifactId>
<version>${kaptcha.version}</version>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.18.RELEASE</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>${docker.plugin.version}</version>
<configuration>
<imageName>hmit/${project.artifactId}</imageName>
<dockerDirectory>${project.basedir}/</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package io.hmit;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.core.env.Environment;
/**
* @author Shen
*/
@Slf4j
@SpringBootApplication(exclude = {
org.activiti.spring.boot.SecurityAutoConfiguration.class,
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class
})
public class AdminApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(AdminApplication.class);
Environment env = app.run(args).getEnvironment();
log.info("启动成功!!");
log.info("Admin Swagger地址: \thttp://127.0.0.1:{}/hmit-admin/swagger-ui.html", env.getProperty("server.port"));
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(AdminApplication.class);
}
}
package io.hmit.common.aspect;
import cn.hutool.core.collection.CollUtil;
import io.hmit.common.annotation.DataFilter;
import io.hmit.common.constant.Constant;
import io.hmit.common.exception.ErrorCode;
import io.hmit.common.interceptor.DataScope;
import io.hmit.modules.security.user.SecurityUser;
import io.hmit.modules.security.user.UserDetail;
import io.hmit.modules.sys.enums.SuperAdminEnum;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
/**
* 数据过滤,切面处理类
*
* @author
*/
@Aspect
@Component
public class DataFilterAspect {
@Pointcut("@annotation(io.hmit.common.annotation.DataFilter)")
public void dataFilterCut() {
}
@Before("dataFilterCut()")
public void dataFilter(JoinPoint point) {
Object params = point.getArgs()[0];
if (params != null && params instanceof Map) {
UserDetail user = SecurityUser.getUser();
//如果是超级管理员,则不进行数据过滤
if (user.getSuperAdmin() == SuperAdminEnum.YES.value()) {
return;
}
try {
//否则进行数据过滤
Map map = (Map) params;
String sqlFilter = getSqlFilter(user, point);
map.put(Constant.SQL_FILTER, new DataScope(sqlFilter));
} catch (Exception e) {
}
return;
}
throw new io.hmit.common.exception.HmitException(ErrorCode.DATA_SCOPE_PARAMS_ERROR);
}
/**
* 获取数据过滤的SQL
*/
private String getSqlFilter(UserDetail user, JoinPoint point) throws Exception {
MethodSignature signature = (MethodSignature) point.getSignature();
Method method = point.getTarget().getClass().getDeclaredMethod(signature.getName(), signature.getParameterTypes());
DataFilter dataFilter = method.getAnnotation(DataFilter.class);
//获取表的别名
String tableAlias = dataFilter.tableAlias();
if (StringUtils.isNotBlank(tableAlias)) {
tableAlias += ".";
}
StringBuilder sqlFilter = new StringBuilder();
sqlFilter.append(" (");
//部门ID列表
List<Long> deptIdList = user.getDeptIdList();
if (CollUtil.isNotEmpty(deptIdList)) {
sqlFilter.append(tableAlias).append(dataFilter.deptId());
sqlFilter.append(" in(").append(StringUtils.join(deptIdList, ",")).append(")");
}
//查询本人数据
if (CollUtil.isNotEmpty(deptIdList)) {
sqlFilter.append(" or ");
}
sqlFilter.append(tableAlias).append(dataFilter.userId()).append("=").append(user.getId());
sqlFilter.append(")");
return sqlFilter.toString();
}
}
\ No newline at end of file
package io.hmit.common.aspect;
import com.alibaba.fastjson.JSON;
import io.hmit.common.annotation.LogOperation;
import io.hmit.common.utils.HttpContextUtils;
import io.hmit.common.utils.IpUtils;
import io.hmit.modules.log.entity.SysLogOperationEntity;
import io.hmit.modules.log.enums.OperationStatusEnum;
import io.hmit.modules.log.service.SysLogOperationService;
import io.hmit.modules.security.user.SecurityUser;
import io.hmit.modules.security.user.UserDetail;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
/**
* 操作日志,切面处理类
*
* @author
*/
@Aspect
@Component
public class LogOperationAspect {
@Autowired
private SysLogOperationService sysLogOperationService;
@Pointcut("@annotation(io.hmit.common.annotation.LogOperation)")
public void logPointCut() {
}
@Around("logPointCut()")
public Object around(ProceedingJoinPoint point) throws Throwable {
long beginTime = System.currentTimeMillis();
try {
//执行方法
Object result = point.proceed();
//执行时长(毫秒)
long time = System.currentTimeMillis() - beginTime;
//保存日志
saveLog(point, time, OperationStatusEnum.SUCCESS.value());
return result;
} catch (Exception e) {
//执行时长(毫秒)
long time = System.currentTimeMillis() - beginTime;
//保存日志
saveLog(point, time, OperationStatusEnum.FAIL.value());
throw e;
}
}
private void saveLog(ProceedingJoinPoint joinPoint, long time, Integer status) throws Exception {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = joinPoint.getTarget().getClass().getDeclaredMethod(signature.getName(), signature.getParameterTypes());
LogOperation annotation = method.getAnnotation(LogOperation.class);
SysLogOperationEntity log = new SysLogOperationEntity();
if (annotation != null) {
//注解上的描述
log.setOperation(annotation.value());
}
//登录用户信息
UserDetail user = SecurityUser.getUser();
if (user != null) {
log.setCreatorName(user.getUsername());
}
log.setStatus(status);
log.setRequestTime((int) time);
//请求相关信息
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
log.setIp(IpUtils.getIpAddr(request));
log.setUserAgent(request.getHeader(HttpHeaders.USER_AGENT));
log.setRequestUri(request.getRequestURI());
log.setRequestMethod(request.getMethod());
//请求参数
Object[] args = joinPoint.getArgs();
try {
String params = JSON.toJSONString(args[0]);
log.setRequestParams(params);
} catch (Exception e) {
}
//保存到DB
sysLogOperationService.save(log);
}
}
\ No newline at end of file
package io.hmit.common.aspect;
import io.hmit.common.exception.ErrorCode;
import io.hmit.common.exception.HmitException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
/**
* Redis切面处理类
*
* @author
*/
@Aspect
@Component
public class RedisAspect {
private Logger logger = LoggerFactory.getLogger(getClass());
/**
* 是否开启redis缓存 true开启 false关闭
*/
@Value("${hmit.redis.open: false}")
private boolean open;
@Around("execution(* io.hmit.common.redis.RedisUtils.*(..))")
public Object around(ProceedingJoinPoint point) throws Throwable {
Object result = null;
if (open) {
try {
result = point.proceed();
} catch (Exception e) {
logger.error("redis error", e);
throw new HmitException(ErrorCode.REDIS_ERROR);
}
}
return result;
}
}
package io.hmit.common.config;
import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Properties;
/**
* 生成验证码配置
*
* @author
*/
@Configuration
public class KaptchaConfig {
@Bean
public DefaultKaptcha producer() {
Properties properties = new Properties();
properties.put("kaptcha.border", "no");
properties.put("kaptcha.textproducer.font.color", "black");
properties.put("kaptcha.textproducer.font.names", "Arial,Courier,cmr10,宋体,楷体,微软雅黑");
properties.put("kaptcha.textproducer.char.space", "5");
Config config = new Config(properties);
DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
defaultKaptcha.setConfig(config);
return defaultKaptcha;
}
}
package io.hmit.common.config;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import io.hmit.common.interceptor.DataFilterInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
/**
* mybatis-plus配置
*
* @author
* @since 1.0.0
*/
@Configuration
public class MybatisPlusConfig {
/**
* 配置数据权限
*/
@Bean
@Order(1)
public DataFilterInterceptor dataFilterInterceptor() {
return new DataFilterInterceptor();
}
/**
* 配置分页
*/
@Bean
@Order(0)
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
\ No newline at end of file
package io.hmit.common.config;
import io.hmit.common.constant.Constant;
import io.swagger.annotations.ApiOperation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import java.util.List;
import static com.google.common.collect.Lists.newArrayList;
/**
* Swagger配置
*
* @author
*/
@Configuration
@EnableSwagger2
public class SwaggerConfig {
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
//加了ApiOperation注解的类,生成接口文档
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class))
//包下的类,生成接口文档
//.apis(RequestHandlerSelectors.basePackage("io.hmit.modules.job.controller"))
.paths(PathSelectors.any())
.build()
.directModelSubstitute(java.util.Date.class, String.class)
.securitySchemes(security());
}
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
.title("hmit-enterprise")
.contact(new Contact(" ", "", " "))
.description("接口文档")
.termsOfServiceUrl("")
.version("1.0.0")
.build();
}
private List<ApiKey> security() {
return newArrayList(
new ApiKey(Constant.TOKEN_HEADER, Constant.TOKEN_HEADER, "header")
);
}
}
\ No newline at end of file
package io.hmit.common.exception;
import cn.hutool.core.map.MapUtil;
import com.alibaba.fastjson.JSON;
import io.hmit.common.utils.HttpContextUtils;
import io.hmit.common.utils.IpUtils;
import io.hmit.common.utils.Result;
import io.hmit.modules.log.entity.SysLogErrorEntity;
import io.hmit.modules.log.service.SysLogErrorService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpHeaders;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
/**
* 异常处理器
*
* @author
* @since 1.0.0
*/
@RestControllerAdvice
public class HmitExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(HmitExceptionHandler.class);
@Autowired
private SysLogErrorService sysLogErrorService;
/**
* 处理自定义异常
*/
@ExceptionHandler(HmitException.class)
public Result handleHmitException(HmitException ex) {
Result result = new Result();
result.error(ex.getCode(), ex.getMsg());
return result;
}
@ExceptionHandler(DuplicateKeyException.class)
public Result handleDuplicateKeyException(DuplicateKeyException ex) {
Result result = new Result();
result.error(ErrorCode.DB_RECORD_EXISTS);
return result;
}
@ExceptionHandler(Exception.class)
public Result handleException(Exception ex) {
logger.error(ex.getMessage(), ex);
saveLog(ex);
return new Result().error();
}
/**
* 保存异常日志
*/
private void saveLog(Exception ex) {
SysLogErrorEntity log = new SysLogErrorEntity();
//请求相关信息
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
log.setIp(IpUtils.getIpAddr(request));
log.setUserAgent(request.getHeader(HttpHeaders.USER_AGENT));
log.setRequestUri(request.getRequestURI());
log.setRequestMethod(request.getMethod());
Map<String, String> params = HttpContextUtils.getParameterMap(request);
if (MapUtil.isNotEmpty(params)) {
log.setRequestParams(JSON.toJSONString(params));
}
//异常信息
log.setErrorInfo(ExceptionUtils.getErrorStackTrace(ex));
//保存
sysLogErrorService.save(log);
}
}
\ No newline at end of file
package io.hmit.common.interceptor;
/**
* 数据范围
*
* @author
* @since 1.0.0
*/
public class DataScope {
private String sqlFilter;
public DataScope(String sqlFilter) {
this.sqlFilter = sqlFilter;
}
public String getSqlFilter() {
return sqlFilter;
}
public void setSqlFilter(String sqlFilter) {
this.sqlFilter = sqlFilter;
}
@Override
public String toString() {
return this.sqlFilter;
}
}
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
package io.hmit.common.validator.group;
/**
* 阿里云
*
* @author
*/
public interface AliyunGroup {
}
package io.hmit.common.validator.group;
/**
* FastDFS
*
* @author
*/
public interface FastDFSGroup {
}
package io.hmit.common.validator.group;
/**
* 本地上传
*
* @author
*/
public interface LocalGroup {
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment