feat: 移植工程
This commit is contained in:
38
admin-service/.gitignore
vendored
Normal file
38
admin-service/.gitignore
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea/modules.xml
|
||||
.idea/jarRepositories.xml
|
||||
.idea/compiler.xml
|
||||
.idea/libraries/
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### Eclipse ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
|
||||
### Mac OS ###
|
||||
.DS_Store
|
||||
6
admin-service/Dockerfile
Normal file
6
admin-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"]
|
||||
58
admin-service/pom.xml
Normal file
58
admin-service/pom.xml
Normal file
@@ -0,0 +1,58 @@
|
||||
<?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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.cxx</groupId>
|
||||
<artifactId>sweet-hut-service</artifactId>
|
||||
<version>2.0.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>admin-service</artifactId>
|
||||
<version>2.0.0</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.cxx</groupId>
|
||||
<artifactId>common</artifactId>
|
||||
<version>2.0.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>org.checkerframework</groupId>-->
|
||||
<!-- <artifactId>checker-qual</artifactId>-->
|
||||
<!-- <version>2.0.0</version>-->
|
||||
<!-- <scope>compile</scope>-->
|
||||
<!-- </dependency>-->
|
||||
|
||||
<!-- 服务器监控 -->
|
||||
<dependency>
|
||||
<groupId>com.github.oshi</groupId>
|
||||
<artifactId>oshi-core</artifactId>
|
||||
<version>6.4.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- influxdb -->
|
||||
<dependency>
|
||||
<groupId>com.influxdb</groupId>
|
||||
<artifactId>influxdb-client-java</artifactId>
|
||||
<version>7.2.0</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<!-- <build>-->
|
||||
<!-- <plugins>-->
|
||||
<!-- <plugin>-->
|
||||
<!-- <groupId>org.springframework.boot</groupId>-->
|
||||
<!-- <artifactId>spring-boot-maven-plugin</artifactId>-->
|
||||
<!-- </plugin>-->
|
||||
<!-- </plugins>-->
|
||||
<!-- </build>-->
|
||||
</project>
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.cxx.admin;
|
||||
|
||||
import org.mybatis.spring.annotation.MapperScan;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||
|
||||
@SpringBootApplication
|
||||
@MapperScan(basePackages = {"com.cxx.common.mapper", "com.cxx.admin.mapper", "com.cxx.admin.dao"})
|
||||
@EnableScheduling
|
||||
public class AdminServiceApplication {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(AdminServiceApplication.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package com.cxx.admin.config;
|
||||
|
||||
import com.cxx.admin.constant.FileConstant;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
/**
|
||||
* @Author: Cxx
|
||||
* @Date: 2024/9/22 10:57
|
||||
* @Description:
|
||||
*/
|
||||
@Configuration
|
||||
public class WebMvcConfig implements WebMvcConfigurer {
|
||||
@Value("${file.path}")
|
||||
private String filePath;
|
||||
|
||||
@Value("${file.log-path}")
|
||||
private String logFilePath;
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("/" + FileConstant.FILE_URL_PREFIX + "/**")
|
||||
.addResourceLocations("file:" + filePath);
|
||||
|
||||
registry.addResourceHandler("/" + FileConstant.FILE_LOG_PREFIX + "/**")
|
||||
.addResourceLocations("file:" + logFilePath);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.cxx.admin.constant;
|
||||
|
||||
public interface FileConstant {
|
||||
String FILE_NAME_SPLIT = "_";
|
||||
String FILE_URL_PREFIX = "files";
|
||||
String FILE_LOG_PREFIX = "logs";
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.cxx.admin.controller;
|
||||
|
||||
import com.cxx.admin.service.AccountService;
|
||||
import com.cxx.common.ReadView;
|
||||
import com.cxx.common.WriteView;
|
||||
import com.cxx.admin.dto.user.AccountDto;
|
||||
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.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/account")
|
||||
@Tag(name = "账户管理")
|
||||
public class AccountController {
|
||||
@Resource
|
||||
private AccountService accountService;
|
||||
|
||||
@Operation(summary = "查询用户账号")
|
||||
@GetMapping("")
|
||||
public @JsonView(ReadView.class) List<AccountDto> queryAccountList() {
|
||||
return accountService.queryAccountList();
|
||||
}
|
||||
|
||||
@Operation(summary = "注册账户")
|
||||
@PostMapping("")
|
||||
public Boolean registerAccount(@JsonView(WriteView.class) @Validated @RequestBody AccountDto accountDto) {
|
||||
return accountService.registerAccount(accountDto);
|
||||
}
|
||||
|
||||
@Operation(summary = "注销账户")
|
||||
@DeleteMapping("/{id}")
|
||||
public Boolean deleteAccount(@PathVariable("id") Long id) {
|
||||
return accountService.deleteAccount(id);
|
||||
}
|
||||
|
||||
@Operation(summary = "更改账户密码")
|
||||
@PutMapping("/password/{id}")
|
||||
public Boolean updateAccountPassword(@PathVariable("id") Long id,
|
||||
@RequestParam String oldPassword,
|
||||
@RequestParam String newPassword) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.cxx.admin.controller;
|
||||
|
||||
import com.cxx.admin.service.BillManageService;
|
||||
import com.cxx.common.WriteView;
|
||||
import com.cxx.common.dto.bill.BillCategoryDto;
|
||||
import com.cxx.common.dto.bill.BillItemDto;
|
||||
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.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/bill-manage")
|
||||
@Tag(name = "账单管理")
|
||||
public class BillManageController {
|
||||
@Resource
|
||||
private BillManageService billManageService;
|
||||
|
||||
@Operation(summary = "新增支付账户")
|
||||
@PostMapping("/pay")
|
||||
public Boolean addBillPay(@JsonView(WriteView.class) @RequestBody BillItemDto billItemDto) {
|
||||
return billManageService.addBillPay(billItemDto);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新支付账户")
|
||||
@PutMapping("/pay/{id}")
|
||||
public Boolean updateBillPay(@PathVariable("id") Long id,
|
||||
@JsonView(WriteView.class) @RequestBody BillItemDto billItemDto) {
|
||||
return billManageService.updateBillPay(id, billItemDto);
|
||||
}
|
||||
|
||||
@Operation(summary = "新增账本类型")
|
||||
@PostMapping("/book")
|
||||
public Boolean addBillBook(@JsonView(WriteView.class) @RequestBody BillItemDto billItemDto) {
|
||||
return billManageService.addBillBook(billItemDto);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新账本类型")
|
||||
@PutMapping("/book/{id}")
|
||||
public Boolean updateBillBook(@PathVariable("id") Long id,
|
||||
@JsonView(WriteView.class) @RequestBody BillItemDto billItemDto) {
|
||||
return billManageService.updateBillBook(id, billItemDto);
|
||||
}
|
||||
|
||||
@Operation(summary = "新增账单类型")
|
||||
@PostMapping("/category")
|
||||
public Boolean addBillCategory(@RequestBody BillCategoryDto billCategoryDto) {
|
||||
return billManageService.addBillCategory(billCategoryDto);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新账单类型")
|
||||
@PutMapping("/category/{id}")
|
||||
public Boolean updateBillCategory(@PathVariable("id") Long id,
|
||||
@RequestBody BillCategoryDto billCategoryDto) {
|
||||
return billManageService.updateBillCategory(id, billCategoryDto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.cxx.admin.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.cxx.admin.service.BlogManageService;
|
||||
import com.cxx.common.ReadView;
|
||||
import com.cxx.common.WriteView;
|
||||
import com.cxx.common.dto.blog.BlogCategoryDto;
|
||||
import com.cxx.common.dto.blog.BlogDto;
|
||||
import com.cxx.common.dto.blog.BlogVisitDto;
|
||||
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-manage")
|
||||
@Tag(name = "博客管理")
|
||||
public class BlogManageController {
|
||||
@Resource
|
||||
private BlogManageService blogManageService;
|
||||
|
||||
@Operation(summary = "分页查询博客")
|
||||
@GetMapping("/page")
|
||||
public IPage<BlogDto> queryBlogByPage(@RequestParam("currentPage") Integer currentPage,
|
||||
@RequestParam("pageSize") Integer pageSize) {
|
||||
return blogManageService.queryBlogByPage(currentPage, pageSize);
|
||||
}
|
||||
|
||||
@Operation(summary = "查询博客内容")
|
||||
@GetMapping("/content/{id}")
|
||||
public @JsonView(ReadView.class) BlogDto queryBlogById(@PathVariable("id") long id) {
|
||||
return blogManageService.queryBlogById(id);
|
||||
}
|
||||
|
||||
@Operation(summary = "查询博客分类")
|
||||
@GetMapping("/category")
|
||||
public List<BlogCategoryDto> queryBlogCategory() {
|
||||
return blogManageService.queryBlogCategory();
|
||||
}
|
||||
|
||||
@Operation(summary = "增加博客")
|
||||
@PostMapping("")
|
||||
public Boolean addBlog(@JsonView(WriteView.class) @RequestBody BlogDto blog) {
|
||||
return blogManageService.addBlog(blog);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新博客")
|
||||
@PutMapping("/{id}")
|
||||
public Boolean updateBlog(@PathVariable("id") long id,
|
||||
@JsonView(WriteView.class) @RequestBody BlogDto blog) {
|
||||
return blogManageService.updateBlog(id, blog);
|
||||
}
|
||||
|
||||
@Operation(summary = "删除博客")
|
||||
@DeleteMapping("/{id}")
|
||||
public Boolean deleteBlog(@PathVariable("id") long id) {
|
||||
return blogManageService.deleteBlog(id);
|
||||
}
|
||||
|
||||
@Operation(summary = "查询博客访问")
|
||||
@GetMapping("/visit")
|
||||
public IPage<BlogVisitDto> queryBlogVisit(@RequestParam("currentPage") Integer currentPage,
|
||||
@RequestParam("pageSize") Integer pageSize) {
|
||||
return blogManageService.queryBlogVisit(currentPage, pageSize);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.cxx.admin.controller;
|
||||
|
||||
import com.cxx.admin.service.BudgetManageService;
|
||||
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.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/budget-manage")
|
||||
@Tag(name = "预算管理")
|
||||
public class BudgetManageController {
|
||||
@Resource
|
||||
private BudgetManageService budgetManageService;
|
||||
|
||||
@Operation(summary = "新增预算类别")
|
||||
@PostMapping("/category")
|
||||
public Boolean addBudgetCategory(@RequestParam String category) {
|
||||
return budgetManageService.addBudgetCategory(category);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新预算类别")
|
||||
@PutMapping("/category/{id}")
|
||||
public Boolean updateBudgetCategory(@PathVariable("id") Long id, @RequestParam String category) {
|
||||
return budgetManageService.updateBudgetCategory(id, category);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.cxx.admin.controller;
|
||||
|
||||
import com.cxx.admin.dto.file.ChunkInfoDto;
|
||||
import com.cxx.admin.dto.file.ChunkResultDto;
|
||||
import com.cxx.admin.dto.file.FileInfoDto;
|
||||
import com.cxx.admin.service.FileService;
|
||||
import com.cxx.admin.dto.file.FileRecordDto;
|
||||
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 org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/file")
|
||||
@Tag(name = "文件管理")
|
||||
public class FileController {
|
||||
@Resource
|
||||
private FileService fileService;
|
||||
|
||||
@Operation(summary = "上传文件")
|
||||
@PostMapping(value = "", headers = "content-type=multipart/form-data")
|
||||
public FileRecordDto uploadFile(@RequestPart("file") MultipartFile file,
|
||||
@RequestParam("path") String path,
|
||||
@RequestParam("md5") String md5) {
|
||||
return fileService.uploadFile(file, path, md5);
|
||||
}
|
||||
|
||||
@Operation(summary = "上传文件块")
|
||||
@PostMapping("/chunk")
|
||||
public Boolean uploadChunk(ChunkInfoDto chunkInfo,
|
||||
String path) {
|
||||
return fileService.uploadChunk(chunkInfo, path);
|
||||
}
|
||||
|
||||
@Operation(summary = "验证当前文件块是否上传")
|
||||
@GetMapping("/chunk")
|
||||
public ChunkResultDto checkChunk(@RequestParam String identifier,
|
||||
@RequestParam String filename,
|
||||
@RequestParam String path) {
|
||||
return fileService.checkChunk(identifier, filename, path);
|
||||
}
|
||||
|
||||
@Operation(summary = "删除当前已上传的文件块")
|
||||
@DeleteMapping("/chunk")
|
||||
public Boolean deleteChunk(@RequestParam String identifier,
|
||||
@RequestParam String path) {
|
||||
return fileService.deleteChunk(identifier, path);
|
||||
}
|
||||
|
||||
@Operation(summary = "合并文件")
|
||||
@PostMapping("/chunk/merge")
|
||||
public FileRecordDto mergeFile(@RequestParam String filename,
|
||||
@RequestParam String path) {
|
||||
return fileService.mergeFile(filename, path);
|
||||
}
|
||||
|
||||
@Operation(summary = "获取文件夹目录")
|
||||
@GetMapping("/catalog")
|
||||
public List<FileInfoDto> getFolderInfo(@RequestParam String folderName) {
|
||||
return fileService.getFolderInfo(folderName);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.cxx.admin.controller;
|
||||
|
||||
import com.cxx.admin.dto.server.*;
|
||||
import com.cxx.admin.service.ServerMonitorService;
|
||||
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("/server-monitor")
|
||||
@Tag(name = "服务器监控")
|
||||
public class ServerMonitorController {
|
||||
@Resource
|
||||
private ServerMonitorService serverMonitorService;
|
||||
|
||||
@Operation(summary = "系统信息")
|
||||
@GetMapping("/system/info")
|
||||
public SystemInfoDto getSystemInfo() {
|
||||
return serverMonitorService.getSystemInfo();
|
||||
}
|
||||
|
||||
@Operation(summary = "系统指标")
|
||||
@GetMapping("/system/metrics")
|
||||
public List<SystemMetricsDto> querySystemMetrics(@RequestParam String range) {
|
||||
return serverMonitorService.querySystemMetrics(range);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.cxx.admin.controller;
|
||||
|
||||
import com.cxx.common.dto.user.SessionDto;
|
||||
import com.cxx.admin.service.SessionService;
|
||||
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.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/session")
|
||||
@Tag(name = "会话管理")
|
||||
public class SessionController {
|
||||
@Resource
|
||||
private SessionService sessionService;
|
||||
|
||||
@Operation(summary = "创建会话")
|
||||
@PostMapping("")
|
||||
public SessionDto createSession(@RequestParam String name,
|
||||
@RequestParam String password) {
|
||||
return sessionService.create(name, password);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.cxx.admin.controller;
|
||||
|
||||
import com.cxx.admin.service.UserService;
|
||||
import com.cxx.common.ReadView;
|
||||
import com.cxx.common.WriteView;
|
||||
import com.cxx.common.dto.user.UserDto;
|
||||
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.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/user")
|
||||
@Tag(name = "用户管理")
|
||||
public class UserController {
|
||||
@Resource
|
||||
private UserService userService;
|
||||
|
||||
@Operation(summary = "查询用户")
|
||||
@GetMapping("/{id}")
|
||||
public @JsonView(ReadView.class) UserDto queryUser(@PathVariable("id") Long id) {
|
||||
return userService.queryUser(id);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新用户")
|
||||
@PutMapping("/{id}")
|
||||
public Boolean updateUser(@PathVariable("id") Long id,
|
||||
@JsonView(WriteView.class) @Validated @RequestBody UserDto userDto) {
|
||||
return userService.updateUser(id, userDto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.cxx.admin.controller;
|
||||
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/wechat")
|
||||
@Tag(name = "微信管理")
|
||||
public class WeChatController {
|
||||
|
||||
@Operation(summary = "获取code")
|
||||
@GetMapping("/code")
|
||||
public Boolean getWeChatAuthCode(@RequestParam("code") String code) {
|
||||
System.out.println(code);
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package com.cxx.admin.dao;
|
||||
|
||||
import com.cxx.admin.dto.user.AccountDto;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Mapper
|
||||
public interface AccountDao {
|
||||
List<AccountDto> queryAccount();
|
||||
}
|
||||
24
admin-service/src/main/java/com/cxx/admin/dao/BlogDao.java
Normal file
24
admin-service/src/main/java/com/cxx/admin/dao/BlogDao.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package com.cxx.admin.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.BlogVisitDto;
|
||||
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);
|
||||
|
||||
BlogDto queryBlogById(@Param("id") Long id);
|
||||
|
||||
List<BlogCategoryDto> queryBlogCategory();
|
||||
|
||||
IPage<BlogVisitDto> queryBlogVisit(IPage<Blog> page);
|
||||
}
|
||||
23
admin-service/src/main/java/com/cxx/admin/dto/FtpInfo.java
Normal file
23
admin-service/src/main/java/com/cxx/admin/dto/FtpInfo.java
Normal file
@@ -0,0 +1,23 @@
|
||||
package com.cxx.admin.dto;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* @Author: Cxx
|
||||
* @Date: 2024/9/24 22:41
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class FtpInfo {
|
||||
private String ftpIp;
|
||||
|
||||
private Integer ftpPort;
|
||||
|
||||
private String ftpUsername;
|
||||
|
||||
private String ftpPassword;
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
package com.cxx.admin.dto.file;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class ChunkInfoDto {
|
||||
/**
|
||||
* 当前文件块,从1开始
|
||||
*/
|
||||
private Integer chunkNumber;
|
||||
/**
|
||||
* 文件名
|
||||
*/
|
||||
private String filename;
|
||||
/**
|
||||
* 块内容
|
||||
*/
|
||||
private transient MultipartFile multipartFile;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.cxx.admin.dto.file;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class ChunkResultDto {
|
||||
/**
|
||||
* 是否跳过上传(已上传的可以直接跳过,达到秒传的效果)
|
||||
*/
|
||||
private boolean isSkipUpload;
|
||||
|
||||
/**
|
||||
* 已经上传的文件块编号,可以跳过,断点续传
|
||||
*/
|
||||
private List<Integer> uploadedChunkList;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.cxx.admin.dto.file;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class FileInfoDto {
|
||||
private String name;
|
||||
private String type;
|
||||
private String size;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date createDate;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.cxx.admin.dto.file;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class FileRecordDto {
|
||||
private Long id;
|
||||
private String name;
|
||||
private String md5;
|
||||
private String path;
|
||||
private String url;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.cxx.admin.dto.server;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class CpuDto {
|
||||
private double usagePercent;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.cxx.admin.dto.server;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class DiskDto {
|
||||
private double total;
|
||||
private double used;
|
||||
private double free;
|
||||
private double usagePercent;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package com.cxx.admin.dto.server;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class MemoryDto {
|
||||
private double total;
|
||||
private double used;
|
||||
private double free;
|
||||
private double usagePercent;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.cxx.admin.dto.server;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class SystemInfoDto {
|
||||
// CPU信息
|
||||
private String cpuName;
|
||||
private String cpuVendor;
|
||||
private int cpuLogicalCores;
|
||||
private int cpuPhysicalCores;
|
||||
private double cpuSystemLoad;
|
||||
// 操作系统信息
|
||||
private String osFamily;
|
||||
private String osVersion;
|
||||
private String osManufacturer;
|
||||
// 系统运行时间
|
||||
private long systemUptime;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.cxx.admin.dto.server;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
public class SystemMetricsDto {
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private Date time;
|
||||
|
||||
private double cpuUsage;
|
||||
private double memoryTotal;
|
||||
private double memoryUsed;
|
||||
private double memoryFree;
|
||||
private double memoryUsage;
|
||||
private double diskTotal;
|
||||
private double diskUsed;
|
||||
private double diskFree;
|
||||
private double diskUsage;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.cxx.admin.dto.user;
|
||||
|
||||
import com.cxx.common.PlainView;
|
||||
import com.cxx.common.ReadView;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@JsonView(PlainView.class)
|
||||
public class AccountDto {
|
||||
@Schema(description = "id")
|
||||
@JsonView(ReadView.class)
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "账户名称")
|
||||
@NotBlank(message = "账户名称不能为空")
|
||||
private String accountName;
|
||||
|
||||
@Schema(description = "密码")
|
||||
@NotBlank(message = "密码不能为空")
|
||||
private String password;
|
||||
|
||||
@Schema(description = "用户名称")
|
||||
@NotBlank(message = "用户名称不能为空")
|
||||
private String username;
|
||||
|
||||
@Schema(description = "账户状态")
|
||||
@JsonView(ReadView.class)
|
||||
private Integer state;
|
||||
|
||||
@Schema(description = "创建日期")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
@JsonView(ReadView.class)
|
||||
private Date date;
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.cxx.admin.dto.user;
|
||||
|
||||
import com.cxx.common.PlainView;
|
||||
import com.cxx.common.ReadView;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonView;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@JsonView(PlainView.class)
|
||||
public class UserSummaryDto {
|
||||
@Schema(description = "id")
|
||||
@JsonView(ReadView.class)
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "id")
|
||||
@JsonView(ReadView.class)
|
||||
private String accountName;
|
||||
|
||||
@Schema(description = "用户名称")
|
||||
@NotBlank(message = "用户名称不能为空")
|
||||
private String username;
|
||||
|
||||
@Schema(description = "账户状态")
|
||||
private Integer state;
|
||||
|
||||
@Schema(description = "创建日期")
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
private LocalDateTime date;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.cxx.admin.schedule;
|
||||
|
||||
import com.cxx.admin.service.ServerMonitorService;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
||||
@Component
|
||||
@Slf4j
|
||||
public class ServerMonitor {
|
||||
@Resource
|
||||
private ServerMonitorService serverMonitorService;
|
||||
|
||||
// @Scheduled(fixedRate = 60000)
|
||||
public void collectAndStoreMetrics() {
|
||||
log.info("开始存储服务器状态");
|
||||
serverMonitorService.storeSystemMetrics();
|
||||
log.info("结束存储服务器状态");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.cxx.admin.service;
|
||||
|
||||
|
||||
import com.cxx.admin.dto.user.AccountDto;
|
||||
import com.cxx.common.entity.Account;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface AccountService {
|
||||
List<AccountDto> queryAccountList();
|
||||
|
||||
Account queryAccountByUserId(Long userId);
|
||||
|
||||
Boolean registerAccount(AccountDto accountDto);
|
||||
|
||||
Boolean deleteAccount(Long id);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.cxx.admin.service;
|
||||
|
||||
import com.cxx.common.dto.bill.BillCategoryDto;
|
||||
import com.cxx.common.dto.bill.BillItemDto;
|
||||
|
||||
public interface BillManageService {
|
||||
Boolean addBillPay(BillItemDto billItemDto);
|
||||
|
||||
Boolean updateBillPay(Long id, BillItemDto billItemDto);
|
||||
|
||||
Boolean addBillBook(BillItemDto billItemDto);
|
||||
|
||||
Boolean updateBillBook(Long id,BillItemDto billItemDto);
|
||||
|
||||
Boolean addBillCategory(BillCategoryDto billCategoryDto);
|
||||
|
||||
Boolean updateBillCategory(Long id, BillCategoryDto billCategoryDto);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.cxx.admin.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.BlogVisitDto;
|
||||
import com.cxx.common.vo.blog.BlogQueryVo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface BlogManageService {
|
||||
IPage<BlogDto> queryBlogByPage(Integer currentPage, Integer pageSize);
|
||||
|
||||
BlogDto queryBlogById(Long id);
|
||||
|
||||
List<BlogCategoryDto> queryBlogCategory();
|
||||
|
||||
Boolean addBlog(BlogDto blog);
|
||||
|
||||
Boolean updateBlog(Long id, BlogDto blog);
|
||||
|
||||
Boolean deleteBlog(Long id);
|
||||
|
||||
IPage<BlogVisitDto> queryBlogVisit(Integer currentPage, Integer pageSize);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.cxx.admin.service;
|
||||
|
||||
|
||||
public interface BudgetManageService {
|
||||
Boolean addBudgetCategory(String category);
|
||||
|
||||
Boolean updateBudgetCategory(Long id, String category);
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.cxx.admin.service;
|
||||
|
||||
import com.cxx.admin.dto.file.ChunkInfoDto;
|
||||
import com.cxx.admin.dto.file.ChunkResultDto;
|
||||
import com.cxx.admin.dto.file.FileInfoDto;
|
||||
import com.cxx.admin.dto.file.FileRecordDto;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface FileService {
|
||||
FileRecordDto uploadFile(MultipartFile file, String path, String md5);
|
||||
|
||||
/**
|
||||
* 上传文件块
|
||||
* @param chunkInfo 文件块信息
|
||||
* @param path 上传路径
|
||||
* @return 是否上传成功
|
||||
*/
|
||||
Boolean uploadChunk(ChunkInfoDto chunkInfo, String path);
|
||||
|
||||
/**
|
||||
* 检查文件块信息
|
||||
* @param identifier 唯一标识
|
||||
* @param filename 文件名
|
||||
* @param path 上传文件夹路径
|
||||
* @return 检查结果
|
||||
*/
|
||||
ChunkResultDto checkChunk(String identifier, String filename, String path);
|
||||
|
||||
/**
|
||||
* 删除文件块
|
||||
* @param identifier 唯一标识
|
||||
* @param path 上传文件夹路径
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
Boolean deleteChunk(String identifier, String path);
|
||||
|
||||
/**
|
||||
* 合并文件
|
||||
* @param filename 文件名
|
||||
* @param path 上传文件夹路径
|
||||
* @return 是否合并成功
|
||||
*/
|
||||
FileRecordDto mergeFile(String filename, String path);
|
||||
|
||||
List<FileInfoDto> getFolderInfo(String folderName);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.cxx.admin.service;
|
||||
|
||||
import com.cxx.admin.dto.server.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ServerMonitorService {
|
||||
CpuDto getCpuInfo();
|
||||
|
||||
MemoryDto getMemoryInfo();
|
||||
|
||||
DiskDto getDiskInfo();
|
||||
|
||||
SystemInfoDto getSystemInfo();
|
||||
|
||||
void storeSystemMetrics();
|
||||
|
||||
List<SystemMetricsDto> querySystemMetrics(String range) ;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.cxx.admin.service;
|
||||
|
||||
import com.cxx.common.dto.user.SessionDto;
|
||||
|
||||
public interface SessionService {
|
||||
SessionDto create(String name, String password);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package com.cxx.admin.service;
|
||||
|
||||
|
||||
import com.cxx.common.dto.user.UserDto;
|
||||
|
||||
public interface UserService {
|
||||
UserDto queryUser(Long id);
|
||||
|
||||
Boolean updateUser(Long id, UserDto userDto);
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.cxx.admin.service.impl;
|
||||
|
||||
|
||||
import cn.dev33.satoken.secure.BCrypt;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.cxx.admin.dao.AccountDao;
|
||||
import com.cxx.admin.service.AccountService;
|
||||
import com.cxx.admin.dto.user.AccountDto;
|
||||
import com.cxx.common.entity.Account;
|
||||
import com.cxx.common.entity.User;
|
||||
import com.cxx.common.mapper.AccountMapper;
|
||||
import com.cxx.common.mapper.UserMapper;
|
||||
import com.cxx.framework.web.CustomException;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@Service
|
||||
public class AccountServiceImpl implements AccountService {
|
||||
@Resource
|
||||
private AccountDao accountDao;
|
||||
|
||||
@Resource
|
||||
private AccountMapper accountMapper;
|
||||
|
||||
@Resource
|
||||
private UserMapper userMapper;
|
||||
|
||||
@Override
|
||||
public List<AccountDto> queryAccountList() {
|
||||
return accountDao.queryAccount();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Account queryAccountByUserId(Long userId) {
|
||||
LambdaQueryWrapper<Account> queryWrapper = new LambdaQueryWrapper<>();
|
||||
return accountMapper.selectOne(queryWrapper.eq(Account::getUserId, userId));
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Boolean registerAccount(AccountDto accountDto) {
|
||||
LambdaQueryWrapper<Account> queryWrapper = new LambdaQueryWrapper<>();
|
||||
if (accountMapper.exists(queryWrapper.eq(Account::getAccountName, accountDto.getAccountName()))) {
|
||||
throw new CustomException("该账户已经存在");
|
||||
}
|
||||
|
||||
LambdaQueryWrapper<User> userQueryWrapper = new LambdaQueryWrapper<>();
|
||||
if (userMapper.exists(userQueryWrapper.eq(User::getUsername, accountDto.getUsername()))) {
|
||||
throw new CustomException("该用户已注册");
|
||||
}
|
||||
|
||||
List<Integer> results = new ArrayList<>();
|
||||
User user = new User();
|
||||
BeanUtils.copyProperties(accountDto, user);
|
||||
results.add(userMapper.insert(user));
|
||||
|
||||
Account account = new Account();
|
||||
account.setAccountName(accountDto.getAccountName());
|
||||
account.setPassword(BCrypt.hashpw(accountDto.getPassword(), BCrypt.gensalt()));
|
||||
account.setUserId(user.getId());
|
||||
account.setState(0);
|
||||
results.add(accountMapper.insert(account));
|
||||
|
||||
return results.stream().allMatch(x -> x > 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean deleteAccount(Long id) {
|
||||
Account account = accountMapper.selectById(id);
|
||||
|
||||
if (account == null) {
|
||||
throw new CustomException("该账号不存在");
|
||||
}
|
||||
|
||||
accountMapper.deleteById(id);
|
||||
return userMapper.deleteById(account.getUserId()) == 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
package com.cxx.admin.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.cxx.admin.service.BillManageService;
|
||||
import com.cxx.common.dto.bill.BillCategoryDto;
|
||||
import com.cxx.common.dto.bill.BillItemDto;
|
||||
import com.cxx.common.entity.BillBook;
|
||||
import com.cxx.common.entity.BillCategory;
|
||||
import com.cxx.common.entity.BillPay;
|
||||
import com.cxx.common.mapper.BillBookMapper;
|
||||
import com.cxx.common.mapper.BillCategoryMapper;
|
||||
import com.cxx.common.mapper.BillPayMapper;
|
||||
import com.cxx.framework.web.CustomException;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Service
|
||||
public class BillManageServiceImpl implements BillManageService {
|
||||
@Resource
|
||||
private BillPayMapper billPayMapper;
|
||||
|
||||
@Resource
|
||||
private BillBookMapper billBookMapper;
|
||||
|
||||
@Resource
|
||||
private BillCategoryMapper billCategoryMapper;
|
||||
|
||||
@Override
|
||||
public Boolean addBillPay(BillItemDto billItemDto) {
|
||||
// 1. 校验是否存在
|
||||
LambdaQueryWrapper<BillPay> queryWrapper = new LambdaQueryWrapper<>();
|
||||
if (billPayMapper.exists(queryWrapper.eq(BillPay::getName, billItemDto.getName()))) {
|
||||
throw new CustomException("该账户已经存在");
|
||||
}
|
||||
|
||||
// 2. 新增账户
|
||||
BillPay newbillPay = new BillPay();
|
||||
BeanUtils.copyProperties(billItemDto, newbillPay);
|
||||
|
||||
return billPayMapper.insert(newbillPay) == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateBillPay(Long id, BillItemDto billItemDto) {
|
||||
// 1. 校验是否存在
|
||||
if (Objects.isNull(billPayMapper.selectById(id))) {
|
||||
throw new RuntimeException("该账户不存在");
|
||||
}
|
||||
|
||||
// 2. 更新账户
|
||||
BillPay billPay = new BillPay();
|
||||
BeanUtils.copyProperties(billItemDto, billPay);
|
||||
billPay.setId(id);
|
||||
|
||||
return billPayMapper.updateById(billPay) == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean addBillBook(BillItemDto billItemDto) {
|
||||
// 1. 校验是否存在
|
||||
LambdaQueryWrapper<BillBook> queryWrapper = new LambdaQueryWrapper<>();
|
||||
if (billBookMapper.exists(queryWrapper.eq(BillBook::getName, billItemDto.getName()))) {
|
||||
throw new CustomException("该账本已经存在");
|
||||
}
|
||||
|
||||
// 2. 新增账本
|
||||
BillBook billBook = new BillBook();
|
||||
BeanUtils.copyProperties(billItemDto, billBook);
|
||||
|
||||
return billBookMapper.insert(billBook) == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateBillBook(Long id, BillItemDto billItemDto) {
|
||||
// 1. 校验是否存在
|
||||
if (Objects.isNull(billBookMapper.selectById(id))) {
|
||||
throw new CustomException("该账单不存在");
|
||||
}
|
||||
|
||||
// 2. 更新账本
|
||||
BillBook billBook = new BillBook();
|
||||
BeanUtils.copyProperties(billItemDto, billBook);
|
||||
billBook.setId(id);
|
||||
|
||||
return billBookMapper.updateById(billBook) == 1;
|
||||
}
|
||||
|
||||
private Long getBillBook(String name) {
|
||||
LambdaQueryWrapper<BillBook> queryWrapper = new LambdaQueryWrapper<>();
|
||||
queryWrapper.eq(BillBook::getName, name);
|
||||
BillBook billBook = billBookMapper.selectOne(queryWrapper);
|
||||
|
||||
if (Objects.isNull(billBook)) {
|
||||
throw new CustomException("该账本类型不存在");
|
||||
}
|
||||
|
||||
return billBook.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean addBillCategory(BillCategoryDto billCategoryDto) {
|
||||
// 1. 校验是否存在
|
||||
LambdaQueryWrapper<BillCategory> queryWrapper = new LambdaQueryWrapper<>();
|
||||
if (billCategoryMapper.exists(queryWrapper.eq(BillCategory::getName, billCategoryDto.getName()))) {
|
||||
throw new CustomException("该账单类型已经存在");
|
||||
}
|
||||
|
||||
// 2. 新增账单类型
|
||||
BillCategory newBillCategory = new BillCategory();
|
||||
BeanUtils.copyProperties(billCategoryDto, newBillCategory);
|
||||
newBillCategory.setBookId(getBillBook(billCategoryDto.getBookName()));
|
||||
|
||||
return billCategoryMapper.insert(newBillCategory) == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateBillCategory(Long id, BillCategoryDto billCategoryDto) {
|
||||
// 1. 校验是否存在
|
||||
if (Objects.isNull(billCategoryMapper.selectById(id))) {
|
||||
throw new CustomException("该账单类型不存在");
|
||||
}
|
||||
|
||||
// 2. 更新账单类型
|
||||
BillCategory billCategory = new BillCategory();
|
||||
BeanUtils.copyProperties(billCategoryDto, billCategory);
|
||||
billCategory.setBookId(getBillBook(billCategoryDto.getBookName()));
|
||||
billCategory.setId(id);
|
||||
|
||||
return billCategoryMapper.updateById(billCategory) == 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,193 @@
|
||||
package com.cxx.admin.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.cxx.admin.dao.BlogDao;
|
||||
import com.cxx.admin.service.BlogManageService;
|
||||
import com.cxx.admin.util.BlogUtils;
|
||||
import com.cxx.common.dto.blog.BlogCategoryDto;
|
||||
import com.cxx.common.dto.blog.BlogDto;
|
||||
import com.cxx.common.dto.blog.BlogVisitDto;
|
||||
import com.cxx.common.entity.Blog;
|
||||
import com.cxx.common.entity.BlogCategory;
|
||||
import com.cxx.common.entity.BlogContent;
|
||||
import com.cxx.common.mapper.BlogCategoryMapper;
|
||||
import com.cxx.common.mapper.BlogContentMapper;
|
||||
import com.cxx.common.mapper.BlogMapper;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@Service
|
||||
public class BlogManageServiceImpl implements BlogManageService {
|
||||
@Resource
|
||||
private BlogDao blogDao;
|
||||
|
||||
@Resource
|
||||
private BlogMapper blogMapper;
|
||||
|
||||
@Resource
|
||||
private BlogCategoryMapper categoryMapper;
|
||||
|
||||
@Resource
|
||||
private BlogContentMapper contentMapper;
|
||||
|
||||
@Override
|
||||
public IPage<BlogDto> queryBlogByPage(Integer currentPage, Integer pageSize) {
|
||||
return blogDao.queryBlogByPage(new Page<>(currentPage, pageSize));
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlogDto queryBlogById(Long id) {
|
||||
return blogDao.queryBlogById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<BlogCategoryDto> queryBlogCategory() {
|
||||
return blogDao.queryBlogCategory();
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Boolean addBlog(BlogDto blogDto) {
|
||||
// 1. 新增博客基本信息
|
||||
Blog blog = saveOrUpdateNewBlog(blogDto);
|
||||
// 2. 新增博客内容信息
|
||||
blog.setContentId(addBlogContent(blogDto.getContent()));
|
||||
// 3. 插入数据库
|
||||
return blogMapper.insert(blog) == 1;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Boolean updateBlog(Long id, BlogDto blogDto) {
|
||||
Blog blog = saveOrUpdateNewBlog(blogDto);
|
||||
blog.setId(id);
|
||||
// 1. 更新博客内容信息
|
||||
updateBlogContent(getBlogById(id).getContentId(), blogDto.getContent());
|
||||
// 2. 校验是否删除博客类别
|
||||
deleteBlogCategory(getBlogById(id).getCategoryId());
|
||||
// 3. 更新数据库
|
||||
return blogMapper.updateById(blog) == 1;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
@Override
|
||||
public Boolean deleteBlog(Long id) {
|
||||
// 1. 删除博客类别
|
||||
deleteBlogCategory(getBlogById(id).getCategoryId());
|
||||
// 2. 删除博客内容
|
||||
contentMapper.deleteById(getBlogById(id).getContentId());
|
||||
// 3. 删除博客
|
||||
return blogMapper.deleteById(id) == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPage<BlogVisitDto> queryBlogVisit(Integer currentPage, Integer pageSize) {
|
||||
return blogDao.queryBlogVisit(new Page<>(currentPage, pageSize));
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过博客id获取博客
|
||||
* @param id id
|
||||
* @return 博客
|
||||
*/
|
||||
private Blog getBlogById(Long id) {
|
||||
Blog blog = blogMapper.selectById(id);
|
||||
|
||||
if (Objects.isNull(blog)) {
|
||||
throw new RuntimeException("暂无该博客");
|
||||
}
|
||||
|
||||
return blog;
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加/更新 博客
|
||||
* @param blogDto 前端传入的博客内容
|
||||
* @return 博客
|
||||
*/
|
||||
private Blog saveOrUpdateNewBlog(BlogDto blogDto) {
|
||||
Blog newBlog = new Blog();
|
||||
|
||||
// 设置博客基础信息
|
||||
newBlog.setTitle(blogDto.getTitle());
|
||||
newBlog.setTopValue(blogDto.getTopValue());
|
||||
newBlog.setIsGreat(blogDto.getIsGreat());
|
||||
|
||||
// 设置博客类别
|
||||
newBlog.setCategoryId(saveOrUpdateBlogCategory(blogDto.getCategory()));
|
||||
|
||||
// 设置博客内容
|
||||
newBlog.setSummary(BlogUtils.getBlogSummary(blogDto.getContent()));
|
||||
|
||||
// 设置博客字数统计
|
||||
Integer wordCount = BlogUtils.getWordCount(blogDto.getContent());
|
||||
newBlog.setWordCount(wordCount);
|
||||
newBlog.setReadDuration(BlogUtils.getReadDuration(wordCount));
|
||||
|
||||
return newBlog;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置博客类别
|
||||
* @param category 类别
|
||||
* @return 类别id
|
||||
*/
|
||||
private Long saveOrUpdateBlogCategory(String category) {
|
||||
// 1. 查找类别是否存在
|
||||
LambdaQueryWrapper<BlogCategory> queryWrapper = new LambdaQueryWrapper<>();
|
||||
BlogCategory blogCategory = categoryMapper.selectOne(queryWrapper.eq(BlogCategory::getName, category));
|
||||
|
||||
// 2. 如果存在则返回id 否则需要新增类别
|
||||
if (Objects.isNull(blogCategory)) {
|
||||
BlogCategory newBlogCategory = new BlogCategory();
|
||||
newBlogCategory.setName(category);
|
||||
categoryMapper.insert(newBlogCategory);
|
||||
return newBlogCategory.getId();
|
||||
} else {
|
||||
return blogCategory.getId();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否需要删除博客类别
|
||||
* @param categoryId 博客类别id
|
||||
*/
|
||||
private void deleteBlogCategory(Long categoryId) {
|
||||
LambdaQueryWrapper<Blog> queryWrapper = new LambdaQueryWrapper<>();
|
||||
if (!blogMapper.exists(queryWrapper.eq(Blog::getCategoryId, categoryId))) {
|
||||
// 如果没有该类别的博客 则删除博客类别
|
||||
categoryMapper.deleteById(categoryId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增博客内容
|
||||
* @param content 博客内容
|
||||
* @return 博客内容id
|
||||
*/
|
||||
private Long addBlogContent(String content) {
|
||||
BlogContent blogContent = new BlogContent();
|
||||
blogContent.setContent(content);
|
||||
contentMapper.insert(blogContent);
|
||||
|
||||
return blogContent.getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新博客内容
|
||||
* @param contentId 博客内容id
|
||||
* @param content 博客内容
|
||||
*/
|
||||
private void updateBlogContent(Long contentId, String content) {
|
||||
BlogContent blogContent = new BlogContent();
|
||||
blogContent.setContent(content);
|
||||
blogContent.setId(contentId);
|
||||
contentMapper.updateById(blogContent);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.cxx.admin.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.cxx.admin.service.BudgetManageService;
|
||||
import com.cxx.common.entity.BudgetCategory;
|
||||
import com.cxx.common.mapper.BudgetCategoryMapper;
|
||||
import com.cxx.framework.web.CustomException;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
@Service
|
||||
public class BudgetManageServiceImpl implements BudgetManageService {
|
||||
@Resource
|
||||
private BudgetCategoryMapper budgetCategoryMapper;
|
||||
|
||||
|
||||
@Override
|
||||
public Boolean addBudgetCategory(String category) {
|
||||
LambdaQueryWrapper<BudgetCategory> queryWrapper = new LambdaQueryWrapper<>();
|
||||
if (budgetCategoryMapper.exists(queryWrapper.eq(BudgetCategory::getName, category))) {
|
||||
throw new CustomException("该预算类别已存在");
|
||||
}
|
||||
|
||||
BudgetCategory budgetCategory = new BudgetCategory();
|
||||
budgetCategory.setName(category);
|
||||
return budgetCategoryMapper.insert(budgetCategory) == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateBudgetCategory(Long id, String category) {
|
||||
if (Objects.isNull(budgetCategoryMapper.selectById(id))) {
|
||||
throw new CustomException("该预算类别不存在");
|
||||
}
|
||||
|
||||
BudgetCategory budgetCategory = new BudgetCategory();
|
||||
budgetCategory.setId(id);
|
||||
budgetCategory.setName(category);
|
||||
|
||||
return budgetCategoryMapper.updateById(budgetCategory) == 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
package com.cxx.admin.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.cxx.admin.constant.FileConstant;
|
||||
import com.cxx.admin.dto.file.ChunkInfoDto;
|
||||
import com.cxx.admin.dto.file.ChunkResultDto;
|
||||
import com.cxx.admin.dto.file.FileInfoDto;
|
||||
import com.cxx.admin.service.FileService;
|
||||
import com.cxx.admin.dto.file.FileRecordDto;
|
||||
import com.cxx.admin.util.FileUtils;
|
||||
import com.cxx.admin.util.UploadFileUtil;
|
||||
import com.cxx.common.entity.FileRecord;
|
||||
import com.cxx.common.mapper.FileRecordMapper;
|
||||
import com.cxx.framework.web.CustomException;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.io.FilenameUtils;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class FileServiceImpl implements FileService {
|
||||
@Value("${file.path}")
|
||||
private String fileRootPath;
|
||||
|
||||
@Resource
|
||||
private FileRecordMapper fileRecordMapper;
|
||||
|
||||
@Override
|
||||
public FileRecordDto uploadFile(MultipartFile multipartFile, String path, String md5) {
|
||||
UploadFileUtil.checkDirIsExist(getFilePath(path));
|
||||
|
||||
String filename = multipartFile.getOriginalFilename();
|
||||
String newPath = path + File.separator + md5 + "." + FilenameUtils.getExtension(filename);
|
||||
File newFile = new File(getFilePath(newPath));
|
||||
|
||||
saveFile(multipartFile, newFile);
|
||||
|
||||
// 这里的url需要加上 WebMvcConfig 中设置的前缀
|
||||
String url = FileConstant.FILE_URL_PREFIX + File.separator + newPath;
|
||||
return getFileRecord(filename, md5, path, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean uploadChunk(ChunkInfoDto chunkInfo, String path) {
|
||||
MultipartFile file = chunkInfo.getMultipartFile();
|
||||
|
||||
try {
|
||||
// 1. 校验路径是否存在
|
||||
UploadFileUtil.checkDirIsExist(getFilePath(path));
|
||||
// 2. 获取文件块路径
|
||||
Path chunkPath = Paths.get(UploadFileUtil.generateChunkPath(getFilePath(path), chunkInfo));
|
||||
// 3. 将文件块写入指定路径
|
||||
Files.write(chunkPath, file.getBytes());
|
||||
} catch (IOException exception) {
|
||||
log.error("文件上传块失败: {}", exception.getMessage());
|
||||
throw new CustomException("文件上传块失败: " + exception.getMessage());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChunkResultDto checkChunk(String identifier, String filename, String path) {
|
||||
ChunkResultDto chunkResult = new ChunkResultDto();
|
||||
List<Integer> uploadedChunkList = new ArrayList<>();
|
||||
|
||||
String folder = getFilePath(path) + File.separator + identifier;
|
||||
String file = folder + File.separator + filename;
|
||||
|
||||
// 判断文件夹是否存在
|
||||
if (UploadFileUtil.fileExists(folder)) {
|
||||
// 先判断整个文件是否已经上传过了,如果是,则告诉前端跳过上传,实现秒传
|
||||
if (UploadFileUtil.fileExists(file)) {
|
||||
chunkResult.setSkipUpload(true);
|
||||
chunkResult.setUploadedChunkList(uploadedChunkList);
|
||||
log.info("完整文件已存在,直接跳过上传,实现秒传");
|
||||
} else {
|
||||
chunkResult.setSkipUpload(false);
|
||||
// 获取已经上传的文件块
|
||||
chunkResult.setUploadedChunkList(UploadFileUtil.getUploadedChunkList(folder, filename));
|
||||
}
|
||||
} else {
|
||||
chunkResult.setSkipUpload(false);
|
||||
chunkResult.setUploadedChunkList(uploadedChunkList);
|
||||
}
|
||||
|
||||
return chunkResult;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean deleteChunk(String identifier, String path) {
|
||||
String folder = getFilePath(path) + File.separator + identifier;
|
||||
log.info("开始删除文件: " + folder);
|
||||
|
||||
// 判断文件夹是否存在
|
||||
if (UploadFileUtil.fileExists(folder)) {
|
||||
UploadFileUtil.deleteDirectory(folder);
|
||||
} else {
|
||||
throw new CustomException("文件: " + folder + "不存在");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileRecordDto mergeFile(String filename, String path) {
|
||||
String uuid = UUID.randomUUID().toString().replace("-", "");
|
||||
String newFilename = uuid + "." + FilenameUtils.getExtension(filename);
|
||||
try {
|
||||
UploadFileUtil.mergeFile(newFilename, getFilePath(path));
|
||||
} catch (IOException exception) {
|
||||
throw new CustomException("合并文件: " + filename + " 失败");
|
||||
}
|
||||
|
||||
String newPath = path + File.separator + newFilename;
|
||||
String url = FileConstant.FILE_URL_PREFIX + File.separator + newPath;
|
||||
return getFileRecord(filename, uuid, path, url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<FileInfoDto> getFolderInfo(String folderName) {
|
||||
File folder = new File(folderName);
|
||||
List<FileInfoDto> fileInfoList = new ArrayList<>();
|
||||
if (folder.exists() && folder.isDirectory()) {
|
||||
File[] files = folder.listFiles();
|
||||
if (files != null) {
|
||||
List<FileInfoDto> folderInfoList = new ArrayList<>();
|
||||
List<FileInfoDto> fileInfoSubList = new ArrayList<>();
|
||||
for (File file : files) {
|
||||
FileInfoDto fileInfo = new FileInfoDto();
|
||||
fileInfo.setName(file.getName());
|
||||
if (file.isDirectory()) {
|
||||
fileInfo.setType("文件夹");
|
||||
fileInfo.setSize("-");
|
||||
folderInfoList.add(fileInfo);
|
||||
} else {
|
||||
fileInfo.setType(FileUtils.getFileType(file.getName()));
|
||||
fileInfo.setSize(FileUtils.formatSize(file.length()));
|
||||
fileInfoSubList.add(fileInfo);
|
||||
}
|
||||
fileInfo.setCreateDate(new Date(file.lastModified()));
|
||||
}
|
||||
fileInfoList.addAll(folderInfoList);
|
||||
fileInfoList.addAll(fileInfoSubList);
|
||||
}
|
||||
}
|
||||
return fileInfoList;
|
||||
}
|
||||
|
||||
private void saveFile(MultipartFile multipartFile, File file) {
|
||||
// 如果文件不存在
|
||||
if (!file.exists()) {
|
||||
try {
|
||||
// 3. 如果不存在则创建文件
|
||||
multipartFile.transferTo(file);
|
||||
} catch (IOException e) {
|
||||
throw new CustomException("文件上传失败:{}", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private FileRecordDto getFileRecord(String filename, String md5, String path, String url) {
|
||||
FileRecord fileRecord = new FileRecord();
|
||||
fileRecord.setName(filename);
|
||||
fileRecord.setMd5(md5);
|
||||
fileRecord.setPath(path);
|
||||
fileRecord.setUrl(url);
|
||||
fileRecord.setId(saveDatabase(fileRecord, md5));
|
||||
|
||||
// 4. 返回文件信息
|
||||
FileRecordDto fileRecordDto = new FileRecordDto();
|
||||
BeanUtils.copyProperties(fileRecord, fileRecordDto);
|
||||
|
||||
return fileRecordDto;
|
||||
}
|
||||
|
||||
private Long saveDatabase(FileRecord fileRecord, String md5) {
|
||||
LambdaQueryWrapper<FileRecord> queryWrapper = Wrappers.lambdaQuery(FileRecord.class);
|
||||
FileRecord dbFileRecord = fileRecordMapper.selectOne(queryWrapper.eq(FileRecord::getMd5, md5));
|
||||
if (Objects.isNull(dbFileRecord)) {
|
||||
fileRecordMapper.insert(fileRecord);
|
||||
return fileRecord.getId();
|
||||
} else {
|
||||
return dbFileRecord.getId();
|
||||
}
|
||||
}
|
||||
|
||||
private String getFilePath(String path) {
|
||||
return fileRootPath + path;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
package com.cxx.admin.service.impl;
|
||||
|
||||
import com.cxx.admin.dto.server.*;
|
||||
import com.cxx.admin.service.ServerMonitorService;
|
||||
import com.influxdb.client.InfluxDBClient;
|
||||
import com.influxdb.client.InfluxDBClientFactory;
|
||||
import com.influxdb.client.QueryApi;
|
||||
import com.influxdb.client.WriteApi;
|
||||
import com.influxdb.client.domain.WritePrecision;
|
||||
import com.influxdb.client.write.Point;
|
||||
import com.influxdb.query.FluxTable;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import oshi.SystemInfo;
|
||||
import oshi.hardware.CentralProcessor;
|
||||
import oshi.hardware.GlobalMemory;
|
||||
import oshi.hardware.HWDiskStore;
|
||||
import oshi.hardware.HardwareAbstractionLayer;
|
||||
import oshi.software.os.OperatingSystem;
|
||||
|
||||
import java.io.File;
|
||||
import java.text.DecimalFormat;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Service
|
||||
public class ServerMonitorServiceImpl implements ServerMonitorService {
|
||||
private final SystemInfo systemInfo = new SystemInfo();
|
||||
private final HardwareAbstractionLayer hardware = systemInfo.getHardware();
|
||||
private final OperatingSystem os = systemInfo.getOperatingSystem();
|
||||
private final CentralProcessor processor = hardware.getProcessor();
|
||||
|
||||
private final InfluxDBClient client;
|
||||
|
||||
private final QueryApi queryApi;
|
||||
|
||||
private final String SYSTEM_METRICS = "system_metrics";
|
||||
|
||||
private final long GB = 1024 * 1024 * 1024;
|
||||
private final DecimalFormat df = new DecimalFormat("0.00");
|
||||
|
||||
public ServerMonitorServiceImpl(
|
||||
@Value("${influxdb.url}") String url,
|
||||
@Value("${influxdb.token}") String token,
|
||||
@Value("${influxdb.org}") String org,
|
||||
@Value("${influxdb.bucket}") String bucket) {
|
||||
this.client = InfluxDBClientFactory.create(url, token.toCharArray(), org, bucket);
|
||||
this.queryApi = this.client.getQueryApi();
|
||||
}
|
||||
|
||||
@Override
|
||||
public CpuDto getCpuInfo() {
|
||||
CpuDto cpuDto = new CpuDto();
|
||||
cpuDto.setUsagePercent(formatPercent(hardware.getProcessor().getSystemCpuLoad(500) * 100));
|
||||
|
||||
return cpuDto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MemoryDto getMemoryInfo() {
|
||||
GlobalMemory memory = hardware.getMemory();
|
||||
MemoryDto memoryDto = new MemoryDto();
|
||||
long total = memory.getTotal();
|
||||
long free = memory.getAvailable();
|
||||
long used = total - free;
|
||||
|
||||
memoryDto.setTotal(bytesToGb(total));
|
||||
memoryDto.setUsed(bytesToGb(used));
|
||||
memoryDto.setFree(bytesToGb(free));
|
||||
memoryDto.setUsagePercent(formatPercent((used * 100.0) / total));
|
||||
|
||||
return memoryDto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DiskDto getDiskInfo() {
|
||||
List<HWDiskStore> disks = hardware.getDiskStores();
|
||||
if (disks.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 获取根分区信息
|
||||
HWDiskStore rootDisk = disks.get(0);
|
||||
DiskDto diskInfo = new DiskDto();
|
||||
diskInfo.setTotal(bytesToGb(rootDisk.getSize()));
|
||||
|
||||
// 获取文件系统使用情况
|
||||
os.getFileSystem().getFileStores().stream()
|
||||
.filter(fs -> fs.getMount().equals(File.separator))
|
||||
.findFirst()
|
||||
.ifPresent(fs -> {
|
||||
long total = fs.getTotalSpace();
|
||||
long free = fs.getFreeSpace();
|
||||
long used = total - free;
|
||||
|
||||
diskInfo.setUsed(bytesToGb(used));
|
||||
diskInfo.setFree(bytesToGb(free));
|
||||
diskInfo.setUsagePercent(formatPercent((double) (used) * 100.0 / total));
|
||||
});
|
||||
|
||||
return diskInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SystemInfoDto getSystemInfo() {
|
||||
SystemInfoDto dto = new SystemInfoDto();
|
||||
|
||||
// 获取CPU信息
|
||||
dto.setCpuName(processor.getProcessorIdentifier().getName());
|
||||
dto.setCpuVendor(processor.getProcessorIdentifier().getVendor());
|
||||
dto.setCpuLogicalCores(processor.getLogicalProcessorCount());
|
||||
dto.setCpuPhysicalCores(processor.getPhysicalProcessorCount());
|
||||
|
||||
// 获取CPU负载
|
||||
double[] loadAverage = processor.getSystemLoadAverage(3);
|
||||
dto.setCpuSystemLoad(loadAverage[0]); // 1分钟平均负载
|
||||
|
||||
// 获取操作系统信息
|
||||
dto.setOsFamily(os.getFamily());
|
||||
dto.setOsVersion(os.getVersionInfo().getVersion());
|
||||
dto.setOsManufacturer(os.getManufacturer());
|
||||
|
||||
// 获取系统运行时间(秒)
|
||||
dto.setSystemUptime(TimeUnit.MILLISECONDS.toSeconds(systemInfo.getOperatingSystem().getSystemUptime()));
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void storeSystemMetrics() {
|
||||
try (WriteApi writeApi = client.getWriteApi()) {
|
||||
CpuDto cpuDto = getCpuInfo();
|
||||
MemoryDto memoryDto = getMemoryInfo();
|
||||
DiskDto diskDto = getDiskInfo();
|
||||
|
||||
Point point = Point
|
||||
.measurement(SYSTEM_METRICS)
|
||||
.addTag("host", "localhost")
|
||||
.addField("cpu_usage", cpuDto.getUsagePercent())
|
||||
.addField("memory_total", memoryDto.getTotal())
|
||||
.addField("memory_used", memoryDto.getUsed())
|
||||
.addField("memory_free", memoryDto.getFree())
|
||||
.addField("memory_usage", memoryDto.getUsagePercent())
|
||||
.addField("disk_total", diskDto.getTotal())
|
||||
.addField("disk_used", diskDto.getUsed())
|
||||
.addField("disk_free", diskDto.getFree())
|
||||
.addField("disk_usage", diskDto.getUsagePercent())
|
||||
.time(Instant.now(), WritePrecision.S);
|
||||
|
||||
writeApi.writePoint(point);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SystemMetricsDto> querySystemMetrics(String range) {
|
||||
String fluxQuery = "from(bucket: \"server_metrics\")" +
|
||||
"|> range(start: -" + range + ")" + // range 可以是 "1h", "24h" 等
|
||||
"|> filter(fn: (r) => r._measurement == \"system_metrics\")" +
|
||||
"|> pivot(rowKey: [\"_time\"], columnKey: [\"_field\"], valueColumn: \"_value\")";
|
||||
|
||||
List<Map<String, Object>> results = executeQuery(fluxQuery);
|
||||
|
||||
List<SystemMetricsDto> systemMetricsList = new ArrayList<>();
|
||||
|
||||
for (Map<String, Object> data : results) {
|
||||
SystemMetricsDto systemMetrics = new SystemMetricsDto();
|
||||
systemMetrics.setCpuUsage((Double) data.get("cpu_usage"));
|
||||
systemMetrics.setMemoryTotal((Double) data.get("memory_total"));
|
||||
systemMetrics.setMemoryUsed((Double) data.get("memory_used"));
|
||||
systemMetrics.setMemoryFree((Double) data.get("memory_free"));
|
||||
systemMetrics.setMemoryUsage((Double) data.get("memory_usage"));
|
||||
systemMetrics.setDiskTotal((Double) data.get("disk_total"));
|
||||
systemMetrics.setDiskUsed((Double) data.get("disk_used"));
|
||||
systemMetrics.setDiskFree((Double) data.get("disk_free"));
|
||||
systemMetrics.setDiskUsage((Double) data.get("disk_usage"));
|
||||
systemMetrics.setTime(Date.from((Instant) data.get("time")));
|
||||
|
||||
systemMetricsList.add(systemMetrics);
|
||||
}
|
||||
|
||||
return systemMetricsList;
|
||||
}
|
||||
|
||||
private List<Map<String, Object>> executeQuery(String fluxQuery) {
|
||||
List<FluxTable> tables = queryApi.query(fluxQuery);
|
||||
List<Map<String, Object>> results = new ArrayList<>();
|
||||
|
||||
for (FluxTable table : tables) {
|
||||
table.getRecords().forEach(record -> {
|
||||
Map<String, Object> data = new HashMap<>();
|
||||
data.put("time", record.getTime());
|
||||
|
||||
record.getValues().forEach((key, value) -> {
|
||||
if (!key.startsWith("_")) { // 过滤掉内部字段
|
||||
data.put(key, value);
|
||||
}
|
||||
});
|
||||
|
||||
results.add(data);
|
||||
});
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
private double bytesToGb(long bytes) {
|
||||
double gb = bytes / (double) GB;
|
||||
return Double.parseDouble(df.format(gb));
|
||||
}
|
||||
|
||||
public double formatPercent(double percent) {
|
||||
return Double.parseDouble(df.format(percent));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.cxx.admin.service.impl;
|
||||
|
||||
|
||||
import cn.dev33.satoken.secure.BCrypt;
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.cxx.common.dto.user.SessionDto;
|
||||
import com.cxx.admin.service.SessionService;
|
||||
import com.cxx.common.dto.user.UserDto;
|
||||
import com.cxx.common.entity.Account;
|
||||
import com.cxx.common.entity.User;
|
||||
import com.cxx.common.mapper.AccountMapper;
|
||||
import com.cxx.common.mapper.UserMapper;
|
||||
import com.cxx.framework.web.CustomException;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
|
||||
@Service
|
||||
public class SessionServiceImpl implements SessionService {
|
||||
@Resource
|
||||
private AccountMapper accountMapper;
|
||||
|
||||
@Resource
|
||||
private UserMapper userMapper;
|
||||
|
||||
@Override
|
||||
public SessionDto create(String name, String password) {
|
||||
LambdaQueryWrapper<Account> queryWrapper = Wrappers.lambdaQuery(Account.class).eq(Account::getAccountName, name);
|
||||
Account account = accountMapper.selectOne(queryWrapper);
|
||||
if (account == null) {
|
||||
throw new CustomException("账户: " + name + " 不存在");
|
||||
}
|
||||
|
||||
if (!BCrypt.checkpw(password, account.getPassword())) {
|
||||
throw new CustomException("密码不正确");
|
||||
}
|
||||
|
||||
User user = userMapper.selectById(account.getUserId());
|
||||
UserDto userDto = new UserDto();
|
||||
BeanUtils.copyProperties(user, userDto);
|
||||
userDto.setAccountId(account.getId());
|
||||
userDto.setAccountName(name);
|
||||
|
||||
SessionDto sessionDto = new SessionDto();
|
||||
StpUtil.login(account.getId());
|
||||
sessionDto.setSaToken(StpUtil.getTokenInfo());
|
||||
sessionDto.setUserInfo(userDto);
|
||||
|
||||
StpUtil.getSession().set("username", name);
|
||||
|
||||
return sessionDto;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.cxx.admin.service.impl;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.cxx.admin.service.AccountService;
|
||||
import com.cxx.admin.service.UserService;
|
||||
import com.cxx.common.dto.user.UserDto;
|
||||
import com.cxx.common.entity.User;
|
||||
import com.cxx.common.mapper.UserMapper;
|
||||
import com.cxx.framework.web.CustomException;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class UserServiceImpl implements UserService {
|
||||
@Resource
|
||||
private UserMapper userMapper;
|
||||
|
||||
@Resource
|
||||
private AccountService accountService;
|
||||
|
||||
@Override
|
||||
public UserDto queryUser(Long id) {
|
||||
User user = userMapper.selectById(id);
|
||||
if (user == null) {
|
||||
throw new CustomException("未查询到该用户");
|
||||
}
|
||||
|
||||
UserDto userDto = new UserDto();
|
||||
BeanUtils.copyProperties(user, userDto);
|
||||
userDto.setAccountName(accountService.queryAccountByUserId(id).getAccountName());
|
||||
return userDto;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean updateUser(Long id, UserDto userDto) {
|
||||
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
|
||||
if (!userMapper.exists(queryWrapper.eq(User::getId, id))) {
|
||||
throw new CustomException("该用户不存在");
|
||||
}
|
||||
|
||||
queryWrapper.clear();
|
||||
if (userMapper.exists(queryWrapper.eq(User::getUsername, userDto.getUsername()).ne(User::getId, id))) {
|
||||
throw new CustomException("该用户已经存在");
|
||||
}
|
||||
|
||||
User user = new User();
|
||||
BeanUtils.copyProperties(userDto, user);
|
||||
user.setId(id);
|
||||
return userMapper.updateById(user) == 1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.cxx.admin.util;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class BlogUtils {
|
||||
/**
|
||||
* 博客概要字数
|
||||
*/
|
||||
private static final Integer BLOG_SUMMARY_COUNT = 100;
|
||||
|
||||
/**
|
||||
* 阅读速度 600 字/分钟
|
||||
*/
|
||||
private static final Double READ_SPEED = 600.0;
|
||||
|
||||
/**
|
||||
* 博客非统计字符
|
||||
*/
|
||||
private static final List<Character> excludeChart = new ArrayList<>(Arrays.asList(' ', '\n', '\t'));
|
||||
|
||||
/**
|
||||
* 获取文本字数
|
||||
*
|
||||
* @param str 文本
|
||||
* @return 字数
|
||||
*/
|
||||
public static Integer getWordCount(String str) {
|
||||
Integer count = 0;
|
||||
|
||||
if (null == str || str.isEmpty()) {
|
||||
return count;
|
||||
}
|
||||
|
||||
for (int i = 0; i < str.length(); i++) {
|
||||
char tmp = str.charAt(i);
|
||||
if (!excludeChart.contains(tmp)) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取阅读时长 单位:分钟
|
||||
*
|
||||
* @param wordCount 文本字数
|
||||
* @return 阅读时长
|
||||
*/
|
||||
public static Double getReadDuration(Integer wordCount) {
|
||||
return wordCount / READ_SPEED;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取简要信息
|
||||
*
|
||||
* @param content 博客内容
|
||||
* @return 简要信息
|
||||
*/
|
||||
public static String getBlogSummary(String content) {
|
||||
if (content.length() > BLOG_SUMMARY_COUNT) {
|
||||
return content.substring(0, BLOG_SUMMARY_COUNT);
|
||||
}
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
public static String getHexTimeStamp() {
|
||||
return Long.toHexString(System.currentTimeMillis());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.cxx.admin.util;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class FileUtils {
|
||||
public static String getFileType(String fileName) {
|
||||
int lastIndex = fileName.lastIndexOf('.');
|
||||
if (lastIndex != -1) {
|
||||
return fileName.substring(lastIndex + 1);
|
||||
}
|
||||
return "未知类型";
|
||||
}
|
||||
|
||||
public static String formatSize(long size) {
|
||||
if (size < 1024) {
|
||||
return size + " B";
|
||||
} else if (size < 1024 * 1024) {
|
||||
return String.format("%.2f KB", (double) size / 1024);
|
||||
} else if (size < 1024 * 1024 * 1024) {
|
||||
return String.format("%.2f MB", (double) size / (1024 * 1024));
|
||||
} else {
|
||||
return String.format("%.2f GB", (double) size / (1024 * 1024 * 1024));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
125
admin-service/src/main/java/com/cxx/admin/util/FtpUtils.java
Normal file
125
admin-service/src/main/java/com/cxx/admin/util/FtpUtils.java
Normal file
@@ -0,0 +1,125 @@
|
||||
package com.cxx.admin.util;
|
||||
|
||||
import com.cxx.admin.dto.FtpInfo;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.net.PrintCommandListener;
|
||||
import org.apache.commons.net.ftp.FTPClient;
|
||||
import org.apache.commons.net.ftp.FTPFile;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* @Author: Cxx
|
||||
* @Date: 2024/9/24 21:49
|
||||
* @Description:
|
||||
*/
|
||||
@Slf4j
|
||||
public class FtpUtils {
|
||||
private static FTPClient ftpClient;
|
||||
|
||||
/**
|
||||
* 文件名分隔符
|
||||
*/
|
||||
public static String FILE_NAME_SPLIT = "_";
|
||||
|
||||
private static boolean connectFtp(FtpInfo ftpInfo) {
|
||||
try {
|
||||
ftpClient = new FTPClient();
|
||||
// 设置utf-8 编码 否则中文文件名会乱码
|
||||
ftpClient.setControlEncoding("utf-8");
|
||||
ftpClient.connect(ftpInfo.getFtpIp(), ftpInfo.getFtpPort());
|
||||
ftpClient.login(ftpInfo.getFtpUsername(), ftpInfo.getFtpPassword());
|
||||
ftpClient.addProtocolCommandListener(
|
||||
new PrintCommandListener(
|
||||
new PrintWriter(new OutputStreamWriter(System.out, StandardCharsets.UTF_8)), true));
|
||||
log.info("连接ftp服务器成功");
|
||||
} catch (IOException e) {
|
||||
log.error("连接ftp服务器失败:", e);
|
||||
throw new RuntimeException("连接ftp服务器失败");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void disConnectFtp() {
|
||||
try {
|
||||
if (ftpClient != null) {
|
||||
ftpClient.disconnect();
|
||||
}
|
||||
log.info("关闭ftp服务器成功");
|
||||
} catch (IOException e) {
|
||||
log.error("关闭ftp服务器失败:", e);
|
||||
throw new RuntimeException("关闭ftp服务器失败");
|
||||
}
|
||||
}
|
||||
|
||||
private static void closeInputStream(FileInputStream fileInputStream) {
|
||||
try {
|
||||
if (fileInputStream != null) {
|
||||
fileInputStream.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("关闭文件流失败:", e);
|
||||
throw new RuntimeException("关闭文件流失败");
|
||||
}
|
||||
}
|
||||
|
||||
public static void uploadFile(FtpInfo ftpInfo, String remotePath, String fileName, File file) {
|
||||
FileInputStream fileInputStream = null;
|
||||
|
||||
try {
|
||||
if (connectFtp(ftpInfo)) {
|
||||
ftpClient.changeWorkingDirectory(remotePath);
|
||||
ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
|
||||
fileInputStream = new FileInputStream(file);
|
||||
boolean uploadResult = ftpClient.storeFile(fileName, fileInputStream);
|
||||
if (uploadResult) {
|
||||
log.info("上传文件:{}成功", fileName);
|
||||
} else {
|
||||
throw new RuntimeException("上传ftp文件失败");
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("上传ftp文件异常:", e);
|
||||
throw new RuntimeException("上传ftp文件异常");
|
||||
} finally {
|
||||
disConnectFtp();
|
||||
closeInputStream(fileInputStream);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验是否存在文件
|
||||
*
|
||||
* @param ftpInfo ftp信息
|
||||
* @param remotePath 文件路径
|
||||
* @param md5 md5值
|
||||
* @return 校验结果
|
||||
*/
|
||||
public static boolean checkIsExitFile(FtpInfo ftpInfo, String remotePath, String md5) {
|
||||
boolean isExist = false;
|
||||
try {
|
||||
if (connectFtp(ftpInfo)) {
|
||||
ftpClient.changeWorkingDirectory(remotePath);
|
||||
FTPFile[] fileList = ftpClient.listFiles();
|
||||
if (fileList != null) {
|
||||
for (FTPFile imageFile : fileList) {
|
||||
String fileMd5 = imageFile.getName().split(FILE_NAME_SPLIT)[0];
|
||||
if (fileMd5.equals(md5)) {
|
||||
log.info("文件{}已经存在", imageFile.getName());
|
||||
isExist = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("校验ftp文件异常:", e);
|
||||
throw new RuntimeException("校验ftp文件异常");
|
||||
} finally {
|
||||
disConnectFtp();
|
||||
}
|
||||
|
||||
return isExist;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
package com.cxx.admin.util;
|
||||
|
||||
import cn.hutool.core.io.file.FileNameUtil;
|
||||
import com.cxx.admin.dto.file.ChunkInfoDto;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* @Author: chenxiuxiang
|
||||
* @Date: 2023/7/24 14:49
|
||||
* @Description: 上传文件工具类
|
||||
*/
|
||||
@Slf4j
|
||||
public class UploadFileUtil {
|
||||
private static final String FILE_SEPARATOR = "_";
|
||||
|
||||
/**
|
||||
* 校验文件夹是否存在
|
||||
*
|
||||
* @param path 路径
|
||||
*/
|
||||
public static void checkDirIsExist(String path) {
|
||||
File dir = new File(path);
|
||||
if (!dir.exists() && !dir.isDirectory()) {
|
||||
boolean mkdir = dir.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件路径
|
||||
*
|
||||
* @param path 上传文件夹路径
|
||||
* @param chunkInfo 分片文件信息
|
||||
* @return 文件路径
|
||||
*/
|
||||
public static String generateChunkPath(String path, ChunkInfoDto chunkInfo) {
|
||||
return path + File.separator + chunkInfo.getFilename() + FILE_SEPARATOR + chunkInfo.getChunkNumber();
|
||||
}
|
||||
|
||||
public static List<Integer> getUploadedChunkList(String folder, String filename) {
|
||||
List<Integer> uploadedChunkList = new ArrayList<>();
|
||||
|
||||
// 获取文件夹下所有的文件
|
||||
try (Stream<Path> list = Files.list(Paths.get(folder))) {
|
||||
// 去除需要合并的文件
|
||||
list.filter(path -> !path.getFileName().toString().equals(filename))
|
||||
// 循环遍历文件 将已经上传的文件序号添加至列表中
|
||||
.forEach(path -> {
|
||||
String chunkPath = path.getFileName().toString();
|
||||
int index = chunkPath.lastIndexOf(FILE_SEPARATOR);
|
||||
uploadedChunkList.add(Integer.valueOf(chunkPath.substring(index + 1)));
|
||||
});
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
||||
return uploadedChunkList;
|
||||
}
|
||||
|
||||
/**
|
||||
* 文件合并
|
||||
*/
|
||||
public static void mergeFile(String filename, String path) throws IOException {
|
||||
// 判断文件是否存在
|
||||
String file = path + File.separator + filename;
|
||||
if (fileExists(file)) {
|
||||
deleteFile(file);
|
||||
}
|
||||
|
||||
// 不存在的话,进行合并
|
||||
Files.createFile(Paths.get(file));
|
||||
|
||||
// 获取文件夹下所有的文件
|
||||
try (Stream<Path> list = Files.list(Paths.get(path))) {
|
||||
// 保留后缀包含分隔符的
|
||||
list.filter(chunkPath -> FileNameUtil.getSuffix(chunkPath.getFileName().toString()).contains(FILE_SEPARATOR))
|
||||
// 按照文件名排序
|
||||
.sorted((o1, o2) -> {
|
||||
String p1 = o1.getFileName().toString();
|
||||
String p2 = o2.getFileName().toString();
|
||||
int i1 = p1.lastIndexOf(FILE_SEPARATOR);
|
||||
int i2 = p2.lastIndexOf(FILE_SEPARATOR);
|
||||
return Integer.valueOf(p1.substring(i1 + 1))
|
||||
.compareTo(Integer.valueOf(p2.substring(i2 + 1)));
|
||||
})
|
||||
// 循环写入到文件中
|
||||
.forEach(chunkPath -> {
|
||||
try {
|
||||
// 以追加的形式写入文件
|
||||
Files.write(Paths.get(file), Files.readAllBytes(chunkPath), StandardOpenOption.APPEND);
|
||||
// 合并后删除该块
|
||||
Files.delete(chunkPath);
|
||||
} catch (IOException exception) {
|
||||
log.error("写入文件失败: " + exception.getMessage());
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据文件的全路径名判断文件是否存在
|
||||
*/
|
||||
public static boolean fileExists(String file) {
|
||||
Path path = Paths.get(file);
|
||||
return Files.exists(path, LinkOption.NOFOLLOW_LINKS);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除目录(文件夹)以及目录下的文件
|
||||
*
|
||||
* @param sPath 被删除目录的文件路径
|
||||
* @return 目录删除成功返回true,否则返回false
|
||||
*/
|
||||
public static boolean deleteDirectory(String sPath) {
|
||||
// 如果sPath不以文件分隔符结尾,自动添加文件分隔符
|
||||
if (!sPath.endsWith(File.separator)) {
|
||||
sPath = sPath + File.separator;
|
||||
}
|
||||
File dirFile = new File(sPath);
|
||||
// 如果dir对应的文件不存在,或者不是一个目录,则退出
|
||||
if (!dirFile.exists() || !dirFile.isDirectory()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean flag = true;
|
||||
// 删除文件夹下的所有文件(包括子目录)
|
||||
File[] files = dirFile.listFiles();
|
||||
for (File file : Objects.requireNonNull(files)) {
|
||||
// 删除子文件
|
||||
if (file.isFile()) {
|
||||
flag = deleteFile(file.getAbsolutePath());
|
||||
}
|
||||
// 删除子目录
|
||||
else {
|
||||
flag = deleteDirectory(file.getAbsolutePath());
|
||||
}
|
||||
if (!flag) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!flag) {
|
||||
return false;
|
||||
}
|
||||
|
||||
log.info("文件删除成功");
|
||||
// 删除当前目录
|
||||
return dirFile.delete();
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除单个文件
|
||||
*
|
||||
* @param sPath 被删除文件的文件名
|
||||
* @return 单个文件删除成功返回true,否则返回false
|
||||
*/
|
||||
public static boolean deleteFile(String sPath) {
|
||||
boolean flag = false;
|
||||
File file = new File(sPath);
|
||||
// 路径为文件且不为空则进行删除
|
||||
if (file.isFile() && file.exists()) {
|
||||
flag = file.delete();
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
}
|
||||
15
admin-service/src/main/resources/application-dev.yml
Normal file
15
admin-service/src/main/resources/application-dev.yml
Normal file
@@ -0,0 +1,15 @@
|
||||
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:
|
||||
|
||||
file:
|
||||
path: D:\\temp\\
|
||||
log-path: D:\\temp\\
|
||||
16
admin-service/src/main/resources/application-docker.yml
Normal file
16
admin-service/src/main/resources/application-docker.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
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
|
||||
|
||||
file:
|
||||
path: /upload-file/
|
||||
16
admin-service/src/main/resources/application-prod.yml
Normal file
16
admin-service/src/main/resources/application-prod.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
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
|
||||
|
||||
file:
|
||||
path: /root/docker/upload-file/
|
||||
log-path: /root/service/logs/
|
||||
36
admin-service/src/main/resources/application.yml
Normal file
36
admin-service/src/main/resources/application.yml
Normal file
@@ -0,0 +1,36 @@
|
||||
server:
|
||||
port: 8080
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: @project.artifactId@
|
||||
version: @project.version@
|
||||
profiles:
|
||||
active: dev
|
||||
servlet:
|
||||
multipart:
|
||||
max-file-size: 10MB
|
||||
max-request-size: 100MB
|
||||
|
||||
# mybatis plus mapper路径
|
||||
mybatis-plus:
|
||||
# mybatis plus
|
||||
mapper-locations: classpath*:/mapper/**/*.xml
|
||||
configuration:
|
||||
log-impl:
|
||||
org.apache.ibatis.logging.stdout.StdOutImpl
|
||||
|
||||
ftp:
|
||||
ip: 192.168.31.54
|
||||
port: 21
|
||||
username: ftp-cxx
|
||||
password: 19940822cxx
|
||||
|
||||
influxdb:
|
||||
url: http://localhost:8086
|
||||
token: i3eja-5jMQBxxF29pvKBialZ_j4y3p8iAMI86Ht3YcMTXhitIeUfx30vAv79xfhckC5YExTKj91AribNwBZBOQ==
|
||||
org: cxx
|
||||
bucket: server_metrics
|
||||
|
||||
web-starter:
|
||||
base-package: com.cxx.service
|
||||
120
admin-service/src/main/resources/logback-spring-drop.xml
Normal file
120
admin-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/adminService"/>
|
||||
|
||||
<!--控制台日志格式:彩色日志-->
|
||||
<!-- 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>
|
||||
13
admin-service/src/main/resources/mapper/AccountMapper.xml
Normal file
13
admin-service/src/main/resources/mapper/AccountMapper.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?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.admin.dao.AccountDao">
|
||||
<select id="queryAccount" resultType="com.cxx.admin.dto.user.AccountDto">
|
||||
SELECT b.id AS id,
|
||||
b.account_name AS accountName,
|
||||
a.username AS username,
|
||||
b.state AS state,
|
||||
b.create_time AS date
|
||||
FROM user as a
|
||||
LEFT JOIN account as b on a.id = b.user_id
|
||||
</select>
|
||||
</mapper>
|
||||
64
admin-service/src/main/resources/mapper/BlogMapper.xml
Normal file
64
admin-service/src/main/resources/mapper/BlogMapper.xml
Normal file
@@ -0,0 +1,64 @@
|
||||
<?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.admin.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="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="queryBlogVisit" resultType="com.cxx.common.dto.blog.BlogVisitDto">
|
||||
SELECT a.ip AS ip,
|
||||
a.os AS os,
|
||||
a.browser AS browser,
|
||||
a.uri AS uri,
|
||||
b.title AS title,
|
||||
a.create_time AS visitTime
|
||||
FROM blog_visit AS a
|
||||
LEFT JOIN blog AS b on a.blog_id = b.id
|
||||
ORDER BY a.create_time DESC
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -0,0 +1,21 @@
|
||||
package com.cxx.admin;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
@SpringBootTest
|
||||
public class AdminServiceApplicationTests {
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestEmail() {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user