mirror of
https://gitee.com/dromara/RuoYi-Vue-Plus.git
synced 2026-09-20 18:15:56 +08:00
Pre Merge pull request !515 from AprilWind/dev-shorturl
This commit is contained in:
commit
48b875864e
@ -194,6 +194,16 @@ sms:
|
|||||||
signature: 您的短信签名
|
signature: 您的短信签名
|
||||||
sdk-app-id: 您的sdkAppId
|
sdk-app-id: 您的sdkAppId
|
||||||
|
|
||||||
|
--- # 短链接
|
||||||
|
shortlink:
|
||||||
|
# 是否启用租户域名生成
|
||||||
|
enabled: false
|
||||||
|
# 访问前缀
|
||||||
|
api: /dev-api
|
||||||
|
# 域名或主机名
|
||||||
|
address: http://localhost/dev-api/resource/short/link/
|
||||||
|
# 错误页面
|
||||||
|
errorAddress: /error
|
||||||
|
|
||||||
--- # 三方授权
|
--- # 三方授权
|
||||||
justauth:
|
justauth:
|
||||||
|
|||||||
@ -126,6 +126,7 @@ security:
|
|||||||
# EasyRetry Job 分派 @see com.aizuda.easy.retry.client.job.core.client.JobEndPoint
|
# EasyRetry Job 分派 @see com.aizuda.easy.retry.client.job.core.client.JobEndPoint
|
||||||
- /job/dispatch/v1
|
- /job/dispatch/v1
|
||||||
- /job/stop/v1
|
- /job/stop/v1
|
||||||
|
- /resource/short/link/*
|
||||||
|
|
||||||
# 多租户配置
|
# 多租户配置
|
||||||
tenant:
|
tenant:
|
||||||
|
|||||||
@ -23,6 +23,7 @@
|
|||||||
<module>ruoyi-common-oss</module>
|
<module>ruoyi-common-oss</module>
|
||||||
<module>ruoyi-common-ratelimiter</module>
|
<module>ruoyi-common-ratelimiter</module>
|
||||||
<module>ruoyi-common-redis</module>
|
<module>ruoyi-common-redis</module>
|
||||||
|
<module>ruoyi-common-shortlink</module>
|
||||||
<module>ruoyi-common-satoken</module>
|
<module>ruoyi-common-satoken</module>
|
||||||
<module>ruoyi-common-security</module>
|
<module>ruoyi-common-security</module>
|
||||||
<module>ruoyi-common-sms</module>
|
<module>ruoyi-common-sms</module>
|
||||||
|
|||||||
@ -96,6 +96,13 @@
|
|||||||
<version>${revision}</version>
|
<version>${revision}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 短链接 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.dromara</groupId>
|
||||||
|
<artifactId>ruoyi-common-shortlink</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<!-- satoken -->
|
<!-- satoken -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dromara</groupId>
|
<groupId>org.dromara</groupId>
|
||||||
|
|||||||
@ -36,4 +36,10 @@ public interface GlobalConstants {
|
|||||||
* 三方认证 redis key
|
* 三方认证 redis key
|
||||||
*/
|
*/
|
||||||
String SOCIAL_AUTH_CODE_KEY = GLOBAL_REDIS_KEY + "social_auth_codes:";
|
String SOCIAL_AUTH_CODE_KEY = GLOBAL_REDIS_KEY + "social_auth_codes:";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短链接 redis key
|
||||||
|
*/
|
||||||
|
String SHORT_LINK_KEY = GLOBAL_REDIS_KEY + "short_link:";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
37
ruoyi-common/ruoyi-common-shortlink/pom.xml
Normal file
37
ruoyi-common/ruoyi-common-shortlink/pom.xml
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?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>org.dromara</groupId>
|
||||||
|
<artifactId>ruoyi-common</artifactId>
|
||||||
|
<version>${revision}</version>
|
||||||
|
</parent>
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<artifactId>ruoyi-common-shortlink</artifactId>
|
||||||
|
|
||||||
|
<description>
|
||||||
|
ruoyi-common-shortlink 短链接模块
|
||||||
|
</description>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- RuoYi Common Core-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.dromara</groupId>
|
||||||
|
<artifactId>ruoyi-common-core</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.dromara</groupId>
|
||||||
|
<artifactId>ruoyi-common-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.dromara</groupId>
|
||||||
|
<artifactId>ruoyi-common-mybatis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
||||||
@ -0,0 +1,50 @@
|
|||||||
|
package org.dromara.common.shortlink.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 有效期
|
||||||
|
*
|
||||||
|
* @author AprilWind
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum ValidityType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 三分钟
|
||||||
|
*/
|
||||||
|
THREE_MINUTES(3 * 60L),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 一个小时
|
||||||
|
*/
|
||||||
|
ONE_HOUR(60 * 60L),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表示一天(24小时)
|
||||||
|
*/
|
||||||
|
ONE_DAY(24 * 60 * 60L),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表示三天
|
||||||
|
*/
|
||||||
|
THREE_DAYS(3 * 24 * 60 * 60L),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表示七天(一周)
|
||||||
|
*/
|
||||||
|
SEVEN_DAYS(7 * 24 * 60 * 60L),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表示三十天(一个月)
|
||||||
|
*/
|
||||||
|
THIRTY_DAYS(30 * 24 * 60 * 60L);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 有效期(单位:秒)
|
||||||
|
*/
|
||||||
|
private final Long validityType;
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,35 @@
|
|||||||
|
package org.dromara.common.shortlink.properties;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短链接 配置属性
|
||||||
|
*
|
||||||
|
* @author AprilWind
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@ConfigurationProperties(prefix = "shortlink")
|
||||||
|
public class ShortLinkProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 客户端使用租户域名生成链接
|
||||||
|
*/
|
||||||
|
private Boolean enabled = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 访问前缀 (开启时启用,可不填写,能访问到后端即可)
|
||||||
|
*/
|
||||||
|
private String api;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短链接主机名或域名
|
||||||
|
*/
|
||||||
|
private String address;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误页面的主机名或域名
|
||||||
|
*/
|
||||||
|
private String errorAddress = "/error";
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,100 @@
|
|||||||
|
package org.dromara.common.shortlink.utils;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Validator;
|
||||||
|
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
|
||||||
|
import lombok.AccessLevel;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.dromara.common.core.constant.GlobalConstants;
|
||||||
|
import org.dromara.common.core.utils.SpringUtils;
|
||||||
|
import org.dromara.common.core.utils.StringUtils;
|
||||||
|
import org.dromara.common.redis.utils.RedisUtils;
|
||||||
|
import org.dromara.common.shortlink.enums.ValidityType;
|
||||||
|
import org.dromara.common.shortlink.properties.ShortLinkProperties;
|
||||||
|
|
||||||
|
import java.time.Duration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短链接生成工具类
|
||||||
|
*
|
||||||
|
* @author AprilWind
|
||||||
|
*/
|
||||||
|
@NoArgsConstructor(access = AccessLevel.PRIVATE)
|
||||||
|
public class ShortLinkUtils {
|
||||||
|
|
||||||
|
private static final IdentifierGenerator IDENTIFIER_GENERATOR = SpringUtils.getBean(IdentifierGenerator.class);
|
||||||
|
private static final ShortLinkProperties SHORT_LINK_PROPERTIES = SpringUtils.getBean(ShortLinkProperties.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据默认主机名(或域名)生成完整短链接
|
||||||
|
*
|
||||||
|
* @param longUrl 完整的长链接
|
||||||
|
* @param validityType 有效期类型枚举
|
||||||
|
* @return 带有默认主机名(或域名)的完整短链接
|
||||||
|
*/
|
||||||
|
public static String generateShortUrl(String longUrl, ValidityType validityType) {
|
||||||
|
return generateShortUrl(SHORT_LINK_PROPERTIES.getAddress(), longUrl, validityType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据指定主机名(或域名)生成完整短链接
|
||||||
|
*
|
||||||
|
* @param address 主机名(或域名)
|
||||||
|
* @param longUrl 完整的长链接
|
||||||
|
* @param validityType 有效期类型枚举
|
||||||
|
* @return 带有指定主机名(或域名)的完整短链接
|
||||||
|
*/
|
||||||
|
public static String generateShortUrl(String address, String longUrl, ValidityType validityType) {
|
||||||
|
String url = generateShortLinkIdentifier(longUrl, validityType);
|
||||||
|
return address + url;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成短链接标识符并将长链接存储到缓存中
|
||||||
|
*
|
||||||
|
* @param longUrl 完整的长链接
|
||||||
|
* @param validityType 有效期类型枚举
|
||||||
|
* @return 生成的短链接标识符
|
||||||
|
*/
|
||||||
|
public static String generateShortLinkIdentifier(String longUrl, ValidityType validityType) {
|
||||||
|
// 使用标识符生成器生成短链接标识符
|
||||||
|
String shortLinkIdentifier = IDENTIFIER_GENERATOR.nextId(null).toString();
|
||||||
|
return generateShortLinkIdentifier(shortLinkIdentifier, longUrl, validityType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成指定短链接标识符并将长链接存储到缓存中
|
||||||
|
*
|
||||||
|
* @param shortLinkIdentifier 指定的短链接标识符
|
||||||
|
* @param longUrl 完整的长链接
|
||||||
|
* @param validityType 有效期类型枚举
|
||||||
|
* @return 生成的指定短链接标识符
|
||||||
|
*/
|
||||||
|
public static String generateShortLinkIdentifier(String shortLinkIdentifier, String longUrl, ValidityType validityType) {
|
||||||
|
Validator.validateUrl(longUrl, "请输入有效的url");
|
||||||
|
RedisUtils.setCacheObject(GlobalConstants.SHORT_LINK_KEY + shortLinkIdentifier, longUrl, Duration.ofSeconds(validityType.getValidityType()));
|
||||||
|
return shortLinkIdentifier;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据短链接获取对应的完整长链接,如果找不到长链接则返回错误链接
|
||||||
|
*
|
||||||
|
* @param shortLinkIdentifier 短链接标识符
|
||||||
|
* @return 对应的完整长链接,如果未找到则返回错误链接
|
||||||
|
*/
|
||||||
|
public static String getLongLink(String shortLinkIdentifier) {
|
||||||
|
return getLongLink(shortLinkIdentifier, SHORT_LINK_PROPERTIES.getErrorAddress());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据短链接获取对应的完整长链接,如果找不到长链接则返回指定的错误链接
|
||||||
|
*
|
||||||
|
* @param shortLinkIdentifier 短链接标识符
|
||||||
|
* @param errUrl 错误链接
|
||||||
|
* @return 对应的完整长链接,如果未找到则返回错误链接
|
||||||
|
*/
|
||||||
|
public static String getLongLink(String shortLinkIdentifier, String errUrl) {
|
||||||
|
String longLink = RedisUtils.getCacheObject(GlobalConstants.SHORT_LINK_KEY + shortLinkIdentifier);
|
||||||
|
return StringUtils.isNotEmpty(longLink) ? longLink : errUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
org.dromara.common.shortlink.properties.ShortLinkProperties
|
||||||
@ -43,6 +43,12 @@
|
|||||||
<artifactId>ruoyi-common-oss</artifactId>
|
<artifactId>ruoyi-common-oss</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- 短链接功能模 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.dromara</groupId>
|
||||||
|
<artifactId>ruoyi-common-shortlink</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.dromara</groupId>
|
<groupId>org.dromara</groupId>
|
||||||
<artifactId>ruoyi-common-log</artifactId>
|
<artifactId>ruoyi-common-log</artifactId>
|
||||||
|
|||||||
@ -0,0 +1,60 @@
|
|||||||
|
package org.dromara.system.controller.system;
|
||||||
|
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.dromara.common.core.domain.R;
|
||||||
|
import org.dromara.common.shortlink.enums.ValidityType;
|
||||||
|
import org.dromara.common.shortlink.properties.ShortLinkProperties;
|
||||||
|
import org.dromara.common.shortlink.utils.ShortLinkUtils;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.servlet.view.RedirectView;
|
||||||
|
|
||||||
|
import java.net.MalformedURLException;
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 短链接 控制层
|
||||||
|
*/
|
||||||
|
@Validated
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/resource/short")
|
||||||
|
public class SysShortLinkController {
|
||||||
|
|
||||||
|
private final ShortLinkProperties shortLinkProperties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据短链接获取长链接并重定向
|
||||||
|
*
|
||||||
|
* @param shortLinkIdentifier 短链接标识符
|
||||||
|
* @return 重定向视图
|
||||||
|
*/
|
||||||
|
@GetMapping("/link/{shortLinkIdentifier}")
|
||||||
|
public RedirectView getLongLink(@PathVariable("shortLinkIdentifier") String shortLinkIdentifier) {
|
||||||
|
String longLink = ShortLinkUtils.getLongLink(shortLinkIdentifier, shortLinkProperties.getErrorAddress());
|
||||||
|
return new RedirectView(longLink);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成短链接并返回
|
||||||
|
*
|
||||||
|
* @param longUrl 长链接
|
||||||
|
* @return 完整的短链接
|
||||||
|
*/
|
||||||
|
@PostMapping("/shorturl")
|
||||||
|
public R<String> generateShortUrl(HttpServletRequest request, @NotBlank(message = "参数不能为空") String longUrl) throws MalformedURLException {
|
||||||
|
String shorturl;
|
||||||
|
if (Boolean.FALSE.equals(shortLinkProperties.getEnabled())) {
|
||||||
|
shorturl = ShortLinkUtils.generateShortUrl(shortLinkProperties.getAddress(), longUrl, ValidityType.THREE_DAYS);
|
||||||
|
} else {
|
||||||
|
String requestUrl = request.getRequestURL().toString().replace("shorturl", "link/");
|
||||||
|
String host = new URL(requestUrl).getHost();
|
||||||
|
String address = requestUrl.replace(host, host + shortLinkProperties.getApi());
|
||||||
|
shorturl = ShortLinkUtils.generateShortUrl(address, longUrl, ValidityType.THREE_DAYS);
|
||||||
|
}
|
||||||
|
return R.ok(shorturl);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -22,6 +22,8 @@ import org.dromara.common.oss.core.OssClient;
|
|||||||
import org.dromara.common.oss.entity.UploadResult;
|
import org.dromara.common.oss.entity.UploadResult;
|
||||||
import org.dromara.common.oss.enumd.AccessPolicyType;
|
import org.dromara.common.oss.enumd.AccessPolicyType;
|
||||||
import org.dromara.common.oss.factory.OssFactory;
|
import org.dromara.common.oss.factory.OssFactory;
|
||||||
|
import org.dromara.common.shortlink.enums.ValidityType;
|
||||||
|
import org.dromara.common.shortlink.utils.ShortLinkUtils;
|
||||||
import org.dromara.system.domain.SysOss;
|
import org.dromara.system.domain.SysOss;
|
||||||
import org.dromara.system.domain.bo.SysOssBo;
|
import org.dromara.system.domain.bo.SysOssBo;
|
||||||
import org.dromara.system.domain.vo.SysOssVo;
|
import org.dromara.system.domain.vo.SysOssVo;
|
||||||
@ -238,16 +240,17 @@ public class SysOssServiceImpl implements ISysOssService, OssService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 桶类型为 private 的URL 修改为临时URL时长为120s
|
* 桶类型为 private 的URL 修改为临时URL时长为180s
|
||||||
*
|
*
|
||||||
* @param oss OSS对象
|
* @param oss OSS对象
|
||||||
* @return oss 匹配Url的OSS对象
|
* @return oss 匹配Url的OSS对象
|
||||||
*/
|
*/
|
||||||
private SysOssVo matchingUrl(SysOssVo oss) {
|
private SysOssVo matchingUrl(SysOssVo oss) {
|
||||||
OssClient storage = OssFactory.instance(oss.getService());
|
OssClient storage = OssFactory.instance(oss.getService());
|
||||||
// 仅修改桶类型为 private 的URL,临时URL时长为120s
|
// 仅修改桶类型为 private 的URL,临时URL时长为180s
|
||||||
if (AccessPolicyType.PRIVATE == storage.getAccessPolicy()) {
|
if (AccessPolicyType.PRIVATE == storage.getAccessPolicy()) {
|
||||||
oss.setUrl(storage.getPrivateUrl(oss.getFileName(), 120));
|
String privateUrl = storage.getPrivateUrl(oss.getFileName(), 180);
|
||||||
|
oss.setUrl(ShortLinkUtils.generateShortUrl(privateUrl, ValidityType.THREE_MINUTES));
|
||||||
}
|
}
|
||||||
return oss;
|
return oss;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user