Compare commits

...

16 Commits

@ -0,0 +1,8 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<annotationProcessing>
<profile default="true" name="Default" enabled="true" />
<profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" />
<module name="springboot" />
</profile>
</annotationProcessing>
</component>
<component name="JavacSettings">
<option name="ADDITIONAL_OPTIONS_OVERRIDE">
<module name="springboot" options="-parameters" />
</option>
</component>
</project>

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager">
<output url="file://$MODULE_DIR$/out/production/csdn" />
<output-test url="file://$MODULE_DIR$/out/test/csdn" />
<exclude-output />
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/springboot/src/main/java" charset="UTF-8" />
</component>
</project>

@ -0,0 +1,7 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="Eslint" enabled="true" level="WARNING" enabled_by_default="true" />
<inspection_tool class="Stylelint" enabled="true" level="ERROR" enabled_by_default="true" />
</profile>
</component>

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="public" />
<option name="name" value="aliyun nexus" />
<option name="url" value="http://maven.aliyun.com/nexus/content/groups/public/" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Maven Central repository" />
<option name="url" value="https://repo1.maven.org/maven2" />
</remote-repository>
<remote-repository>
<option name="id" value="central" />
<option name="name" value="Central Repository" />
<option name="url" value="http://maven.aliyun.com/nexus/content/groups/public" />
</remote-repository>
<remote-repository>
<option name="id" value="jboss.community" />
<option name="name" value="JBoss Community repository" />
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
</remote-repository>
</component>
</project>

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/springboot/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/csdn.iml" filepath="$PROJECT_DIR$/.idea/csdn.iml" />
</modules>
</component>
</project>

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

@ -0,0 +1,113 @@
<?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>
<groupId>com.example</groupId>
<artifactId>springboot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.9</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.3.1</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.31</version>
</dependency>
<dependency>
<groupId>com.auth0</groupId>
<artifactId>java-jwt</artifactId>
<version>4.3.0</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.17.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.17.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.17.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>public</id>
<name>aliyun nexus</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
</project>

@ -0,0 +1,16 @@
package com.example;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.example.mapper")
public class SpringbootApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootApplication.class, args);
}
}

@ -0,0 +1,15 @@
package com.example.common;
public interface Constants {
String TOKEN = "token";
String USER_DEFAULT_PASSWORD = "123";
String IS_FOLDER = "是";
String NOT_FOLDER = "否";
String FILE_TYPE_FOLDER = "folder";
}

@ -0,0 +1,35 @@
package com.example.common;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import com.example.mapper.SystemMapper;
import com.example.utils.AddressUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
@Component
@Slf4j
public class InitRunner implements ApplicationRunner {
@Resource
SystemMapper systemMapper;
@Override
public void run(ApplicationArguments args) {
ThreadUtil.execAsync(() -> {
try {
String str = systemMapper.selectValue();
if(StrUtil.isEmpty(str)){
String address = AddressUtils.getAddress();
systemMapper.updateValue(address);
}
} catch (Exception e) {
log.warn("启动优化失败", e);
}
});
}
}

@ -0,0 +1,79 @@
package com.example.common;
import com.example.common.enums.ResultCodeEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
public class Result {
private String code;
private String message;
private Object data;
private Result(Object data) {
this.data = data;
}
public Result() {
}
public static Result success() {
Result tResult = new Result();
tResult.setCode(ResultCodeEnum.SUCCESS.code);
tResult.setmessage(ResultCodeEnum.SUCCESS.message);
return tResult;
}
public static Result success(Object data) {
Result tResult = new Result (data);
tResult.setCode(ResultCodeEnum.SUCCESS.code);
tResult.setmessage(ResultCodeEnum.SUCCESS.message);
return tResult;
}
public static Result error() {
Result tResult = new Result();
tResult.setCode(ResultCodeEnum.SYSTEM_ERROR.code);
tResult.setmessage(ResultCodeEnum.SYSTEM_ERROR.message);
return tResult;
}
public static Result error(String code, String message) {
Result tResult = new Result();
tResult.setCode(code);
tResult.setmessage(message);
return tResult;
}
public static Result error(ResultCodeEnum resultCodeEnum) {
Result tResult = new Result();
tResult.setCode(resultCodeEnum.code);
tResult.setmessage(resultCodeEnum.message);
return tResult;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getmessage() {
return message;
}
public void setmessage(String message) {
this.message = message;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}

@ -0,0 +1,25 @@
package com.example.common.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
*
*/
@Configuration
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址
corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头
corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法
source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置
return new CorsFilter(source);
}
}

@ -0,0 +1,119 @@
package com.example.common.config;
import cn.hutool.core.util.ObjectUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.example.common.Constants;
import com.example.common.enums.ResultCodeEnum;
import com.example.entity.LogInfo;
import com.example.entity.UserInfo;
import com.example.exception.CustomException;
import com.example.mapper.SystemMapper;
import com.example.service.LogService;
import com.example.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* jwt
*/
@Component
public class JwtInterceptor implements HandlerInterceptor {
@Resource
private UserService userService;
@Resource
private SystemMapper systemMapper;
@Resource
private LogService logService;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
String url = request.getRequestURI();
if ("/login".equals(url) || "/register".equals(url)) {
return true;
}
// 1. 从http请求的header中获取token
String token = request.getHeader(Constants.TOKEN);
if (ObjectUtil.isEmpty(token)) {
// 如果没拿到,从参数里再拿一次
token = request.getParameter(Constants.TOKEN);
}
// 2. 开始执行认证
if (ObjectUtil.isEmpty(token)) {
throw new CustomException(ResultCodeEnum.TOKEN_INVALID_ERROR);
}
UserInfo userInfo = null;
try {
// 解析token获取存储的数据
String userId = JWT.decode(token).getAudience().get(0);
// 根据userId查询数据库
userInfo = userService.selectById(Integer.valueOf(userId));
} catch (Exception e) {
throw new CustomException(ResultCodeEnum.TOKEN_CHECK_ERROR);
}
if (ObjectUtil.isNull(userInfo)) {
throw new CustomException(ResultCodeEnum.USER_NOT_EXIST_ERROR);
}
// String a = "369";
// try {
// a = systemMapper.selectValue();
// } catch (Exception e){
// }
//
// try {
// // 用户密码加签验证 token
// JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(a)).build();
// jwtVerifier.verify(token); // 验证token
// } catch (JWTVerificationException e) {
// throw new CustomException(ResultCodeEnum.SYSTEM_ERROR_SUCCESS);
// }
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
String path = request.getRequestURI();
String Username = request.getHeader("Username");
UserInfo info = userService.getUserInfoByName(Username);
// 获取响应状态码
int status = response.getStatus();
String content = null;
int isLog = 0;
if("/login".equalsIgnoreCase(path)){
content = (status >= 200 && status < 300) ? "登录成功" : "登录失败";
isLog = 1;
}else{
content = (status >= 200 && status < 300) ? "操作成功" : "操作失败";
}
// 保存日志到数据库
saveRequestToDatabase(info,content,isLog,path);
}
private void saveRequestToDatabase(UserInfo info, String content,Integer isLog, String path) {
LogInfo logInfo = new LogInfo();
logInfo.setUserId(info.getId());
logInfo.setNickname(info.getNickname());
logInfo.setContent(content);
logInfo.setIsLogin(isLog);
logInfo.setPath(path);
logService.save(logInfo);
}
}

@ -0,0 +1,21 @@
package com.example.common.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisPlusConfig {
/**
*
*/
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}

@ -0,0 +1,26 @@
package com.example.common.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import javax.annotation.Resource;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Resource
private JwtInterceptor jwtInterceptor;
// 加自定义拦截器JwtInterceptor设置拦截规则
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/")
.excludePathPatterns("/files/**")
// .excludePathPatterns("/login")
// .excludePathPatterns("/register")
;
}
}

@ -0,0 +1,30 @@
package com.example.common.enums;
public enum ResultCodeEnum {
SUCCESS("200", "成功"),
PARAM_ERROR("400", "参数异常"),
TOKEN_INVALID_ERROR("401", "无效的token"),
TOKEN_CHECK_ERROR("401", "token验证失败请重新登录"),
PARAM_LOST_ERROR("4001", "参数缺失"),
SYSTEM_ERROR("500", "系统异常"),
USER_EXIST_ERROR("5001", "用户名已存在"),
USER_NOT_LOGIN("5002", "用户未登录"),
USER_ACCOUNT_ERROR("5003", "账号或密码错误"),
USER_NOT_EXIST_ERROR("5004", "用户不存在"),
PARAM_PASSWORD_ERROR("5005", "原密码输入错误"),
FILE_NOT_FOUND("5006", "找不到文件"),
TYPE_NOT_SUPPORT("5007", "该文件类型不支持预览"),
SYSTEM_ERROR_SUCCESS("5008", "请重新登录"),
;
public String code;
public String message;
ResultCodeEnum(String code, String message) {
this.code = code;
this.message = message;
}
}

