feat: 移植工程

This commit is contained in:
2025-06-10 09:54:52 +08:00
commit a2de21b092
277 changed files with 11116 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
package com.cxx.blog;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan(basePackages = {"com.cxx.common.mapper", "com.cxx.blog.dao"})
public class BlogServiceApplication {
public static void main(String[] args) {
SpringApplication.run(BlogServiceApplication.class, args);
}
}

View File

@@ -0,0 +1,71 @@
package com.cxx.blog.config;
import com.cxx.blog.service.BlogService;
import com.cxx.common.entity.BlogVisit;
import com.cxx.blog.util.IpUtils;
import eu.bitwalker.useragentutils.Browser;
import eu.bitwalker.useragentutils.OperatingSystem;
import eu.bitwalker.useragentutils.UserAgent;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
/**
* 利用AOP监控博客访问
* 1. @Before前置通知在方法执行之前执行
* 2. @After后置通知在方法执行之后执行
* 3. @AfterRunning返回通知在方法返回结果之后执行
* 4. @AfterThrowing异常通知在方法抛出异常之后执行
* 5. @Around环绕通知围绕着方法执行
*/
@Component
@Aspect
@Slf4j
public class BlogVisitMonitor {
@Resource
private BlogService blogService;
/**
* 定义切面
* 指定需要统计的包
*/
@Pointcut("execution(* com.cxx.blog.controller.BlogController.*(..))")
public void pointCut() {
}
/**
* 只有正常返回才会执行此方法
* 如果程序执行失败,则不执行此方法
*/
@AfterReturning(returning = "returnVal", pointcut = "pointCut()")
public void doAfterReturning(JoinPoint joinPoint, Object returnVal) {
// 获取接收到的HTTP请求信息
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String agent = request.getHeader("User-Agent");
UserAgent userAgent = UserAgent.parseUserAgentString(agent);
OperatingSystem os = userAgent.getOperatingSystem();
Browser browser = userAgent.getBrowser();
String uri = request.getRequestURI();
BlogVisit blogVisit = new BlogVisit();
blogVisit.setIp(IpUtils.getIpAddress(request));
blogVisit.setOs(os.getName());
blogVisit.setBrowser(browser.getName() + "-" + userAgent.getBrowserVersion());
blogVisit.setUri(uri);
blogVisit.setBlogId(0L);
if (blogVisit.getUri().contains("content")) {
blogVisit.setBlogId(Long.valueOf(uri.split("/")[3]));
}
blogService.addBlogVisit(blogVisit);
}
}

View File

@@ -0,0 +1,62 @@
package com.cxx.blog.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cxx.blog.service.BlogService;
import com.cxx.common.ReadView;
import com.cxx.common.dto.blog.BlogCategoryDto;
import com.cxx.common.dto.blog.BlogDto;
import com.cxx.common.dto.blog.BlogLatestDto;
import com.cxx.common.dto.blog.BlogStatsDto;
import com.cxx.common.vo.blog.BlogQueryVo;
import com.fasterxml.jackson.annotation.JsonView;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/blog")
@Tag(name = "查看博客")
public class BlogController {
@Resource
private BlogService blogService;
@Operation(summary = "分页查询博客")
@GetMapping("/page")
public IPage<BlogDto> queryBlogByPage(@RequestParam("currentPage") Integer currentPage,
@RequestParam("pageSize") Integer pageSize) {
return blogService.queryBlogByPage(currentPage, pageSize);
}
@Operation(summary = "条件查询博客")
@GetMapping("/condition")
public @JsonView(ReadView.class) List<BlogDto> queryBlogByCondition(BlogQueryVo query) {
return blogService.queryBlogByCondition(query);
}
@Operation(summary = "查询博客内容")
@GetMapping("/content/{id}")
public @JsonView(ReadView.class) BlogDto queryBlogById(@PathVariable("id") long id) {
return blogService.queryBlogById(id);
}
@Operation(summary = "查询博客分类")
@GetMapping("/category")
public List<BlogCategoryDto> queryBlogCategory() {
return blogService.queryBlogCategory();
}
@Operation(summary = "查询博客统计信息")
@GetMapping("/stats")
public BlogStatsDto queryBlogStats() {
return blogService.queryBlogStats();
}
@Operation(summary = "查询近期博客")
@GetMapping("/latest")
public List<BlogLatestDto> queryLatestBlog() {
return blogService.queryLatestBlog();
}
}

View File

@@ -0,0 +1,25 @@
package com.cxx.blog.dao;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cxx.common.dto.blog.BlogCategoryDto;
import com.cxx.common.dto.blog.BlogDto;
import com.cxx.common.dto.blog.BlogLatestDto;
import com.cxx.common.entity.Blog;
import com.cxx.common.vo.blog.BlogQueryVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@Mapper
public interface BlogDao {
IPage<BlogDto> queryBlogByPage(IPage<Blog> page);
List<BlogDto> queryBlogByCondition(@Param("query") BlogQueryVo query);
BlogDto queryBlogById(@Param("id") Long id);
List<BlogCategoryDto> queryBlogCategory();
List<BlogLatestDto> queryLatestBlog();
}

