| @@ -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); | |||||
| } | |||||
| } | |||||
| } | |||||