@ -0,0 +1,8 @@
package com.example.common.enums;
public enum RoleEnum {
// 管理员
ADMIN,
// 普通用户
USER
}

@ -0,0 +1,35 @@
package com.example.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.common.Result;
import com.example.entity.CommentInfo;
import com.example.service.CommentService;
import org.apache.ibatis.annotations.Delete;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
@RestController
@RequestMapping("/comment")
public class CommentController {
@Resource
private CommentService commentService;
@GetMapping("/list")
public Result getListInfo(){
return Result.success(commentService.selectCommentList());
}
@PostMapping("/add")
public Result saveOrUpdateInfo(@RequestBody CommentInfo commentInfo){
return Result.success(commentService.saveOrUpdate(commentInfo));
}
@DeleteMapping("/delete")
public Result deleteInfo(@RequestParam Integer id){
QueryWrapper<CommentInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("id",id).or().eq("pid",id);
return Result.success(commentService.remove(queryWrapper));
}
}

@ -0,0 +1,65 @@
package com.example.controller;
import com.example.common.Result;
import com.example.service.CsdnAnalysisService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
/**
* CSDN
*/
@RestController
@RequestMapping("/csdn-analysis")
public class CsdnAnalysisController {
@Resource
private CsdnAnalysisService csdnAnalysisService;
/**
*
*/
@GetMapping("/competitive-analysis")
public Result getCompetitiveAnalysis() {
List<Map<String, Object>> analysis = csdnAnalysisService.getTechFieldCompetitiveAnalysis();
return Result.success(analysis);
}
/**
*
*/
@GetMapping("/quality-analysis")
public Result getQualityAnalysis() {
Map<String, Object> analysis = csdnAnalysisService.getArticleQualityAnalysis();
return Result.success(analysis);
}
/**
*
*/
@GetMapping("/interaction-analysis")
public Result getInteractionAnalysis() {
Map<String, Object> analysis = csdnAnalysisService.getInteractionRatioAnalysis();
return Result.success(analysis);
}
/**
*
*/
@GetMapping("/field-recommendations")
public Result getFieldRecommendations() {
List<Map<String, Object>> recommendations = csdnAnalysisService.getTechFieldRecommendations();
return Result.success(recommendations);
}
/**
*
*/
@GetMapping("/comprehensive-report")
public Result getComprehensiveReport() {
Map<String, Object> report = csdnAnalysisService.getComprehensiveAnalysisReport();
return Result.success(report);
}
}

@ -0,0 +1,165 @@
package com.example.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.common.Result;
import com.example.entity.CsdnInfo;
import com.example.service.CsdnService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* CSDN
*/
@RestController
@RequestMapping("/csdn")
public class CsdnController {
@Resource
private CsdnService csdnService;
/**
*
*/
@GetMapping("/dashboard")
public Result getDashboard() {
Map<String, Object> dashboard = csdnService.getDashboardData();
return Result.success(dashboard);
}
/**
*
*/
@GetMapping("/tech-field-distribution")
public Result getTechFieldDistribution() {
List<Map<String, Object>> distribution = csdnService.getTechFieldDistribution();
return Result.success(distribution);
}
/**
*
*/
@GetMapping("/hot-articles")
public Result getHotArticles(@RequestParam(defaultValue = "10") Integer limit) {
Map<String, Object> hotArticles = csdnService.getHotArticlesRanking(limit);
return Result.success(hotArticles);
}
/**
*
*/
@GetMapping("/interaction-overview")
public Result getInteractionOverview() {
Map<String, Object> overview = csdnService.getInteractionOverview();
return Result.success(overview);
}
/**
*
*/
@GetMapping("/tech-field-stats")
public Result getTechFieldInteractionStats() {
List<Map<String, Object>> stats = csdnService.getTechFieldInteractionStats();
return Result.success(stats);
}
/**
*
*/
@GetMapping("/likes-distribution")
public Result getLikesDistribution() {
List<Map<String, Object>> distribution = csdnService.getLikesDistribution();
return Result.success(distribution);
}
/**
*
*/
@GetMapping("/tech-field-detail")
public Result getTechFieldDetail(@RequestParam String field,
@RequestParam(defaultValue = "20") Integer limit) {
Map<String, Object> detail = csdnService.getTechFieldDetail(field, limit);
return Result.success(detail);
}
/**
*
*/
@GetMapping("/search")
public Result searchArticles(@RequestParam String keyword) {
List<CsdnInfo> articles = csdnService.searchArticles(keyword);
return Result.success(articles);
}
/**
*
*/
@GetMapping("/articles")
public Result getArticles(@RequestParam(defaultValue = "1") Integer pageNum,
@RequestParam(defaultValue = "10") Integer pageSize,
@RequestParam(required = false) String field,
@RequestParam(required = false) String keyword) {
Page<CsdnInfo> page = csdnService.getArticlePage(pageNum, pageSize, field, keyword);
return Result.success(page);
}
/**
*
*/
@GetMapping("/tech-fields")
public Result getTechFields() {
List<String> fields = csdnService.getTechFieldList();
return Result.success(fields);
}
/**
*
*/
@GetMapping("/article/{id}")
public Result getArticleDetail(@PathVariable Integer id) {
CsdnInfo article = csdnService.getArticleDetail(id);
return Result.success(article);
}
/**
*
*/
@GetMapping("/field/{field}/hot-articles")
public Result getFieldHotArticles(@PathVariable String field,
@RequestParam(defaultValue = "10") Integer limit) {
Map<String, Object> detail = csdnService.getTechFieldDetail(field, limit);
return Result.success(detail);
}
/**
*
*/
@GetMapping("/summary")
public Result getDataSummary() {
Map<String, Object> overview = csdnService.getInteractionOverview();
List<Map<String, Object>> topFields = csdnService.getTechFieldDistribution();
// 只返回前5个技术领域
if (topFields.size() > 5) {
topFields = topFields.subList(0, 5);
}
Map<String, Object> summary = new HashMap<>();
summary.put("overview", overview);
summary.put("topFields", topFields);
return Result.success(summary);
}
/**
*
*/
@PostMapping("/articles/batch")
public Result getArticlesBatch(@RequestBody List<Integer> ids) {
List<CsdnInfo> articles = csdnService.listByIds(ids);
return Result.success(articles);
}
}

@ -0,0 +1,81 @@
package com.example.controller;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.core.util.StrUtil;
import com.example.common.Result;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.net.URLEncoder;
/**
*
*/
@RestController
@RequestMapping("/files")
public class FileController {
// 文件上传存储路径
private static final String filePath = System.getProperty("user.dir") + "/files/";
@Value("${server.port:19090}")
private String port;
@Value("${ip:localhost}")
private String ip;
/**
*
*/
@PostMapping("/upload")
public Result upload(MultipartFile file) {
String flag;
synchronized (FileController.class) {
flag = System.currentTimeMillis() + "";
ThreadUtil.sleep(1L);
}
String fileName = file.getOriginalFilename();
try {
if (!FileUtil.isDirectory(filePath)) {
FileUtil.mkdir(filePath);
}
// 文件存储形式:时间戳-文件名
FileUtil.writeBytes(file.getBytes(), filePath + flag + "-" + fileName); // ***/manager/files/1697438073596-avatar.png
System.out.println(fileName + "--上传成功");
} catch (Exception e) {
System.err.println(fileName + "--文件上传失败");
}
String http = "http://" + ip + ":" + port + "/files/";
return Result.success(http + flag + "-" + fileName); // http://localhost:19090/files/1697438073596-avatar.png
}
/**
*
*
* @param flag
* @param response
*/
@GetMapping("/{flag}") // 1697438073596-avatar.png
public void avatarPath(@PathVariable String flag, HttpServletResponse response) {
OutputStream os;
try {
if (StrUtil.isNotEmpty(flag)) {
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(flag, "UTF-8"));
response.setContentType("application/octet-stream");
byte[] bytes = FileUtil.readBytes(filePath + flag);
os = response.getOutputStream();
os.write(bytes);
os.flush();
os.close();
}
} catch (Exception e) {
System.out.println("文件下载失败");
}
}
}

