@@ -45,3 +45,5 @@ nbdist/ | |||||
!*/build/*.java | !*/build/*.java | ||||
!*/build/*.html | !*/build/*.html | ||||
!*/build/*.xml | !*/build/*.xml | ||||
ruoyi-admin/src/main/resources/public/* |
@@ -0,0 +1,13 @@ | |||||
@echo off | |||||
echo. | |||||
echo [��Ϣ] ʹ��Jar��������Web���̡� | |||||
echo. | |||||
cd %~dp0 | |||||
cd ..\libs | |||||
set JAVA_OPTS=-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m | |||||
java -jar %JAVA_OPTS% ruoyi-admin-1.0.0.jar | |||||
pause |
@@ -211,12 +211,6 @@ | |||||
<version>${net.coobird.version}</version> | <version>${net.coobird.version}</version> | ||||
</dependency> | </dependency> | ||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-thymeleaf</artifactId> | |||||
<version>2.5.15</version> | |||||
</dependency> | |||||
<!-- 文件模块--> | <!-- 文件模块--> | ||||
<dependency> | <dependency> | ||||
<groupId>com.ruoyi</groupId> | <groupId>com.ruoyi</groupId> | ||||
@@ -224,6 +218,13 @@ | |||||
<version>${ruoyi.version}</version> | <version>${ruoyi.version}</version> | ||||
</dependency> | </dependency> | ||||
<!-- URL重写 --> | |||||
<dependency> | |||||
<groupId>org.tuckey</groupId> | |||||
<artifactId>urlrewritefilter</artifactId> | |||||
<version>4.0.4</version> | |||||
</dependency> | |||||
</dependencies> | </dependencies> | ||||
</dependencyManagement> | </dependencyManagement> | ||||
@@ -18,12 +18,6 @@ | |||||
<dependencies> | <dependencies> | ||||
<!-- SpringBoot集成thymeleaf模板 --> | |||||
<dependency> | |||||
<groupId>org.springframework.boot</groupId> | |||||
<artifactId>spring-boot-starter-thymeleaf</artifactId> | |||||
</dependency> | |||||
<!-- spring-boot-devtools --> | <!-- spring-boot-devtools --> | ||||
<dependency> | <dependency> | ||||
<groupId>org.springframework.boot</groupId> | <groupId>org.springframework.boot</groupId> | ||||
@@ -37,15 +37,6 @@ spring: | |||||
restart: | restart: | ||||
# 热部署开关 | # 热部署开关 | ||||
enabled: true | enabled: true | ||||
# 模板引擎 | |||||
thymeleaf: | |||||
mode: LEGACYHTML5 | |||||
encoding: utf-8 | |||||
# 禁用缓存 | |||||
cache: false | |||||
prefix: classpath:/web/ | |||||
suffix: .vue | |||||
content-type: text/html | |||||
# 开发环境配置 | # 开发环境配置 | ||||
server: | server: | ||||
@@ -118,18 +109,3 @@ xss: | |||||
excludes: /system/notice | excludes: /system/notice | ||||
# 匹配链接 | # 匹配链接 | ||||
urlPatterns: /system/*,/monitor/*,/tool/* | urlPatterns: /system/*,/monitor/*,/tool/* | ||||
sms: | |||||
# 启用短信平台 | |||||
startSms: true | |||||
# 过期时间(分钟) | |||||
expiration: 2 | |||||
# 发送频率间隔(分钟) | |||||
frequency: 1 | |||||
# 短信平台(助通) | |||||
zt: | |||||
send: | |||||
sms: | |||||
username: znrx666hy | |||||
password: RXZTKS0FaLG4pN |
@@ -32,5 +32,10 @@ | |||||
<outputDirectory>bin</outputDirectory> | <outputDirectory>bin</outputDirectory> | ||||
<fileMode>755</fileMode> | <fileMode>755</fileMode> | ||||
</file> | </file> | ||||
<file> | |||||
<source>${project.parent.basedir}/bin/start.bat</source> | |||||
<outputDirectory>bin</outputDirectory> | |||||
<fileMode>755</fileMode> | |||||
</file> | |||||
</files> | </files> | ||||
</assembly> | </assembly> |
@@ -0,0 +1,9 @@ | |||||
<?xml version="1.0" encoding="utf-8"?> | |||||
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.2//EN" | |||||
"http://tuckey.org/res/dtds/urlrewrite3.2.dtd"> | |||||
<urlrewrite> | |||||
<rule> | |||||
<from>^/api/(.*)$</from> | |||||
<to>/$1</to> | |||||
</rule> | |||||
</urlrewrite> |
@@ -0,0 +1,19 @@ | |||||
package com.ruoyi.file.object; | |||||
import java.util.TimerTask; | |||||
public class DumpUploadTask extends TimerTask | |||||
{ | |||||
private final ProjectState state; | |||||
public DumpUploadTask(ProjectState state) | |||||
{ | |||||
this.state = state; | |||||
} | |||||
@Override | |||||
public void run() | |||||
{ | |||||
StateMachine.INSTANCE.AddState(state); | |||||
} | |||||
} |
@@ -24,7 +24,7 @@ public final class StateMachine | |||||
private final Map<String, ProjectState> projectStateMap = new LinkedHashMap<>(); | private final Map<String, ProjectState> projectStateMap = new LinkedHashMap<>(); | ||||
public static final StateMachine INSTANCE = new StateMachine(); | public static final StateMachine INSTANCE = new StateMachine(); | ||||
public void AddState(ProjectState state) | |||||
public synchronized void AddState(ProjectState state) | |||||
{ | { | ||||
ProjectState projectState = projectStateMap.get(state.token); | ProjectState projectState = projectStateMap.get(state.token); | ||||
if(null != projectState) | if(null != projectState) | ||||
@@ -6,16 +6,16 @@ import javax.validation.constraints.NotBlank; | |||||
import javax.validation.constraints.NotNull; | import javax.validation.constraints.NotNull; | ||||
@Data | @Data | ||||
public class CommonAttachReq | |||||
public class CommonAttachReq extends RuralCollectiveAssetsBaseReq | |||||
{ | { | ||||
public static final String REDIRECT_URI = "/file/common/attach"; | |||||
@NotBlank(message = "文件分类不能为空") | @NotBlank(message = "文件分类不能为空") | ||||
private String bizPath; | private String bizPath; | ||||
@NotBlank(message = "文件表名不能为空") | @NotBlank(message = "文件表名不能为空") | ||||
private String tableName; | private String tableName; | ||||
@NotNull(message = "文件表ID不能为空") | @NotNull(message = "文件表ID不能为空") | ||||
private Long tableId; | private Long tableId; | ||||
@NotBlank(message = "服务标识不能为空") | |||||
private String token; | |||||
private String fileType; | private String fileType; | ||||
} | } |
@@ -6,10 +6,9 @@ import javax.validation.constraints.NotBlank; | |||||
import javax.validation.constraints.NotNull; | import javax.validation.constraints.NotNull; | ||||
@Data | @Data | ||||
public class CommonUploadReq | |||||
public class CommonUploadReq extends RuralCollectiveAssetsBaseReq | |||||
{ | { | ||||
@NotBlank(message = "服务标识不能为空") | |||||
private String token; | |||||
public static final String REDIRECT_URI = "/file/common/upload"; | |||||
private String bizPath = "upload"; | private String bizPath = "upload"; | ||||
} | } |
@@ -2,14 +2,12 @@ package com.ruoyi.file.request; | |||||
import lombok.Data; | import lombok.Data; | ||||
import javax.validation.constraints.NotBlank; | |||||
@Data | @Data | ||||
public class FinanceVoucherUploadReq | |||||
public class FinanceVoucherUploadReq extends RuralCollectiveAssetsBaseReq | |||||
{ | { | ||||
public static final String REDIRECT_URI = "/file/finance/voucher/upload"; | |||||
private Long id; | private Long id; | ||||
@NotBlank(message = "服务标识不能为空") | |||||
private String token; | |||||
private String bizPath = "voucher"; | private String bizPath = "voucher"; | ||||
@@ -0,0 +1,37 @@ | |||||
package com.ruoyi.file.request; | |||||
import cn.hutool.core.bean.BeanUtil; | |||||
import com.ruoyi.common.utils.StringUtils; | |||||
import lombok.Data; | |||||
import javax.validation.constraints.NotBlank; | |||||
import java.util.Map; | |||||
@Data | |||||
public class RuralCollectiveAssetsBaseReq | |||||
{ | |||||
@NotBlank(message = "服务标识不能为空") | |||||
private String token; | |||||
private String authorization; // api_token 如果为空, 重定向则不携带身份认证 | |||||
public Map<String, Object> toMap(String...rmNames) | |||||
{ | |||||
Map<String, Object> map = BeanUtil.beanToMap(this, false, true); | |||||
map.remove("token"); | |||||
map.remove("authorization"); | |||||
if(null != rmNames) | |||||
{ | |||||
for(String rmName : rmNames) | |||||
{ | |||||
map.remove(rmName); | |||||
} | |||||
} | |||||
return map; | |||||
} | |||||
public boolean withAuthorization() | |||||
{ | |||||
return StringUtils.isNotEmpty(authorization); | |||||
} | |||||
} |
@@ -1,16 +1,12 @@ | |||||
package com.ruoyi.file.request; | package com.ruoyi.file.request; | ||||
import com.ruoyi.common.utils.StringUtils; | |||||
import lombok.Data; | import lombok.Data; | ||||
import org.springframework.web.multipart.MultipartFile; | |||||
import javax.servlet.http.HttpServletRequest; | import javax.servlet.http.HttpServletRequest; | ||||
import javax.validation.constraints.NotBlank; | import javax.validation.constraints.NotBlank; | ||||
import java.util.Enumeration; | import java.util.Enumeration; | ||||
import java.util.HashMap; | |||||
import java.util.LinkedHashMap; | import java.util.LinkedHashMap; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.Set; | |||||
@Data | @Data | ||||
public final class UploadRedirectReq | public final class UploadRedirectReq | ||||
@@ -18,12 +14,22 @@ public final class UploadRedirectReq | |||||
@NotBlank(message = "重定向地址不能为空") | @NotBlank(message = "重定向地址不能为空") | ||||
private String redirectUri; | private String redirectUri; | ||||
private String token; | |||||
// 身份授权, 从请求中读取 | |||||
private String authorization; | |||||
// 重定向携带身份授权的参数名, 置空则不携带 | |||||
private String authorizationName = "api_token"; | |||||
// 重定向参数数据 | |||||
private Map<String, Object> formData; | private Map<String, Object> formData; | ||||
public void ParseToken(HttpServletRequest request) | public void ParseToken(HttpServletRequest request) | ||||
{ | { | ||||
token = request.getHeader("Authorization"); | |||||
authorization = request.getHeader("Authorization"); | |||||
} | |||||
public void SetupToken(String authorizationName, HttpServletRequest request) | |||||
{ | |||||
this.authorizationName = authorizationName; | |||||
ParseToken(request); | |||||
} | } | ||||
public void ParseFormData(HttpServletRequest request) | public void ParseFormData(HttpServletRequest request) | ||||
@@ -12,6 +12,7 @@ import cn.hutool.http.Method; | |||||
import com.ruoyi.common.utils.StringUtils; | import com.ruoyi.common.utils.StringUtils; | ||||
import com.ruoyi.common.utils.file.PathUtils; | import com.ruoyi.common.utils.file.PathUtils; | ||||
import com.ruoyi.file.domain.Project; | import com.ruoyi.file.domain.Project; | ||||
import com.ruoyi.file.object.DumpUploadTask; | |||||
import com.ruoyi.file.request.CommonAttachReq; | import com.ruoyi.file.request.CommonAttachReq; | ||||
import com.ruoyi.file.request.CommonUploadReq; | import com.ruoyi.file.request.CommonUploadReq; | ||||
import com.ruoyi.file.object.ProjectState; | import com.ruoyi.file.object.ProjectState; | ||||
@@ -27,6 +28,7 @@ import com.ruoyi.file.object.UploadSession; | |||||
import com.ruoyi.file.object.UploadTask; | import com.ruoyi.file.object.UploadTask; | ||||
import com.ruoyi.file.utils.FileUploadFunc; | import com.ruoyi.file.utils.FileUploadFunc; | ||||
import com.ruoyi.file.utils.ProjectUtils; | import com.ruoyi.file.utils.ProjectUtils; | ||||
import com.ruoyi.framework.manager.AsyncManager; | |||||
import com.ruoyi.framework.web.service.TokenService; | import com.ruoyi.framework.web.service.TokenService; | ||||
import org.springframework.http.HttpStatus; | import org.springframework.http.HttpStatus; | ||||
import org.springframework.stereotype.Service; | import org.springframework.stereotype.Service; | ||||
@@ -37,6 +39,7 @@ import javax.servlet.http.HttpServletResponse; | |||||
import java.nio.charset.StandardCharsets; | import java.nio.charset.StandardCharsets; | ||||
import java.util.LinkedHashMap; | import java.util.LinkedHashMap; | ||||
import java.util.Map; | import java.util.Map; | ||||
import java.util.TimerTask; | |||||
@Service | @Service | ||||
public class FileService | public class FileService | ||||
@@ -97,8 +100,8 @@ public class FileService | |||||
public void commonUpload(MultipartFile file, CommonUploadReq req, HttpServletRequest request, HttpServletResponse response) | public void commonUpload(MultipartFile file, CommonUploadReq req, HttpServletRequest request, HttpServletResponse response) | ||||
{ | { | ||||
UploadRedirectReq redirectReq = new UploadRedirectReq(); | UploadRedirectReq redirectReq = new UploadRedirectReq(); | ||||
redirectReq.setRedirectUri("/file/common/upload"); | |||||
redirectReq.ParseToken(request); | |||||
redirectReq.setRedirectUri(CommonUploadReq.REDIRECT_URI); | |||||
redirectReq.SetupToken(req.getAuthorization(), request); | |||||
UploadLog.Clear(); | UploadLog.Clear(); | ||||
UploadSession session = Upload(file, req.getBizPath(), req.getToken()); | UploadSession session = Upload(file, req.getBizPath(), req.getToken()); | ||||
@@ -109,11 +112,9 @@ public class FileService | |||||
public void commonAttach(MultipartFile file, CommonAttachReq req, HttpServletRequest request, HttpServletResponse response) | public void commonAttach(MultipartFile file, CommonAttachReq req, HttpServletRequest request, HttpServletResponse response) | ||||
{ | { | ||||
UploadRedirectReq redirectReq = new UploadRedirectReq(); | UploadRedirectReq redirectReq = new UploadRedirectReq(); | ||||
redirectReq.setRedirectUri("/file/common/attach"); | |||||
Map<String, Object> map = BeanUtil.beanToMap(req, false, true); | |||||
map.remove("token"); | |||||
redirectReq.setFormData(map); | |||||
redirectReq.ParseToken(request); | |||||
redirectReq.setRedirectUri(CommonAttachReq.REDIRECT_URI); | |||||
redirectReq.setFormData(req.toMap()); | |||||
redirectReq.SetupToken(req.getAuthorization(), request); | |||||
UploadLog.Clear(); | UploadLog.Clear(); | ||||
UploadSession session = Upload(file, req.getBizPath(), req.getToken()); | UploadSession session = Upload(file, req.getBizPath(), req.getToken()); | ||||
@@ -124,12 +125,9 @@ public class FileService | |||||
public void financeVoucherUpload(MultipartFile file, FinanceVoucherUploadReq req, HttpServletRequest request, HttpServletResponse response) | public void financeVoucherUpload(MultipartFile file, FinanceVoucherUploadReq req, HttpServletRequest request, HttpServletResponse response) | ||||
{ | { | ||||
UploadRedirectReq redirectReq = new UploadRedirectReq(); | UploadRedirectReq redirectReq = new UploadRedirectReq(); | ||||
redirectReq.setRedirectUri("/file/finance/voucher/upload"); | |||||
Map<String, Object> map = BeanUtil.beanToMap(req, false, true); | |||||
map.remove("token"); | |||||
map.remove("bizPath"); | |||||
redirectReq.setFormData(map); | |||||
redirectReq.ParseToken(request); | |||||
redirectReq.setRedirectUri(FinanceVoucherUploadReq.REDIRECT_URI); | |||||
redirectReq.setFormData(req.toMap("bizPath")); | |||||
redirectReq.SetupToken(req.getAuthorization(), request); | |||||
UploadLog.Clear(); | UploadLog.Clear(); | ||||
UploadSession session = Upload(file, req.getBizPath(), req.getToken()); | UploadSession session = Upload(file, req.getBizPath(), req.getToken()); | ||||
@@ -194,7 +192,8 @@ public class FileService | |||||
{ | { | ||||
String url = PathUtils.appendPaths(session.project.getRemoteHost(), req.getRedirectUri()); | String url = PathUtils.appendPaths(session.project.getRemoteHost(), req.getRedirectUri()); | ||||
Map<String, Object> parms = new LinkedHashMap<>(); | Map<String, Object> parms = new LinkedHashMap<>(); | ||||
parms.put("api_token", TokenService.getPureToken(req.getToken())); | |||||
if(StringUtils.isNotEmpty(req.getAuthorizationName())) | |||||
parms.put(req.getAuthorizationName(), TokenService.getPureToken(req.getAuthorization())); | |||||
parms.put("fileUrl", session.result.getFileUrl()); | parms.put("fileUrl", session.result.getFileUrl()); | ||||
parms.put("fileName", session.task.OriginFileName()); | parms.put("fileName", session.task.OriginFileName()); | ||||
if(StringUtils.isNotEmpty(session.result.getThumbnailFileUrl())) | if(StringUtils.isNotEmpty(session.result.getThumbnailFileUrl())) | ||||
@@ -244,7 +243,8 @@ public class FileService | |||||
state.AddNumError(1); | state.AddNumError(1); | ||||
state.SetLastErrorTime(session.result.getTime()); | state.SetLastErrorTime(session.result.getTime()); | ||||
} | } | ||||
StateMachine.INSTANCE.AddState(state); | |||||
UploadLog.Appendln(state.ToString(", ")); | UploadLog.Appendln(state.ToString(", ")); | ||||
AsyncManager.me().execute(new DumpUploadTask(state)); | |||||
} | } | ||||
} | } |
@@ -65,6 +65,12 @@ | |||||
<artifactId>ruoyi-system</artifactId> | <artifactId>ruoyi-system</artifactId> | ||||
</dependency> | </dependency> | ||||
<!-- URL重写 --> | |||||
<dependency> | |||||
<groupId>org.tuckey</groupId> | |||||
<artifactId>urlrewritefilter</artifactId> | |||||
</dependency> | |||||
</dependencies> | </dependencies> | ||||
</project> | </project> |
@@ -126,7 +126,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter | |||||
// open 放行 | // open 放行 | ||||
.antMatchers("/open/**").permitAll() | .antMatchers("/open/**").permitAll() | ||||
.antMatchers("/admin/**").permitAll() | |||||
// 静态资源 | |||||
.antMatchers("/static/**").permitAll() | |||||
// 除上面外的所有请求全部需要鉴权认证 | // 除上面外的所有请求全部需要鉴权认证 | ||||
.anyRequest().authenticated() | .anyRequest().authenticated() | ||||
@@ -0,0 +1,34 @@ | |||||
package com.ruoyi.framework.config; | |||||
import org.springframework.beans.factory.annotation.Value; | |||||
import org.springframework.context.annotation.Configuration; | |||||
import org.springframework.core.annotation.Order; | |||||
import org.springframework.core.io.Resource; | |||||
import org.tuckey.web.filters.urlrewrite.Conf; | |||||
import org.tuckey.web.filters.urlrewrite.UrlRewriteFilter; | |||||
import javax.servlet.FilterConfig; | |||||
import java.io.IOException; | |||||
@Configuration | |||||
@Order(Integer.MIN_VALUE) // 必须先于security过滤器 | |||||
public class UrlRewriteConf extends UrlRewriteFilter | |||||
{ | |||||
private static final String URL_REWRITE = "classpath:/urlrewrite.xml"; | |||||
//注入urlrewrite配置文件 | |||||
@Value(URL_REWRITE) | |||||
private Resource resource; | |||||
//重写配置文件加载方式 | |||||
protected void loadUrlRewriter(FilterConfig filterConfig) | |||||
{ | |||||
try { | |||||
//将Resource对象转换成Conf对象 | |||||
Conf conf = new Conf(filterConfig.getServletContext(), resource.getInputStream(), resource.getFilename(), "@@traceability@@"); | |||||
checkConf(conf); | |||||
} catch (IOException ex) { | |||||
throw new RuntimeException("Unable to load URL rewrite configuration file from " + URL_REWRITE, ex); | |||||
} | |||||
} | |||||
} |