diff --git a/src/main/java/im/zhaojun/zfile/controller/admin/ShortLinkManagerController.java b/src/main/java/im/zhaojun/zfile/controller/admin/ShortLinkManagerController.java new file mode 100644 index 0000000..a5fb99d --- /dev/null +++ b/src/main/java/im/zhaojun/zfile/controller/admin/ShortLinkManagerController.java @@ -0,0 +1,45 @@ +package im.zhaojun.zfile.controller.admin; + +import im.zhaojun.zfile.model.support.ResultBean; +import im.zhaojun.zfile.service.ShortLinkConfigService; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.annotation.Resource; + +/** + * 直链管理 Controller + * + * @author zhaojun + */ +@Controller +@RequestMapping("/admin") +public class ShortLinkManagerController { + + @Resource + private ShortLinkConfigService shortLinkConfigService; + + @GetMapping("/link/list") + @ResponseBody + public ResultBean list(String key, + String url, + String dateFrom, + String dateTo, + Integer page, + Integer limit, + @RequestParam(required = false, defaultValue = "createDate") String orderBy, + @RequestParam(required = false, defaultValue = "desc") String orderDirection) { + return ResultBean.success(shortLinkConfigService.find(key, url, dateFrom, dateTo, page, limit, orderBy, orderDirection)); + } + + @GetMapping("/link/delete/{id}") + @ResponseBody + public ResultBean deleteById(@PathVariable Integer id) { + shortLinkConfigService.deleteById(id); + return ResultBean.success(); + } +} \ No newline at end of file diff --git a/src/main/java/im/zhaojun/zfile/controller/home/ShortLinkController.java b/src/main/java/im/zhaojun/zfile/controller/home/ShortLinkController.java new file mode 100644 index 0000000..0db9ca2 --- /dev/null +++ b/src/main/java/im/zhaojun/zfile/controller/home/ShortLinkController.java @@ -0,0 +1,72 @@ +package im.zhaojun.zfile.controller.home; + +import cn.hutool.core.util.RandomUtil; +import cn.hutool.core.util.URLUtil; +import im.zhaojun.zfile.model.dto.SystemConfigDTO; +import im.zhaojun.zfile.model.entity.ShortLinkConfig; +import im.zhaojun.zfile.model.support.ResultBean; +import im.zhaojun.zfile.service.ShortLinkConfigService; +import im.zhaojun.zfile.service.SystemConfigService; +import im.zhaojun.zfile.util.StringUtils; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.ResponseBody; + +import javax.annotation.Resource; + +/** + * 短链 Controller + * @author zhao + */ +@Controller +public class ShortLinkController { + + @Resource + private SystemConfigService systemConfigService; + + @Resource + private ShortLinkConfigService shortLinkConfigService; + + @GetMapping("/api/short-link") + @ResponseBody + public ResultBean shortLink(String driveId, String path) { + SystemConfigDTO systemConfig = systemConfigService.getSystemConfig(); + String domain = systemConfig.getDomain(); + + // 拼接直链地址. + String fullPath = StringUtils.removeDuplicateSeparator("/directlink/" + driveId + path); + + ShortLinkConfig shortLinkConfig; + String randomKey; + do { + // 获取短链 + randomKey = RandomUtil.randomString(6); + shortLinkConfig = shortLinkConfigService.findByKey(randomKey); + } while (shortLinkConfig != null); + + + shortLinkConfig = new ShortLinkConfig(); + shortLinkConfig.setKey(randomKey); + shortLinkConfig.setUrl(fullPath); + shortLinkConfigService.save(shortLinkConfig); + + String shortUrl = StringUtils.removeDuplicateSeparator(domain + "/s/" + randomKey); + return ResultBean.successData(shortUrl); + } + + @GetMapping("/s/{key}") + public String parseShortKey(@PathVariable String key) { + ShortLinkConfig shortLinkConfig = shortLinkConfigService.findByKey(key); + if (shortLinkConfig == null) { + throw new RuntimeException("此直链不存在或已失效."); + } + + SystemConfigDTO systemConfig = systemConfigService.getSystemConfig(); + String domain = systemConfig.getDomain(); + + String url = URLUtil.encode(StringUtils.removeDuplicateSeparator(domain + shortLinkConfig.getUrl())); + return "redirect:" + url; + + } +} diff --git a/src/main/java/im/zhaojun/zfile/model/entity/ShortLinkConfig.java b/src/main/java/im/zhaojun/zfile/model/entity/ShortLinkConfig.java new file mode 100644 index 0000000..96e7512 --- /dev/null +++ b/src/main/java/im/zhaojun/zfile/model/entity/ShortLinkConfig.java @@ -0,0 +1,25 @@ +package im.zhaojun.zfile.model.entity; + +import lombok.Data; + +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.GenerationType; +import javax.persistence.Id; +import java.util.Date; + +@Entity(name = "SHORT_LINK") +@Data +public class ShortLinkConfig { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Integer id; + + private String key; + + private String url; + + private Date createDate; + +} diff --git a/src/main/java/im/zhaojun/zfile/repository/ShortLinkConfigRepository.java b/src/main/java/im/zhaojun/zfile/repository/ShortLinkConfigRepository.java new file mode 100644 index 0000000..3431d1d --- /dev/null +++ b/src/main/java/im/zhaojun/zfile/repository/ShortLinkConfigRepository.java @@ -0,0 +1,52 @@ +package im.zhaojun.zfile.repository; + +import im.zhaojun.zfile.model.entity.ShortLinkConfig; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.JpaSpecificationExecutor; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +import java.util.Date; + +/** + * @author zhaojun + */ +@Repository +public interface ShortLinkConfigRepository extends JpaRepository, JpaSpecificationExecutor { + + /** + * 获取驱动器下的所有规则 + * + * @param key + * 驱动器 ID + */ + ShortLinkConfig findByKey(String key); + + @Query(nativeQuery = true, + value = " select * from SHORT_LINK where " + + " key like concat('%', :key,'%') " + + " and url like concat('%', :url,'%') " + + " and (:dateFrom is null or create_date >= :dateFrom" + + " and (:dateTo is null or create_date <= :dateTo) ", + countQuery = " select count(1) from SHORT_LINK where " + + " key like concat('%', :key,'%') " + + " and url like concat('%', :url,'%') " + + " and (:dateFrom is null or create_date >= :dateFrom" + + " and (:dateTo is null or create_date <= :dateTo) " + ) + // @Query(nativeQuery = true, + // value = " select * from SHORT_LINK where " + + // " key like concat('%', :key,'%') " + + // " and url like concat('%', :url,'%') " + + // " and (:dateFrom is null or date_format(create_date, '%Y-%m-%d') >= date_format(:dateFrom, '%Y-%m-%d'))" + + // " and (:dateTo is null or date_format(create_date, '%Y-%m-%d') <= date_format(:dateTo, '%Y-%m-%d')) ) ", + // countQuery = " select count(1) from SHORT_LINK where " + + // " key like concat('%', :key,'%') " + + // " and url like concat('%', :url,'%') " + + // " and (:dateFrom is null or date_format(create_date, '%Y-%m-%d') >= date_format(:dateFrom, '%Y-%m-%d'))" + + // " and (:dateTo is null or date_format(create_date, '%Y-%m-%d') <= date_format(:dateTo, '%Y-%m-%d')) ) " + // ) + Page findByPage(String key, String url, Date dateFrom, Date dateTo, Pageable pageable); +} \ No newline at end of file diff --git a/src/main/java/im/zhaojun/zfile/service/ShortLinkConfigService.java b/src/main/java/im/zhaojun/zfile/service/ShortLinkConfigService.java new file mode 100644 index 0000000..22afc89 --- /dev/null +++ b/src/main/java/im/zhaojun/zfile/service/ShortLinkConfigService.java @@ -0,0 +1,74 @@ +package im.zhaojun.zfile.service; + +import cn.hutool.core.date.DateUtil; +import cn.hutool.core.util.StrUtil; +import im.zhaojun.zfile.model.entity.ShortLinkConfig; +import im.zhaojun.zfile.repository.ShortLinkConfigRepository; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import javax.persistence.criteria.Predicate; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +@Service +public class ShortLinkConfigService { + + @Resource + private ShortLinkConfigRepository shortLinkConfigRepository; + + public ShortLinkConfig findByKey(String key) { + return shortLinkConfigRepository.findByKey(key); + } + + public void save(ShortLinkConfig shortLinkConfig) { + shortLinkConfig.setCreateDate(new Date()); + shortLinkConfigRepository.save(shortLinkConfig); + } + + public Page find(String key, + String url, + String dateFrom, + String dateTo, + Integer page, + Integer limit, + String orderBy, + String orderDirection) { + + Sort sort = Sort.by("desc".equals(orderDirection) ? Sort.Direction.DESC : Sort.Direction.ASC, orderBy); + Pageable pageable = PageRequest.of(page - 1, limit, sort); + + Specification specification = (root, criteriaQuery, criteriaBuilder) -> { + List predicates = new ArrayList<>(); + + if (StrUtil.isNotEmpty(dateFrom) && StrUtil.isNotEmpty(dateTo)) { + predicates.add(criteriaBuilder.between(root.get("createDate"), + DateUtil.parseDateTime(dateFrom + " 00:00:00"), + DateUtil.parseDateTime(dateTo + " 23:59:59"))); + } + + if (StrUtil.isNotEmpty(key)) { + predicates.add(criteriaBuilder.like(root.get("key"), "%" + key + '%')); + } + + if (StrUtil.isNotEmpty(url)) { + predicates.add(criteriaBuilder.like(root.get("url"), "%" + url + '%')); + } + + return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])); + }; + return shortLinkConfigRepository.findAll(specification, pageable); + } + + public void deleteById(Integer id) { + shortLinkConfigRepository.deleteById(id); + } + + +} \ No newline at end of file