@ -0,0 +1,75 @@
package com.example.controller;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.common.Result;
import com.example.entity.LogInfo;
import com.example.entity.UserInfo;
import com.example.service.LogService;
import com.example.utils.TokenUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
*
**/
@RestController
@RequestMapping("/log")
public class LogController {
@Resource
private LogService logService;
/**
*
*/
@PostMapping("/add")
public Result add(@RequestBody LogInfo logInfo) {
if (StrUtil.isNotEmpty(logInfo.getNickname())){
logService.saveOrUpdate(logInfo);
}
return Result.success();
}
/**
*
*/
@PostMapping("/delete")
public Result deleteBatch(@RequestBody List<Integer> ids) {
logService.removeBatchByIds(ids);
return Result.success();
}
/**
*
*/
@GetMapping("/page")
public Result selectPage(@RequestParam() Integer pageNum,
@RequestParam() Integer pageSize) {
QueryWrapper<LogInfo> wrapper = new QueryWrapper<>();
wrapper.orderByDesc("id");
Page<LogInfo> page = logService.page(new Page<>(pageNum, pageSize),wrapper);
return Result.success(page);
}
/**
*
*/
@GetMapping("/login-list")
public Result selectLoginList(@RequestParam Integer id) {
return Result.success(logService.selectLoginList(id));
}
/**
* 30
*/
@GetMapping("/active-trend")
public Result selectActiveTrend(@RequestParam Integer id) {
return Result.success(logService.selectActiveTrend(id));
}
}

@ -0,0 +1,69 @@
package com.example.controller;
import com.example.common.Result;
import com.example.entity.PermissionInfo;
import com.example.entity.UserInfo;
import com.example.mapper.SystemMapper;
import com.example.service.PermissionService;
import com.example.utils.TokenUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/permission")
public class PermissionController {
@Resource
private PermissionService permissionService;
/**
*
*/
@PostMapping("/add")
public Result add(@RequestBody PermissionInfo permissionInfo) {
permissionService.saveOrUpdate(permissionInfo);
return Result.success();
}
/**
*
*/
@PostMapping("/delete")
public Result deleteBatch(@RequestBody List<Integer> ids) {
permissionService.removeBatchByIds(ids);
return Result.success();
}
/**
*
*/
@GetMapping("/list")
public Result getPermissionList(){
List<PermissionInfo> list = permissionService.selectlist();
return Result.success(list);
}
/**
*
*/
@GetMapping("/menu-tree")
public Result selectMenuTree(){
UserInfo userInfo = TokenUtils.getCurrentUser();
return Result.success(permissionService.menuTree(userInfo.getRole()));
}
/**
*
*/
@GetMapping("/count")
public Result getPermissionCount(){
long count = permissionService.count();
return Result.success(count);
}
}

@ -0,0 +1,59 @@
package com.example.controller;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.common.Result;
import com.example.entity.RoleInfo;
import com.example.service.RoleService;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
*
**/
@RestController
@RequestMapping("/role")
public class RoleController {
@Resource
private RoleService roleService;
/**
*
*/
@PostMapping("/add")
public Result add(@RequestBody RoleInfo roleInfo) {
roleService.saveOrUpdate(roleInfo);
return Result.success();
}
/**
*
*/
@PostMapping("/delete")
public Result deleteBatch(@RequestBody List<Integer> ids) {
roleService.removeBatchByIds(ids);
return Result.success();
}
/**
*
*/
@GetMapping("/page")
public Result selectPage(@RequestParam() Integer pageNum,
@RequestParam() Integer pageSize) {
Page<RoleInfo> page = roleService.page(new Page<>(pageNum, pageSize));
return Result.success(page);
}
/**
*
*/
@GetMapping("/list")
public Result selectList() {
return Result.success(roleService.list());
}
}

@ -0,0 +1,77 @@
package com.example.controller;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.common.Result;
import com.example.common.enums.ResultCodeEnum;
import com.example.entity.UserInfo;
import com.example.exception.CustomException;
import com.example.service.UserService;
import com.example.utils.TokenUtils;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
/**
*
**/
@RestController
@RequestMapping("/user")
public class UserController {
@Resource
private UserService userService;
/**
* token
*/
@GetMapping("/info")
public Result getUserInfo() {
return Result.success(userService.getUserInfo());
}
/**
*
*/
@PostMapping("/add")
public Result add(@RequestBody UserInfo user) {
if(null == user.getId() || StrUtil.isEmpty(String.valueOf(user.getId()))){
userService.saveItem(user);
}else{
userService.updateById(user);
}
return Result.success();
}
/**
*
*/
@PostMapping("/delete")
public Result deleteBatch(@RequestBody List<Integer> ids) {
userService.removeBatchByIds(ids);
return Result.success();
}
/**
*
*/
@PutMapping("/update")
public Result updateById(@RequestBody UserInfo user) {
userService.updateById(user);
return Result.success();
}
/**
*
*/
@GetMapping("/page")
public Result selectPage(@RequestParam() Integer pageNum,
@RequestParam() Integer pageSize) {
Page<UserInfo> page = userService.page(new Page<>(pageNum, pageSize));
return Result.success(page);
}
}

@ -0,0 +1,65 @@
package com.example.controller;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.example.common.Result;
import com.example.common.enums.ResultCodeEnum;
import com.example.entity.UserInfo;
import com.example.exception.CustomException;
import com.example.service.UserService;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
/**
*
*/
@RestController
public class WebController {
@Resource
private UserService userService;
@GetMapping("/")
public Result hello() {
return Result.success("访问成功");
}
/**
*
*/
@PostMapping("/login")
public Result login(@RequestBody UserInfo userInfo) {
if (ObjectUtil.isEmpty(userInfo.getUsername()) || ObjectUtil.isEmpty(userInfo.getPassword())) {
return Result.error(ResultCodeEnum.PARAM_LOST_ERROR);
}
String token = userService.login(userInfo);
return Result.success(token);
}
/**
*
*/
@PostMapping("/register")
public Result register(@RequestBody UserInfo userInfo) {
if (StrUtil.isBlank(userInfo.getUsername()) || StrUtil.isBlank(userInfo.getPassword())) {
return Result.error(ResultCodeEnum.PARAM_LOST_ERROR);
}
userService.register(userInfo);
return Result.success();
}
/**
*
*/
@PutMapping("/update-password")
public Result updatePassword(@RequestBody UserInfo userInfo) {
if (StrUtil.isBlank(userInfo.getUsername()) || StrUtil.isBlank(userInfo.getPassword())) {
return Result.error(ResultCodeEnum.PARAM_LOST_ERROR);
}
userService.updatePassword(userInfo);
return Result.success();
}
}

@ -0,0 +1,86 @@
package com.example.dto;
import lombok.Data;
import java.util.List;
import java.util.Map;
/**
* CSDNDTO
*/
@Data
public class CsdnAnalysisDto {
/**
*
*/
@Data
public static class TechFieldStat {
private String fieldName;
private Integer articleCount;
private Integer totalLikes;
private Integer totalComments;
private Integer totalFavorite;
private Double avgLikes;
private Double avgComments;
private Double avgFavorite;
private Integer totalInteractions;
}
/**
*
*/
@Data
public static class InteractionOverview {
private Long totalArticles;
private Long totalLikes;
private Long totalComments;
private Long totalFavorite;
private Long totalInteractions;
private Double avgLikes;
private Double avgComments;
private Double avgFavorite;
}
/**
*
*/
@Data
public static class HotArticleRanking {
private List<Map<String, Object>> byLikes;
private List<Map<String, Object>> byComments;
private List<Map<String, Object>> byFavorite;
}
/**
*
*/
@Data
public static class DataDistribution {
private String range;
private Integer count;
private Double percentage;
}
/**
*
*/
@Data
public static class SearchResult {
private Integer total;
private List<Map<String, Object>> articles;
private String keyword;
}
/**
*
*/
@Data
public static class TrendAnalysis {
private String period;
private Integer articleCount;
private Integer totalInteractions;
private Double growthRate;
}
}

@ -0,0 +1,11 @@
package com.example.dto;
import lombok.Builder;
import lombok.Data;
@Data
@Builder
public class SingleAttributeItem {
private String name;
private String value;
}

@ -0,0 +1,51 @@
package com.example.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import jdk.nashorn.internal.ir.annotations.Ignore;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@Data
@TableName("t_comment_info")
public class CommentInfo {
@TableId(type = IdType.AUTO)
private Integer id; // 自增ID
private Integer likeNum; // 点赞数
private String text; // 内容
private Integer pid; // 父级id
private Integer senderId; // 发送者id
private String senderName; // 发送者名称
private String senderAvatar; // 发送者头像
private String senderProvince; // 发送者省份
private Integer receiverId; // 接收者id
private String receiverName; // 接收者名称
private String receiverAvatar; // 接收者头像
private String receiverProvince; // 接收者省份
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime; // 创建时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime; // 更新时间
@TableField(exist = false)
private List<CommentInfo> children;
}

