feat: 移植工程
This commit is contained in:
6
blog-service/Dockerfile
Normal file
6
blog-service/Dockerfile
Normal file
@@ -0,0 +1,6 @@
|
||||
FROM docker-0.unsee.tech/openjdk:11-jdk-slim
|
||||
ARG JAR_FILE=target/*.jar
|
||||
COPY $JAR_FILE app.jar
|
||||
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
|
||||
RUN echo 'Asia/Shanghai' > /etc/timezone
|
||||
ENTRYPOINT ["java","-jar","/app.jar"]
|
||||
1
blog-service/pom.xml
Normal file
1
blog-service/pom.xml
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
25
blog-service/src/main/java/com/cxx/blog/dao/BlogDao.java
Normal file
25
blog-service/src/main/java/com/cxx/blog/dao/BlogDao.java
Normal 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();
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
36
blog-service/src/main/java/com/cxx/blog/util/BlogUtils.java
Normal file
36
blog-service/src/main/java/com/cxx/blog/util/BlogUtils.java
Normal 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;
|
||||
}
|
||||
}
|
||||
59
blog-service/src/main/java/com/cxx/blog/util/IpUtils.java
Normal file
59
blog-service/src/main/java/com/cxx/blog/util/IpUtils.java
Normal 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;
|
||||
}
|
||||
}
|
||||
11
blog-service/src/main/resources/application-dev.yml
Normal file
11
blog-service/src/main/resources/application-dev.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
spring:
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://127.0.0.1:3306/sweet_hut?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8&useSSL=false
|
||||
username: root
|
||||
password: 123456
|
||||
|
||||
logging:
|
||||
level:
|
||||
root: info
|
||||
config:
|
||||
13
blog-service/src/main/resources/application-docker.yml
Normal file
13
blog-service/src/main/resources/application-docker.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
spring:
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://mysql:3306/sweet_hut?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8&useSSL=false
|
||||
username: docker
|
||||
password: 19940822Cxx
|
||||
|
||||
logging:
|
||||
fluentd:
|
||||
host: fluent-bit
|
||||
port: 24224
|
||||
level:
|
||||
root: info
|
||||
12
blog-service/src/main/resources/application-prod.yml
Normal file
12
blog-service/src/main/resources/application-prod.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
spring:
|
||||
datasource:
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://127.0.0.1:3306/sweet_hut?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8&useSSL=false
|
||||
username: cxx
|
||||
password: 19940822Cxx@1213
|
||||
|
||||
logging:
|
||||
level:
|
||||
root: info
|
||||
config:
|
||||
classpath:logback-spring-drop.xml
|
||||
20
blog-service/src/main/resources/application.yml
Normal file
20
blog-service/src/main/resources/application.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
server:
|
||||
port: 8082
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: @project.artifactId@
|
||||
version: @project.version@
|
||||
profiles:
|
||||
active: dev
|
||||
|
||||
# mybatis plus mapper路径
|
||||
mybatis-plus:
|
||||
# mybatis plus
|
||||
mapper-locations: classpath*:/mapper/**/*.xml
|
||||
configuration:
|
||||
log-impl:
|
||||
org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
|
||||
web-starter:
|
||||
base-package: com.cxx.blog
|
||||
120
blog-service/src/main/resources/logback-spring-drop.xml
Normal file
120
blog-service/src/main/resources/logback-spring-drop.xml
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration scan="true" scanPeriod="10 seconds">
|
||||
|
||||
<contextName>logback</contextName>
|
||||
|
||||
<property name="log.path" value="logs/blogService"/>
|
||||
|
||||
<!--控制台日志格式:彩色日志-->
|
||||
<!-- magenta:洋红 -->
|
||||
<!-- boldMagenta:粗红-->
|
||||
<!-- cyan:青色 -->
|
||||
<!-- white:白色 -->
|
||||
<!-- magenta:洋红 -->
|
||||
<property name="CONSOLE_LOG_PATTERN"
|
||||
value="%yellow(%date{yyyy-MM-dd HH:mm:ss}) |%highlight(%-5level) |%blue(%thread) |%blue(%file:%line) |%green(%logger) |%cyan(%msg%n)"/>
|
||||
|
||||
<!--文件日志格式-->
|
||||
<property name="FILE_LOG_PATTERN"
|
||||
value="%date{yyyy-MM-dd HH:mm:ss} |%-5level |%thread |%file:%line |%logger |%msg%n"/>
|
||||
|
||||
<!--编码-->
|
||||
<property name="ENCODING"
|
||||
value="UTF-8"/>
|
||||
|
||||
<!--输出到控制台-->
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<!--日志级别-->
|
||||
<level>DEBUG</level>
|
||||
</filter>
|
||||
<encoder>
|
||||
<!--日志格式-->
|
||||
<Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
|
||||
<!--日志字符集-->
|
||||
<charset>${ENCODING}</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!--输出到文件-->
|
||||
<appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!--日志过滤器:此日志文件只记录INFO级别的-->
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>INFO</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
<!-- 正在记录的日志文件的路径及文件名 -->
|
||||
<file>${log.path}/log_info.log</file>
|
||||
<encoder>
|
||||
<pattern>${FILE_LOG_PATTERN}</pattern>
|
||||
<charset>${ENCODING}</charset>
|
||||
</encoder>
|
||||
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<!-- 每天日志归档路径以及格式 -->
|
||||
<fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||
<maxFileSize>500MB</maxFileSize>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
<!--日志文件保留天数-->
|
||||
<maxHistory>15</maxHistory>
|
||||
</rollingPolicy>
|
||||
</appender>
|
||||
|
||||
<appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!-- 日志过滤器:此日志文件只记录WARN级别的 -->
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>WARN</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
<!-- 正在记录的日志文件的路径及文件名 -->
|
||||
<file>${log.path}/log_warn.log</file>
|
||||
<encoder>
|
||||
<pattern>${FILE_LOG_PATTERN}</pattern>
|
||||
<charset>${ENCODING}</charset> <!-- 此处设置字符集 -->
|
||||
</encoder>
|
||||
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||
<maxFileSize>100MB</maxFileSize>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
<!--日志文件保留天数-->
|
||||
<maxHistory>15</maxHistory>
|
||||
</rollingPolicy>
|
||||
</appender>
|
||||
|
||||
<appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
|
||||
<!-- 日志过滤器:此日志文件只记录ERROR级别的 -->
|
||||
<filter class="ch.qos.logback.classic.filter.LevelFilter">
|
||||
<level>ERROR</level>
|
||||
<onMatch>ACCEPT</onMatch>
|
||||
<onMismatch>DENY</onMismatch>
|
||||
</filter>
|
||||
<!-- 正在记录的日志文件的路径及文件名 -->
|
||||
<file>${log.path}/log_error.log</file>
|
||||
<encoder>
|
||||
<pattern>${FILE_LOG_PATTERN}</pattern>
|
||||
<charset>${ENCODING}</charset> <!-- 此处设置字符集 -->
|
||||
</encoder>
|
||||
<!-- 日志记录器的滚动策略,按日期,按大小记录 -->
|
||||
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
|
||||
<fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
|
||||
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
|
||||
<maxFileSize>100MB</maxFileSize>
|
||||
</timeBasedFileNamingAndTriggeringPolicy>
|
||||
<!--日志文件保留天数-->
|
||||
<maxHistory>15</maxHistory>
|
||||
</rollingPolicy>
|
||||
</appender>
|
||||
|
||||
<root level="INFO">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="INFO_FILE"/>
|
||||
<appender-ref ref="WARN_FILE"/>
|
||||
<appender-ref ref="ERROR_FILE"/>
|
||||
</root>
|
||||
|
||||
</configuration>
|
||||
90
blog-service/src/main/resources/mapper/blogMapper.xml
Normal file
90
blog-service/src/main/resources/mapper/blogMapper.xml
Normal file
@@ -0,0 +1,90 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.cxx.blog.dao.BlogDao">
|
||||
<select id="queryBlogByPage" resultType="com.cxx.common.dto.blog.BlogDto">
|
||||
SELECT a.id AS id,
|
||||
a.title AS title,
|
||||
a.top_value AS topValue,
|
||||
a.is_great AS isGreat,
|
||||
b.NAME AS category,
|
||||
a.summary AS summary,
|
||||
a.word_count AS wordCount,
|
||||
a.read_duration AS readDuration,
|
||||
COUNT(c.id) AS visitCount,
|
||||
a.create_time AS createTime,
|
||||
a.update_time AS updateTime
|
||||
FROM blog a
|
||||
LEFT JOIN blog_category b ON b.id = a.category_id
|
||||
LEFT JOIN blog_visit c ON c.blog_id = a.id
|
||||
GROUP BY a.id
|
||||
ORDER BY a.top_value DESC,
|
||||
a.update_time DESC
|
||||
</select>
|
||||
|
||||
<select id="queryBlogByCondition" resultType="com.cxx.common.dto.blog.BlogDto">
|
||||
SELECT a.id AS id,
|
||||
a.title AS title,
|
||||
a.top_value AS topValue,
|
||||
a.is_great AS isGreat,
|
||||
b.name AS category,
|
||||
a.summary AS summary,
|
||||
c.content AS content,
|
||||
a.word_count AS wordCount,
|
||||
a.read_duration AS readDuration,
|
||||
a.create_time AS createTime,
|
||||
a.update_time AS updateTime
|
||||
FROM blog a
|
||||
LEFT JOIN blog_category b on a.category_id = b.id
|
||||
LEFT JOIN blog_content c on a.content_id = c.id
|
||||
<where>
|
||||
<if test="query.category != null and query.category != ''">
|
||||
b.name = #{query.category}
|
||||
</if>
|
||||
<if test="query.title != null and query.title != ''">
|
||||
AND a.title LIKE CONCAT('%',#{query.title},'%')
|
||||
</if>
|
||||
<if test="query.year != null">
|
||||
AND YEAR(a.create_time) = #{query.year}
|
||||
</if>
|
||||
</where>
|
||||
ORDER BY a.update_time DESC
|
||||
</select>
|
||||
|
||||
<select id="queryBlogById" resultType="com.cxx.common.dto.blog.BlogDto">
|
||||
SELECT a.id AS id,
|
||||
a.title AS title,
|
||||
a.top_value AS topValue,
|
||||
a.is_great AS isGreat,
|
||||
b.NAME AS category,
|
||||
a.summary AS summary,
|
||||
c.content AS content,
|
||||
a.word_count AS wordCount,
|
||||
a.read_duration AS readDuration,
|
||||
COUNT(d.id) AS visitCount,
|
||||
a.create_time AS createTime,
|
||||
a.update_time AS updateTime
|
||||
FROM blog a
|
||||
LEFT JOIN blog_category b ON b.id = a.category_id
|
||||
LEFT JOIN blog_content c ON c.id = a.content_id
|
||||
LEFT JOIN blog_visit d ON d.blog_id = a.id
|
||||
WHERE a.id = #{id}
|
||||
LIMIT 1
|
||||
</select>
|
||||
|
||||
<select id="queryBlogCategory" resultType="com.cxx.common.dto.blog.BlogCategoryDto">
|
||||
SELECT b.name AS name,
|
||||
count(b.name) AS count
|
||||
FROM blog a
|
||||
LEFT JOIN blog_category b
|
||||
ON a.category_id = b.id
|
||||
GROUP BY b.name
|
||||
</select>
|
||||
|
||||
<select id="queryLatestBlog" resultType="com.cxx.common.dto.blog.BlogLatestDto">
|
||||
SELECT id AS id,
|
||||
title AS title
|
||||
FROM blog
|
||||
ORDER BY update_time DESC
|
||||
LIMIT 5
|
||||
</select>
|
||||
</mapper>
|
||||
18
blog-service/src/test/java/com/cxx/blog/BlogServiceTest.java
Normal file
18
blog-service/src/test/java/com/cxx/blog/BlogServiceTest.java
Normal file
@@ -0,0 +1,18 @@
|
||||
package com.cxx.blog;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
/**
|
||||
* @Author: Cxx
|
||||
* @Date: 2024/9/22 0:17
|
||||
* @Description:
|
||||
*/
|
||||
@SpringBootTest
|
||||
public class BlogServiceTest {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user