View File

@@ -0,0 +1,28 @@
package com.cxx.blog.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.cxx.common.dto.blog.BlogCategoryDto;
import com.cxx.common.dto.blog.BlogDto;
import com.cxx.common.dto.blog.BlogLatestDto;
import com.cxx.common.dto.blog.BlogStatsDto;
import com.cxx.common.entity.BlogVisit;
import com.cxx.common.vo.blog.BlogQueryVo;
import java.util.List;
public interface BlogService {
IPage<BlogDto> queryBlogByPage(Integer currentPage, Integer pageSize);
List<BlogDto> queryBlogByCondition(BlogQueryVo query);
BlogDto queryBlogById(Long id);
List<BlogCategoryDto> queryBlogCategory();
BlogStatsDto queryBlogStats();
List<BlogLatestDto> queryLatestBlog();
void addBlogVisit(BlogVisit blogVisit);
}

View File

@@ -0,0 +1,73 @@
package com.cxx.blog.service.impl;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cxx.blog.dao.BlogDao;
import com.cxx.blog.service.BlogService;
import com.cxx.common.dto.blog.BlogCategoryDto;
import com.cxx.common.dto.blog.BlogDto;
import com.cxx.common.dto.blog.BlogLatestDto;
import com.cxx.common.dto.blog.BlogStatsDto;
import com.cxx.common.entity.BlogVisit;
import com.cxx.common.mapper.BlogCategoryMapper;
import com.cxx.common.mapper.BlogMapper;
import com.cxx.common.mapper.BlogVisitMapper;
import com.cxx.common.vo.blog.BlogQueryVo;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class BlogServiceImpl implements BlogService {
@Resource
private BlogDao blogDao;
@Resource
private BlogMapper blogMapper;
@Resource
private BlogCategoryMapper categoryMapper;
@Resource
private BlogVisitMapper visitMapper;
@Override
public IPage<BlogDto> queryBlogByPage(Integer currentPage, Integer pageSize) {
return blogDao.queryBlogByPage(new Page<>(currentPage, pageSize));
}
@Override
public List<BlogDto> queryBlogByCondition(BlogQueryVo query) {
return blogDao.queryBlogByCondition(query);
}
@Override
public BlogDto queryBlogById(Long id) {
return blogDao.queryBlogById(id);
}
@Override
public List<BlogCategoryDto> queryBlogCategory() {
return blogDao.queryBlogCategory();
}
@Override
public BlogStatsDto queryBlogStats() {
BlogStatsDto blogStats = new BlogStatsDto();
blogStats.setBlogCount(blogMapper.selectCount(null));
blogStats.setCategoryCount(categoryMapper.selectCount(null));
return blogStats;
}
@Override
public List<BlogLatestDto> queryLatestBlog() {
return blogDao.queryLatestBlog();
}
@Override
public void addBlogVisit(BlogVisit blogVisit) {
visitMapper.insert(blogVisit);
}
}

View File

@@ -0,0 +1,36 @@
package com.cxx.blog.util;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class BlogUtils {
public static File multipartFileToFile(MultipartFile multipartFile) {
if (multipartFile.getOriginalFilename() == null) {
return null;
}
File file = new File(multipartFile.getOriginalFilename());
try {
InputStream ins = multipartFile.getInputStream();
OutputStream os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
ins.close();
} catch (Exception e) {
e.printStackTrace();
}
return file;
}
}

View File

@@ -0,0 +1,59 @@
package com.cxx.blog.util;
import jakarta.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class IpUtils {
private static final String UNKNOWN = "unknown";
private static final String LOCALHOST_IP = "127.0.0.1";
// 客户端与服务器同为一台机器,获取的 ip 有时候是 ipv6 格式
private static final String LOCALHOST_IPV6 = "0:0:0:0:0:0:0:1";
private static final String SEPARATOR = ",";
/**
* 根据 HttpServletRequest 获取 IP
* @param request 请求
* @return ip
*/
public static String getIpAddress(HttpServletRequest request) {
if (request == null) {
return "unknown";
}
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.isEmpty() || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.isEmpty() || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Forwarded-For");
}
if (ip == null || ip.isEmpty() || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.isEmpty() || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Real-IP");
}
if (ip == null || ip.isEmpty() || UNKNOWN.equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
if (LOCALHOST_IP.equalsIgnoreCase(ip) || LOCALHOST_IPV6.equalsIgnoreCase(ip)) {
// 根据网卡取本机配置的 IP
InetAddress iNet = null;
try {
iNet = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
if (iNet != null)
ip = iNet.getHostAddress();
}
}
// 对于通过多个代理的情况,分割出第一个 IP
if (ip != null && ip.length() > 15) {
if (ip.indexOf(SEPARATOR) > 0) {
ip = ip.substring(0, ip.indexOf(SEPARATOR));
}
}
return LOCALHOST_IPV6.equals(ip) ? LOCALHOST_IP : ip;
}
}