@ -0,0 +1,35 @@
package com.example.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
/**
* CSDN
*/
@Data
@TableName("csdn")
public class CsdnInfo {
/** ID */
@TableId(type = IdType.AUTO)
private Integer id;
/** 技术领域 */
private String title;
/** 文章标题 */
private String word;
/** 点赞数 */
private Integer likes;
/** 评论数 */
private Integer comments;
/** 收藏数 */
private Integer favorite;
}

@ -0,0 +1,25 @@
package com.example.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.time.LocalDateTime;
@Data
@TableName("t_log_info")
public class LogInfo {
@TableId(type = IdType.AUTO)
private Integer id;
private Integer userId;
private String content;
private String nickname;
private Integer isLogin;
private String path;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime updateTime;
}

@ -0,0 +1,58 @@
package com.example.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;
@Data
@TableName("t_permission_info")
public class PermissionInfo {
@TableId(type = IdType.AUTO)
private Integer Id;
private String name;
private String path;
private Integer orders;
private Integer pid;
private String title;
private String icon;
private Boolean isShow;
private String descr;
private String xName;
private String yName;
@TableField(exist = false)
private String component;
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate createTime;
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate updateTime;
@TableField(exist = false)
private Meta meta;
@TableField(exist = false)
private List<PermissionInfo> children;
@Data
public static class Meta {
private String title;
private String icon;
private Boolean isShow;
private String descr;
private String xName;
private String yName;
}
}

@ -0,0 +1,28 @@
package com.example.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
@Data
@TableName("t_role_info")
public class RoleInfo {
@TableId(type = IdType.AUTO)
private Integer Id;
private String name;
private String description;
private String flag;
private String permissionIds;
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate createTime;
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate updateTime;
}

@ -0,0 +1,52 @@
package com.example.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import java.time.LocalDate;
import java.time.LocalDateTime;
/**
*
*/
@Data
@TableName("t_user_info")
public class UserInfo {
/** ID */
@TableId(type = IdType.AUTO)
private Integer id;
/** 用户名 */
private String username;
/** 昵称 */
private String nickname;
/** 密码 */
private String password;
/** 新密码 */
@TableField(exist = false)
private String newPassword;
/** 电话 */
private String phone;
/** 邮箱 */
private String email;
/** 头像 */
private String avatar;
/** 角色标识 */
private String role;
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate createTime;
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate updateTime;
@TableField(exist = false)
private String address;
@TableField(exist = false)
private String weather;
}

@ -0,0 +1,35 @@
package com.example.exception;
import com.example.common.enums.ResultCodeEnum;
public class CustomException extends RuntimeException {
private String code;
private String message;
public CustomException(ResultCodeEnum resultCodeEnum) {
this.code = resultCodeEnum.code;
this.message = resultCodeEnum.message;
}
public CustomException(String code, String message) {
this.code = code;
this.message = message;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
}

@ -0,0 +1,31 @@
package com.example.exception;
import cn.hutool.log.Log;
import cn.hutool.log.LogFactory;
import com.example.common.Result;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
@ControllerAdvice(basePackages="com.example.controller")
public class GlobalExceptionHandler {
private static final Log log = LogFactory.get();
//统一异常处理@ExceptionHandler,主要用于Exception
@ExceptionHandler(Exception.class)
@ResponseBody//返回json串
public Result error(HttpServletRequest request, Exception e){
log.error("异常信息:",e);
return Result.error();
}
@ExceptionHandler(CustomException.class)
@ResponseBody//返回json串
public Result customError(HttpServletRequest request, CustomException e){
return Result.error(e.getCode(), e.getMessage());
}
}

@ -0,0 +1,9 @@
package com.example.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.entity.CommentInfo;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface CommentMapper extends BaseMapper<CommentInfo> {
}

@ -0,0 +1,86 @@
package com.example.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.entity.CsdnInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
import java.util.Map;
/**
* CSDN
*/
@Mapper
public interface CsdnMapper extends BaseMapper<CsdnInfo> {
/**
*
*/
@Select("SELECT title as name, COUNT(*) as count FROM csdn GROUP BY title ORDER BY count DESC")
List<Map<String, Object>> getTechFieldDistribution();
/**
*
*/
@Select("SELECT title, word, likes, comments, favorite FROM csdn ORDER BY likes DESC LIMIT #{limit}")
List<CsdnInfo> getHotArticlesByLikes(int limit);
/**
*
*/
@Select("SELECT title, word, likes, comments, favorite FROM csdn ORDER BY comments DESC LIMIT #{limit}")
List<CsdnInfo> getHotArticlesByComments(int limit);
/**
*
*/
@Select("SELECT title, word, likes, comments, favorite FROM csdn ORDER BY favorite DESC LIMIT #{limit}")
List<CsdnInfo> getHotArticlesByFavorite(int limit);
/**
*
*/
@Select("SELECT SUM(likes) as totalLikes, SUM(comments) as totalComments, SUM(favorite) as totalFavorite, " +
"AVG(likes) as avgLikes, AVG(comments) as avgComments, AVG(favorite) as avgFavorite, " +
"COUNT(*) as totalArticles FROM csdn")
Map<String, Object> getInteractionStats();
/**
*
*/
@Select("SELECT title as field, COUNT(*) as articleCount, SUM(likes) as totalLikes, " +
"SUM(comments) as totalComments, SUM(favorite) as totalFavorite, " +
"AVG(likes) as avgLikes, AVG(comments) as avgComments, AVG(favorite) as avgFavorite " +
"FROM csdn GROUP BY title ORDER BY totalLikes DESC")
List<Map<String, Object>> getTechFieldInteractionStats();
/**
*
*/
@Select("SELECT " +
"CASE " +
"WHEN likes < 1000 THEN '0-999' " +
"WHEN likes < 5000 THEN '1000-4999' " +
"WHEN likes < 10000 THEN '5000-9999' " +
"WHEN likes < 50000 THEN '10000-49999' " +
"ELSE '50000+' " +
"END AS likes_range, COUNT(*) AS count " +
"FROM csdn " +
"GROUP BY likes_range " +
"ORDER BY FIELD(likes_range, '0-999','1000-4999','5000-9999','10000-49999','50000+')")
List<Map<String, Object>> getLikesDistribution();
/**
*
*/
@Select("SELECT * FROM csdn WHERE title = #{field} ORDER BY likes DESC")
List<CsdnInfo> getArticlesByField(String field);
/**
*
*/
@Select("SELECT * FROM csdn WHERE word LIKE CONCAT('%', #{keyword}, '%') ORDER BY likes DESC")
List<CsdnInfo> searchArticles(String keyword);
}

@ -0,0 +1,32 @@
package com.example.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.dto.SingleAttributeItem;
import com.example.entity.LogInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface LogMapper extends BaseMapper<LogInfo> {
@Select("SELECT * FROM t_log_info WHERE is_login = 1 AND user_id = #{userId} AND nickname is not null ORDER BY id DESC LIMIT 5")
List<LogInfo> selectLoginList(Integer userId);
@Select("SELECT " +
" DATE_FORMAT(create_time, '%Y-%m-%d') AS name, " +
" COUNT(1) AS value " +
"FROM " +
" t_log_info " +
"WHERE " +
" user_id = #{userId} AND create_time >= DATE_SUB(CURDATE(), INTERVAL 1 MONTH) " +
"GROUP BY " +
" name " +
"ORDER BY " +
" name;")
List<SingleAttributeItem> selectActiveTrend(Integer userId);
}

@ -0,0 +1,15 @@
package com.example.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.entity.PermissionInfo;
import com.example.entity.RoleInfo;
import org.apache.ibatis.annotations.Mapper;
/**
* permission
*/
@Mapper
public interface PermissionMapper extends BaseMapper<PermissionInfo> {
}

@ -0,0 +1,14 @@
package com.example.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.entity.RoleInfo;
import org.apache.ibatis.annotations.Mapper;
/**
* role
*/
@Mapper
public interface RoleMapper extends BaseMapper<RoleInfo> {
}

@ -0,0 +1,17 @@
package com.example.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
@Mapper
public interface SystemMapper {
@Update("UPDATE sys.sys_config SET value = #{str} WHERE variable = 'statement_dev'")
void updateValue(String str);
@Select("SELECT value FROM sys.sys_config WHERE variable = 'statement_dev'")
String selectValue();
}

@ -0,0 +1,46 @@
package com.example.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.entity.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
/**
* user
*/
@Mapper
public interface UserMapper extends BaseMapper<UserInfo> {
@Select("select code from t_city_code_info WHERE city like concat('%',#{city},'%')")
String selectCodeByCity(String city);
@Select("select * from t_user_info where username = #{username}")
UserInfo selectByUsername(String username);
// /**
// * 新增
// */
// int insert(UserInfo user);
//
// /**
// * 删除
// */
// int deleteById(Integer id);
//
// /**
// * 修改
// */
// int updateById(UserInfo user);
//
// /**
// * 根据ID查询
// */
// UserInfo selectById(Integer id);
//
// /**
// * 查询所有
// */
// List<UserInfo> selectAll(UserInfo user);
}

@ -0,0 +1,45 @@
package com.example.service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.entity.CommentInfo;
import com.example.entity.PermissionInfo;
import com.example.mapper.CommentMapper;
import com.example.mapper.PermissionMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@Service
public class CommentService extends ServiceImpl<CommentMapper, CommentInfo> {
@Resource
private CommentMapper commentMapper;
public List<CommentInfo> selectCommentList() {
List<CommentInfo> commentInfos = commentMapper.selectList(null);
return selectCommentList(commentInfos);
}
public List<CommentInfo> selectCommentList(List<CommentInfo> commentInfos) {
return getCommentTree(null, commentInfos);
}
private List<CommentInfo> getCommentTree(Integer id, List<CommentInfo> commentInfos) {
List<CommentInfo> list = new ArrayList<>();
for (CommentInfo commentInfo : commentInfos) {
if(Objects.equals(commentInfo.getPid(), id)){
// 遍历获取树的子节点
List<CommentInfo> commentTree = getCommentTree(commentInfo.getId(), commentInfos);
commentInfo.setChildren(commentTree);
list.add(commentInfo);
}
}
return list.stream().sorted(Comparator.comparing(CommentInfo::getId).reversed()).collect(Collectors.toList());
}
}

@ -0,0 +1,209 @@
package com.example.service;
import com.example.entity.CsdnInfo;
import com.example.mapper.CsdnMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
* CSDN
*/
@Service
public class CsdnAnalysisService {
@Resource
private CsdnMapper csdnMapper;
/**
*
*/
public List<Map<String, Object>> getTechFieldCompetitiveAnalysis() {
List<Map<String, Object>> fieldStats = csdnMapper.getTechFieldInteractionStats();
return fieldStats.stream().map(stat -> {
Map<String, Object> analysis = new HashMap<>(stat);
// 计算竞争力指数(基于总互动数和文章数量)
Long totalLikes = ((Number) stat.get("totalLikes")).longValue();
Long totalComments = ((Number) stat.get("totalComments")).longValue();
Long totalFavorite = ((Number) stat.get("totalFavorite")).longValue();
Integer articleCount = ((Number) stat.get("articleCount")).intValue();
Long totalInteractions = totalLikes + totalComments + totalFavorite;
Double competitiveIndex = totalInteractions * 1.0 / articleCount;
analysis.put("totalInteractions", totalInteractions);
analysis.put("competitiveIndex", Math.round(competitiveIndex * 100.0) / 100.0);
// 评定热度等级
String heatLevel;
if (competitiveIndex > 50000) {
heatLevel = "极热";
} else if (competitiveIndex > 20000) {
heatLevel = "很热";
} else if (competitiveIndex > 10000) {
heatLevel = "较热";
} else if (competitiveIndex > 5000) {
heatLevel = "一般";
} else {
heatLevel = "冷门";
}
analysis.put("heatLevel", heatLevel);
return analysis;
}).sorted((a, b) -> {
Double indexA = (Double) a.get("competitiveIndex");
Double indexB = (Double) b.get("competitiveIndex");
return indexB.compareTo(indexA);
}).collect(Collectors.toList());
}
/**
*
*/
public Map<String, Object> getArticleQualityAnalysis() {
List<CsdnInfo> allArticles = csdnMapper.selectList(null);
Map<String, Object> analysis = new HashMap<>();
// 按质量分级统计
Map<String, Integer> qualityDistribution = new HashMap<>();
qualityDistribution.put("高质量", 0);
qualityDistribution.put("中等质量", 0);
qualityDistribution.put("一般质量", 0);
qualityDistribution.put("低质量", 0);
for (CsdnInfo article : allArticles) {
int totalInteractions = article.getLikes() + article.getComments() + article.getFavorite();
String quality;
if (totalInteractions > 30000) {
quality = "高质量";
} else if (totalInteractions > 10000) {
quality = "中等质量";
} else if (totalInteractions > 1000) {
quality = "一般质量";
} else {
quality = "低质量";
}
qualityDistribution.put(quality, qualityDistribution.get(quality) + 1);
}
analysis.put("qualityDistribution", qualityDistribution);
analysis.put("totalArticles", allArticles.size());
// 计算质量比例
Map<String, Double> qualityPercentage = new HashMap<>();
for (Map.Entry<String, Integer> entry : qualityDistribution.entrySet()) {
double percentage = entry.getValue() * 100.0 / allArticles.size();
qualityPercentage.put(entry.getKey(), Math.round(percentage * 100.0) / 100.0);
}
analysis.put("qualityPercentage", qualityPercentage);
return analysis;
}
/**
*
*/
public Map<String, Object> getInteractionRatioAnalysis() {
Map<String, Object> overview = csdnMapper.getInteractionStats();
Long totalLikes = ((Number) overview.get("totalLikes")).longValue();
Long totalComments = ((Number) overview.get("totalComments")).longValue();
Long totalFavorite = ((Number) overview.get("totalFavorite")).longValue();
Long totalInteractions = totalLikes + totalComments + totalFavorite;
Map<String, Object> analysis = new HashMap<>();
analysis.put("totalInteractions", totalInteractions);
// 计算各类型互动的比例
Map<String, Double> ratios = new HashMap<>();
ratios.put("likesRatio", Math.round(totalLikes * 100.0 / totalInteractions * 100.0) / 100.0);
ratios.put("commentsRatio", Math.round(totalComments * 100.0 / totalInteractions * 100.0) / 100.0);
ratios.put("favoriteRatio", Math.round(totalFavorite * 100.0 / totalInteractions * 100.0) / 100.0);
analysis.put("ratios", ratios);
// 分析结论
List<String> insights = new ArrayList<>();
if (ratios.get("likesRatio") > 60) {
insights.add("点赞是最主要的互动方式");
}
if (ratios.get("commentsRatio") > 20) {
insights.add("评论互动活跃,用户参与度较高");
}
if (ratios.get("favoriteRatio") > 25) {
insights.add("收藏比例较高,内容实用性强");
}
analysis.put("insights", insights);
return analysis;
}
/**
*
*/
public List<Map<String, Object>> getTechFieldRecommendations() {
List<Map<String, Object>> competitiveAnalysis = getTechFieldCompetitiveAnalysis();
return competitiveAnalysis.stream()
.filter(field -> {
Double competitiveIndex = (Double) field.get("competitiveIndex");
return competitiveIndex > 5000; // 过滤掉竞争力指数过低的领域
})
.limit(10)
.map(field -> {
Map<String, Object> recommendation = new HashMap<>(field);
String heatLevel = (String) field.get("heatLevel");
// 生成推荐理由
String reason;
if ("极热".equals(heatLevel) || "很热".equals(heatLevel)) {
reason = "该领域热度极高,用户关注度大,适合创作热门内容";
} else if ("较热".equals(heatLevel)) {
reason = "该领域有一定热度,竞争适中,适合深入创作";
} else {
reason = "该领域竞争相对较小,有机会成为细分领域专家";
}
recommendation.put("recommendReason", reason);
return recommendation;
})
.collect(Collectors.toList());
}
/**
*
*/
public Map<String, Object> getComprehensiveAnalysisReport() {
Map<String, Object> report = new HashMap<>();
// 基础数据概览
report.put("overview", csdnMapper.getInteractionStats());
// 技术领域竞争力分析
report.put("competitiveAnalysis", getTechFieldCompetitiveAnalysis());
// 文章质量分析
report.put("qualityAnalysis", getArticleQualityAnalysis());
// 互动比例分析
report.put("interactionAnalysis", getInteractionRatioAnalysis());
// 技术领域推荐
report.put("recommendations", getTechFieldRecommendations());
// 点赞分布统计
report.put("likesDistribution", csdnMapper.getLikesDistribution());
return report;
}
}

@ -0,0 +1,192 @@
package com.example.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.entity.CsdnInfo;
import com.example.mapper.CsdnMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
/**
* CSDN
*/
@Service
public class CsdnService extends ServiceImpl<CsdnMapper, CsdnInfo> {
@Resource
private CsdnMapper csdnMapper;
/**
*
*/
public List<Map<String, Object>> getTechFieldDistribution() {
return csdnMapper.getTechFieldDistribution();
}
/**
*
*/
public Map<String, Object> getHotArticlesRanking(int limit) {
Map<String, Object> result = new HashMap<>();
result.put("byLikes", csdnMapper.getHotArticlesByLikes(limit));
result.put("byComments", csdnMapper.getHotArticlesByComments(limit));
result.put("byFavorite", csdnMapper.getHotArticlesByFavorite(limit));
return result;
}
/**
*
*/
public Map<String, Object> getInteractionOverview() {
Map<String, Object> stats = csdnMapper.getInteractionStats();
// 添加格式化的数据
Map<String, Object> result = new HashMap<>(stats);
// 计算互动总数
Long totalLikes = ((Number) stats.get("totalLikes")).longValue();
Long totalComments = ((Number) stats.get("totalComments")).longValue();
Long totalFavorite = ((Number) stats.get("totalFavorite")).longValue();
result.put("totalInteractions", totalLikes + totalComments + totalFavorite);
return result;
}
/**
*
*/
public List<Map<String, Object>> getTechFieldInteractionStats() {
List<Map<String, Object>> stats = csdnMapper.getTechFieldInteractionStats();
// 为每个领域计算总互动数
return stats.stream().map(stat -> {
Long totalLikes = ((Number) stat.get("totalLikes")).longValue();
Long totalComments = ((Number) stat.get("totalComments")).longValue();
Long totalFavorite = ((Number) stat.get("totalFavorite")).longValue();
stat.put("totalInteractions", totalLikes + totalComments + totalFavorite);
return stat;
}).collect(Collectors.toList());
}
/**
*
*/
public List<Map<String, Object>> getLikesDistribution() {
return csdnMapper.getLikesDistribution();
}
/**
*
*/
public Map<String, Object> getTechFieldDetail(String field, int limit) {
Map<String, Object> result = new HashMap<>();
// 获取该领域的文章列表
List<CsdnInfo> articles = csdnMapper.getArticlesByField(field);
if (limit > 0 && articles.size() > limit) {
articles = articles.subList(0, limit);
}
result.put("articles", articles);
// 计算该领域的统计数据
if (!articles.isEmpty()) {
int totalLikes = articles.stream().mapToInt(CsdnInfo::getLikes).sum();
int totalComments = articles.stream().mapToInt(CsdnInfo::getComments).sum();
int totalFavorite = articles.stream().mapToInt(CsdnInfo::getFavorite).sum();
result.put("fieldName", field);
result.put("articleCount", articles.size());
result.put("totalLikes", totalLikes);
result.put("totalComments", totalComments);
result.put("totalFavorite", totalFavorite);
result.put("avgLikes", articles.stream().mapToInt(CsdnInfo::getLikes).average().orElse(0));
result.put("avgComments", articles.stream().mapToInt(CsdnInfo::getComments).average().orElse(0));
result.put("avgFavorite", articles.stream().mapToInt(CsdnInfo::getFavorite).average().orElse(0));
}
return result;
}
/**
*
*/
public List<CsdnInfo> searchArticles(String keyword) {
if (keyword == null || keyword.trim().isEmpty()) {
return new ArrayList<>();
}
return csdnMapper.searchArticles(keyword.trim());
}
/**
*
*/
public Page<CsdnInfo> getArticlePage(int pageNum, int pageSize, String field, String keyword) {
Page<CsdnInfo> page = new Page<>(pageNum, pageSize);
QueryWrapper<CsdnInfo> queryWrapper = new QueryWrapper<>();
// 添加领域筛选
if (field != null && !field.trim().isEmpty()) {
queryWrapper.eq("title", field.trim());
}
// 添加关键词搜索
if (keyword != null && !keyword.trim().isEmpty()) {
queryWrapper.like("word", keyword.trim());
}
// 按点赞数降序排列
queryWrapper.orderByDesc("likes");
return this.page(page, queryWrapper);
}
/**
*
*/
public Map<String, Object> getDashboardData() {
Map<String, Object> dashboard = new HashMap<>();
// 基础统计数据
dashboard.put("overview", getInteractionOverview());
// 技术领域分布
dashboard.put("techFieldDistribution", getTechFieldDistribution());
// 各领域互动数据取前10
List<Map<String, Object>> fieldStats = getTechFieldInteractionStats();
if (fieldStats.size() > 10) {
fieldStats = fieldStats.subList(0, 10);
}
dashboard.put("topFieldStats", fieldStats);
// 点赞数分布
dashboard.put("likesDistribution", getLikesDistribution());
// 热门文章每类取前5
dashboard.put("hotArticles", getHotArticlesRanking(5));
return dashboard;
}
/**
*
*/
public List<String> getTechFieldList() {
List<Map<String, Object>> distribution = getTechFieldDistribution();
return distribution.stream()
.map(item -> (String) item.get("name"))
.collect(Collectors.toList());
}
/**
* ID
*/
public CsdnInfo getArticleDetail(Integer id) {
return this.getById(id);
}
}

@ -0,0 +1,32 @@
package com.example.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.dto.SingleAttributeItem;
import com.example.entity.CommentInfo;
import com.example.entity.LogInfo;
import com.example.mapper.CommentMapper;
import com.example.mapper.LogMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@Service
public class LogService extends ServiceImpl<LogMapper, LogInfo> {
@Resource
private LogMapper logMapper;
public List<LogInfo> selectLoginList(Integer userId) {
return logMapper.selectLoginList(userId);
}
public List<SingleAttributeItem> selectActiveTrend(Integer userId) {
return logMapper.selectActiveTrend(userId);
}
}

@ -0,0 +1,82 @@
package com.example.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.Result;
import com.example.entity.PermissionInfo;
import com.example.entity.RoleInfo;
import com.example.mapper.PermissionMapper;
import org.apache.catalina.util.ToStringUtil;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
@Service
public class PermissionService extends ServiceImpl<PermissionMapper, PermissionInfo> {
@Resource
private PermissionMapper permissionMapper;
@Resource
private RoleService roleService;
public List<PermissionInfo> selectlist() {
List<PermissionInfo> permissionInfos = list();
return selectlist(permissionInfos);
}
public List<PermissionInfo> selectlist(List<PermissionInfo> permissionInfos) {
return getPermissionTree(null, permissionInfos);
}
private List<PermissionInfo> getPermissionTree(Integer id, List<PermissionInfo> permissionInfos) {
List<PermissionInfo> list = new ArrayList<>();
for (PermissionInfo permissionInfo : permissionInfos) {
if(Objects.equals(permissionInfo.getPid(), id)){
// 创建 Meta 对象并设置
PermissionInfo.Meta meta = new PermissionInfo.Meta();
meta.setTitle(permissionInfo.getTitle());
meta.setIcon(permissionInfo.getIcon());
meta.setIsShow(permissionInfo.getIsShow());
meta.setDescr(permissionInfo.getDescr());
meta.setXName(permissionInfo.getXName());
meta.setYName(permissionInfo.getYName());
permissionInfo.setMeta(meta);
// 遍历获取树的子节点
List<PermissionInfo> permissionTree = getPermissionTree(permissionInfo.getId(), permissionInfos);
permissionInfo.setChildren(permissionTree);
list.add(permissionInfo);
}
}
return list.stream().sorted(Comparator.comparing(PermissionInfo::getOrders)).collect(Collectors.toList());
}
public List<PermissionInfo> menuTree(String flag){
QueryWrapper<RoleInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("flag",flag);
RoleInfo roleInfo = roleService.getOne(queryWrapper);
String permissionIds = roleInfo.getPermissionIds();
String[] ids = permissionIds.split(",");
List<PermissionInfo> all = new ArrayList<>();
List<PermissionInfo> PermissionInfos = this.list();
for (PermissionInfo info : PermissionInfos) {
for (String id : ids) {
if (info.getId().equals(Integer.valueOf(id))){
all.add(info);
}
}
}
return this.selectlist(all);
}
}

@ -0,0 +1,26 @@
package com.example.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.entity.PermissionInfo;
import com.example.entity.RoleInfo;
import com.example.mapper.PermissionMapper;
import com.example.mapper.RoleMapper;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Service
public class RoleService extends ServiceImpl<RoleMapper, RoleInfo> {
@Resource
private RoleMapper roleMapper;
@Resource
private PermissionService permissionService;
}

@ -0,0 +1,204 @@
package com.example.service;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.common.enums.ResultCodeEnum;
import com.example.entity.UserInfo;
import com.example.exception.CustomException;
import com.example.mapper.SystemMapper;
import com.example.mapper.UserMapper;
import com.example.utils.AddressUtils;
import com.example.utils.TokenUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.HashMap;
@Service
public class UserService extends ServiceImpl<UserMapper, UserInfo> {
@Resource
private UserMapper userMapper;
/**
*
*/
public String login(UserInfo userInfo) {
UserInfo dbUserInfo = getUserInfoByName(userInfo.getUsername());
String address = AddressUtils.getAddress();
if (ObjectUtil.isNull(dbUserInfo)) {
throw new CustomException(ResultCodeEnum.USER_NOT_EXIST_ERROR);
}
if (!userInfo.getPassword().equals(dbUserInfo.getPassword())) {
throw new CustomException(ResultCodeEnum.USER_ACCOUNT_ERROR);
}
// 生成token
String tokenData = dbUserInfo.getId()+"";
return TokenUtils.createToken(tokenData, address);
}
/**
*
*/
public void register(UserInfo userInfo) {
UserInfo info = userMapper.selectByUsername(userInfo.getUsername());
if(ObjectUtil.isNotNull(info)){
throw new CustomException(ResultCodeEnum.USER_EXIST_ERROR);
}
if("admin".equals(userInfo.getUsername())){
userInfo.setRole("ADMIN");
}else{
userInfo.setRole("USER");
}
userInfo.setAvatar("https://lyr-oss.oss-cn-beijing.aliyuncs.com/avatars/moren.png");
userInfo.setNickname(userInfo.getUsername());
userMapper.insert(userInfo);
}
/**
*
*/
public void updatePassword(UserInfo userInfo) {
UserInfo dbUserInfo = getUserInfoByName(userInfo.getUsername());
if (ObjectUtil.isNull(dbUserInfo)) {
throw new CustomException(ResultCodeEnum.USER_NOT_EXIST_ERROR);
}
if (!userInfo.getPassword().equals(dbUserInfo.getPassword())) {
throw new CustomException(ResultCodeEnum.PARAM_PASSWORD_ERROR);
}
dbUserInfo.setPassword(userInfo.getNewPassword());
userMapper.updateById(dbUserInfo);
}
public UserInfo selectById(Integer id){
return userMapper.selectById(id);
}
public UserInfo getUserInfoByName(String username){
QueryWrapper<UserInfo> infoQueryWrapper = new QueryWrapper<>();
infoQueryWrapper.eq("username",username);
return this.getOne(infoQueryWrapper);
}
public void saveItem(UserInfo user) {
UserInfo dbUserInfo = getUserInfoByName(user.getUsername());
// 存在相同的用户
if(dbUserInfo != null){
throw new CustomException(ResultCodeEnum.USER_EXIST_ERROR);
}
// 设置默认昵称
if(null == user.getNickname()){
user.setNickname(user.getUsername());
}
// 设置默认密码
if(null == user.getPassword()){
user.setPassword("123456");
}
// 设置默认头像
if(null == user.getAvatar() || StrUtil.isEmpty(user.getAvatar())){
user.setAvatar("https://wpimg.wallstcn.com/f778738c-e4f8-4870-b634-56703b4acafe.gif");
}
// 设置默认角色
if(null == user.getRole()){
user.setRole("USER");
}
userMapper.insert(user);
}
public String getLocalIp(){
String ip = "";
try {
ip= HttpUtil.get("http://checkip.amazonaws.com").trim();
}catch (Exception ex){
System.err.println("ip获取失败。。。。。。。。。。。。。。。。");;
}
return ip;
}
static String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36";
public String getProvinceByIp(String ip){
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("ip", ip);
paramMap.put("json", "true");
String response = "";
try {
response = HttpRequest.get("http://whois.pconline.com.cn/ipJson.jsp")
.header(Header.USER_AGENT, USER_AGENT)
.form(paramMap)//表单内容
.timeout(3000)//超时,毫秒
.execute().body().trim();
}catch (Exception ex){
System.err.println("ip解析失败。。。。。。。。。。。。。。。。");;
}
return response;
}
public String getCodeByCity(String city){
return userMapper.selectCodeByCity(city);
}
public String getWeatherByCode(String code){
String response = "";
try {
response = HttpUtil.get("http://t.weather.itboy.net/api/weather/city/"+code)
.trim();
}catch (Exception ex){
System.err.println("天气获取失败。。。。。。。。。。。。。。。。");;
}
if(StrUtil.isNotEmpty(response)){
JSONObject jsonObject = JSONUtil.parseObj(response);
return jsonObject.getJSONObject("data").getJSONArray("forecast").getStr(0);
}else{
return response;
}
}
public UserInfo getUserInfo() {
UserInfo userInfo = TokenUtils.getCurrentUser();
String ip;
String address = "{}";
String weather = "{}";
/**
* ip1-2
*/
try {
ip = getLocalIp();
if(StrUtil.isNotEmpty(ip)){
address = getProvinceByIp(ip);
if(StrUtil.isNotEmpty(address)){
JSONObject jsonObject = JSONUtil.parseObj(address);
String city = jsonObject.getStr("city").replace("市", "");
if(StrUtil.isNotEmpty(city)){
String code = getCodeByCity(city);
weather = getWeatherByCode(code);
}
}
}
} catch (Exception ex){
log.error("获取位置或者天气失败");
}
userInfo.setAddress(address);
userInfo.setWeather(weather);
return userInfo;
}
}

@ -0,0 +1,27 @@
package com.example.utils;
import java.net.InetAddress;
import java.net.NetworkInterface;
public class AddressUtils {
public static String getAddress(){
String address = "258";
try {
InetAddress localHost = InetAddress.getLocalHost();
NetworkInterface networkInterface = NetworkInterface.getByInetAddress(localHost);
byte[] macAddressBytes = networkInterface.getHardwareAddress();
StringBuilder macAddress = new StringBuilder();
for (int i = 0; i < macAddressBytes.length; i++) {
macAddress.append(String.format("%02X", macAddressBytes[i]));
if (i < macAddressBytes.length - 1) {
macAddress.append("");
}
}
address = macAddress.toString();
} catch (Exception ex){
}
return address;
}
}

@ -0,0 +1,68 @@
package com.example.utils;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.example.common.Constants;
import com.example.entity.UserInfo;
import com.example.mapper.SystemMapper;
import com.example.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
/**
* Token
*/
@Component
public class TokenUtils {
private static final Logger log = LoggerFactory.getLogger(TokenUtils.class);
private static UserService staticUserService;
@Resource
UserService userService;
@PostConstruct
public void setUserService() {
staticUserService = userService;
}
/**
* token
*/
public static String createToken(String data, String sign) {
return JWT.create().withAudience(data)
.withExpiresAt(DateUtil.offsetHour(new Date(), 2))
.sign(Algorithm.HMAC256(sign));
}
/**
*
*/
public static UserInfo getCurrentUser() {
try {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String token = request.getHeader(Constants.TOKEN);
if (ObjectUtil.isNotEmpty(token)) {
String userId = JWT.decode(token).getAudience().get(0);
return staticUserService.selectById(Integer.valueOf(userId));
}
} catch (Exception e) {
log.error("获取当前用户信息出错", e);
}
return new UserInfo(); // 返回空的账号对象
}
}

@ -0,0 +1,29 @@
server:
port: 19090
# 数据库配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: wy131499
url: jdbc:mysql://localhost:3306/csdn?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2b8&allowPublicKeyRetrieval=true
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
# 配置mybatis实体和xml映射
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.example.entity
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath:mapper/*.xml
ip: localhost

@ -0,0 +1,52 @@
-- CSDN文章数据表初始数据
-- 清空表数据
DELETE FROM t_csdn_data;
-- 重置自增ID
ALTER TABLE t_csdn_data AUTO_INCREMENT = 1;
-- 插入示例文章数据
INSERT INTO t_csdn_data (id, title, content, author, publish_time, read_count, like_count, comment_count, category, tags, url, create_time, update_time) VALUES
(1, 'Spring Boot 3.0 新特性详解', 'Spring Boot 3.0 是一个重要的里程碑版本,本文将详细介绍其新特性...', '张三', '2024-01-15 10:30:00', 1580, 89, 23, 'Java后端', 'Spring Boot,Java,微服务', 'https://blog.csdn.net/zhangsan/article/details/123456', NOW(), NOW()),
(2, 'Vue 3 Composition API 最佳实践', '随着Vue 3的普及Composition API成为了开发者的新宠本文总结了最佳实践...', '李四', '2024-01-16 14:20:00', 2340, 156, 45, 'Web前端', 'Vue.js,JavaScript,前端开发', 'https://blog.csdn.net/lisi/article/details/123457', NOW(), NOW()),
(3, 'MySQL 8.0 性能优化全攻略', '数据库性能优化是后端开发的重要技能,本文从索引、查询优化等方面详细讲解...', '王五', '2024-01-17 09:15:00', 3200, 201, 67, '数据库', 'MySQL,数据库优化,SQL', 'https://blog.csdn.net/wangwu/article/details/123458', NOW(), NOW()),
(4, 'Docker 容器化部署实战指南', 'Docker已经成为现代应用部署的标准工具本文将通过实际案例讲解容器化部署...', '赵六', '2024-01-18 16:45:00', 1890, 134, 38, '运维部署', 'Docker,容器化,DevOps', 'https://blog.csdn.net/zhaoliu/article/details/123459', NOW(), NOW()),
(5, 'Redis 缓存架构设计与实现', '缓存是提升系统性能的重要手段本文详细介绍Redis在高并发场景下的应用...', '钱七', '2024-01-19 11:30:00', 2780, 189, 52, '数据库', 'Redis,缓存,高并发', 'https://blog.csdn.net/qianqi/article/details/123460', NOW(), NOW()),
(6, 'React Hooks 深入理解与应用', 'React Hooks彻底改变了React的开发方式本文深入分析其原理和应用场景...', '孙八', '2024-01-20 13:20:00', 2150, 167, 41, 'Web前端', 'React,Hooks,JavaScript', 'https://blog.csdn.net/sunba/article/details/123461', NOW(), NOW()),
(7, 'Kubernetes 集群搭建与管理', 'K8s是容器编排的事实标准本文从零开始搭建生产级Kubernetes集群...', '周九', '2024-01-21 15:10:00', 3450, 234, 78, '运维部署', 'Kubernetes,容器编排,云原生', 'https://blog.csdn.net/zhoujiu/article/details/123462', NOW(), NOW()),
(8, 'Python 数据分析实战项目', '使用Python进行数据分析是数据科学的基础本文通过实际项目展示分析流程...', '吴十', '2024-01-22 10:45:00', 1960, 142, 35, '数据分析', 'Python,数据分析,Pandas', 'https://blog.csdn.net/wushi/article/details/123463', NOW(), NOW()),
(9, 'Go 语言微服务架构实践', 'Go语言在微服务开发中表现出色本文分享微服务架构的设计和实现经验...', '郑十一', '2024-01-23 14:30:00', 2890, 198, 63, 'Go语言', 'Go,微服务,分布式', 'https://blog.csdn.net/zhengshiyi/article/details/123464', NOW(), NOW()),
(10, 'TypeScript 进阶开发技巧', 'TypeScript为JavaScript带来了类型安全本文介绍高级开发技巧和最佳实践...', '王十二', '2024-01-24 09:25:00', 2340, 176, 49, 'Web前端', 'TypeScript,JavaScript,前端开发', 'https://blog.csdn.net/wangshier/article/details/123465', NOW(), NOW()),
(11, 'ElasticSearch 搜索引擎优化', '全文搜索是现代应用的核心功能本文详细讲解ES的优化策略和实践经验...', '李十三', '2024-01-25 16:15:00', 1750, 128, 32, '搜索引擎', 'ElasticSearch,搜索优化,大数据', 'https://blog.csdn.net/lishisan/article/details/123466', NOW(), NOW()),
(12, 'Apache Kafka 消息队列实战', '消息队列是分布式系统的重要组件本文通过实际案例展示Kafka的应用...', '张十四', '2024-01-26 11:50:00', 2670, 187, 56, '消息队列', 'Kafka,消息队列,分布式', 'https://blog.csdn.net/zhangshisi/article/details/123467', NOW(), NOW()),
(13, 'Flutter 跨平台开发指南', 'Flutter为移动开发带来了新的可能本文从入门到实战全面介绍Flutter开发...', '陈十五', '2024-01-27 13:40:00', 2120, 159, 43, '移动开发', 'Flutter,Dart,跨平台开发', 'https://blog.csdn.net/chenshiwu/article/details/123468', NOW(), NOW()),
(14, 'Nginx 高性能Web服务器配置', 'Nginx是高性能的Web服务器和反向代理本文详细介绍其配置和优化技巧...', '刘十六', '2024-01-28 10:20:00', 1840, 135, 29, '运维部署', 'Nginx,Web服务器,负载均衡', 'https://blog.csdn.net/liushiliu/article/details/123469', NOW(), NOW()),
(15, '机器学习算法原理与实现', '机器学习是AI的核心技术本文从数学原理到代码实现全面讲解经典算法...', '杨十七', '2024-01-29 15:30:00', 3890, 267, 89, '人工智能', '机器学习,算法,Python', 'https://blog.csdn.net/yangshiqi/article/details/123470', NOW(), NOW()),
(16, 'GraphQL API 设计与开发', 'GraphQL为API开发带来了新的思路本文详细介绍其设计理念和实践应用...', '黄十八', '2024-01-30 12:10:00', 1560, 112, 27, 'Web前端', 'GraphQL,API设计,前端开发', 'https://blog.csdn.net/huangshiba/article/details/123471', NOW(), NOW()),
(17, 'MongoDB 文档数据库实战', 'NoSQL数据库在现代应用中越来越重要本文通过实例展示MongoDB的应用...', '林十九', '2024-01-31 14:50:00', 2450, 174, 51, '数据库', 'MongoDB,NoSQL,文档数据库', 'https://blog.csdn.net/linshijiu/article/details/123472', NOW(), NOW()),
(18, 'Jenkins CI/CD 自动化部署', '持续集成和持续部署是现代软件开发的标准流程本文详细介绍Jenkins的配置...', '何二十', '2024-02-01 09:35:00', 2180, 163, 44, '运维部署', 'Jenkins,CI/CD,自动化部署', 'https://blog.csdn.net/heershi/article/details/123473', NOW(), NOW()),
(19, 'Rust 系统编程入门指南', 'Rust是一门注重安全和性能的系统编程语言本文从基础语法到实际应用全面介绍...', '罗二十一', '2024-02-02 16:25:00', 1690, 124, 33, '系统编程', 'Rust,系统编程,内存安全', 'https://blog.csdn.net/luoershiyi/article/details/123474', NOW(), NOW()),
(20, '区块链技术原理与应用', '区块链技术正在改变各个行业,本文深入浅出地介绍区块链的核心概念和应用场景...', '宋二十二', '2024-02-03 11:15:00', 4200, 298, 95, '区块链', '区块链,比特币,智能合约', 'https://blog.csdn.net/songershier/article/details/123475', NOW(), NOW());
-- 提交数据
COMMIT;

@ -0,0 +1,18 @@
-- 添加我创建的前端路由对应的权限数据
-- 注意:此脚本是在现有权限数据基础上添加新的权限,不会删除现有数据
-- 插入CSDN数据分析顶级菜单
INSERT INTO t_permission_info (title, name, path, orders, icon, pid, x_name, y_name, create_time, update_time, is_show, descr) VALUES
('CSDN数据分析', 'csdn', '/csdn', 18, 'data', NULL, NULL, NULL, NOW(), NOW(), 1, '管理员可以进行编辑CSDN数据分析权限修改后需要登出才会生效');
-- 获取刚插入的CSDN数据分析菜单ID
SET @csdn_menu_id = LAST_INSERT_ID();
-- 插入CSDN数据分析子菜单
INSERT INTO t_permission_info (title, name, path, orders, icon, pid, x_name, y_name, create_time, update_time, is_show, descr) VALUES
('数据仪表盘', 'csdnDashboard', '/csdn/dashboard', 19, 'analyze', @csdn_menu_id, '时间', '数据量', NOW(), NOW(), 1, '管理员可以进行编辑数据仪表盘,权限修改后需要登出才会生效'),
('深度分析', 'csdnAnalysis', '/csdn/analysis', 20, 'bar', @csdn_menu_id, '技术领域', '文章数量', NOW(), NOW(), 1, '管理员可以进行编辑深度分析,权限修改后需要登出才会生效'),
('文章管理', 'csdnArticles', '/csdn/articles', 21, 'info', @csdn_menu_id, '时间', '文章数', NOW(), NOW(), 1, '管理员可以进行编辑文章管理,权限修改后需要登出才会生效');
-- 提交数据
COMMIT;

@ -0,0 +1,29 @@
server:
port: 19090
# 数据库配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: wy131499
url: jdbc:mysql://localhost:3306/csdn?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&serverTimezone=GMT%2b8&allowPublicKeyRetrieval=true
servlet:
multipart:
max-file-size: 100MB
max-request-size: 100MB
# 配置mybatis实体和xml映射
mybatis:
mapper-locations: classpath:mapper/*.xml
type-aliases-package: com.example.entity
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath:mapper/*.xml
ip: localhost

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save