From cb2d2b5bf287f1729a951418f5fd3c3cd1ac3ef7 Mon Sep 17 00:00:00 2001 From: zhouyl <583641232@qq.com> Date: Wed, 28 Aug 2024 15:21:48 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20=20=20=20CPU=E6=80=A7=E8=83=BD?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 5 + .../system/ToolManageController.java | 3 - .../src/main/resources/application-dev.yml | 6 +- tp-admin/src/main/resources/application.yml | 39 ++-- .../config/ApiDecryptAutoConfiguration.java | 34 ++++ .../properties/ApiDecryptProperties.java | 36 ++++ .../framework/encrypt/ApiEncrypt.java | 20 +++ .../framework/filter/CryptoFilter.java | 112 ++++++++++++ .../filter/DecryptRequestBodyWrapper.java | 95 ++++++++++ .../filter/EncryptResponseBodyWrapper.java | 125 +++++++++++++ tp-functional/pom.xml | 5 + .../controller/CpuInfoController.java | 169 ++++++++++++++++++ .../functional/domain/CpuInfo.java | 72 ++++++++ .../functional/mapper/CpuInfoMapper.java | 18 ++ .../functional/service/CpuInfoService.java | 16 ++ .../service/impl/CpuInfoServiceImpl.java | 21 +++ .../service/impl/ToolManageServiceImpl.java | 1 + 17 files changed, 758 insertions(+), 19 deletions(-) create mode 100644 tp-framework/src/main/java/com/inscloudtech/framework/config/ApiDecryptAutoConfiguration.java create mode 100644 tp-framework/src/main/java/com/inscloudtech/framework/config/properties/ApiDecryptProperties.java create mode 100644 tp-framework/src/main/java/com/inscloudtech/framework/encrypt/ApiEncrypt.java create mode 100644 tp-framework/src/main/java/com/inscloudtech/framework/filter/CryptoFilter.java create mode 100644 tp-framework/src/main/java/com/inscloudtech/framework/filter/DecryptRequestBodyWrapper.java create mode 100644 tp-framework/src/main/java/com/inscloudtech/framework/filter/EncryptResponseBodyWrapper.java create mode 100644 tp-functional/src/main/java/com/inscloudtech/functional/controller/CpuInfoController.java create mode 100644 tp-functional/src/main/java/com/inscloudtech/functional/domain/CpuInfo.java create mode 100644 tp-functional/src/main/java/com/inscloudtech/functional/mapper/CpuInfoMapper.java create mode 100644 tp-functional/src/main/java/com/inscloudtech/functional/service/CpuInfoService.java create mode 100644 tp-functional/src/main/java/com/inscloudtech/functional/service/impl/CpuInfoServiceImpl.java diff --git a/pom.xml b/pom.xml index 846d37c..6d72f77 100644 --- a/pom.xml +++ b/pom.xml @@ -306,6 +306,11 @@ + + org.jsoup + jsoup + 1.15.3 + com.inscloudtech tp-functional diff --git a/tp-admin/src/main/java/com/inscloudtech/web/controller/system/ToolManageController.java b/tp-admin/src/main/java/com/inscloudtech/web/controller/system/ToolManageController.java index fd057c5..ff40b8d 100644 --- a/tp-admin/src/main/java/com/inscloudtech/web/controller/system/ToolManageController.java +++ b/tp-admin/src/main/java/com/inscloudtech/web/controller/system/ToolManageController.java @@ -2,7 +2,6 @@ package com.inscloudtech.web.controller.system; import cn.dev33.satoken.annotation.SaCheckPermission; -import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.inscloudtech.common.annotation.Log; import com.inscloudtech.common.annotation.RepeatSubmit; @@ -11,7 +10,6 @@ import com.inscloudtech.common.core.domain.PageQuery; import com.inscloudtech.common.core.domain.R; import com.inscloudtech.common.core.page.TableDataInfo; import com.inscloudtech.common.core.validate.AddGroup; -import com.inscloudtech.common.core.validate.EditGroup; import com.inscloudtech.common.enums.BusinessType; import com.inscloudtech.common.utils.poi.ExcelUtil; import com.inscloudtech.system.domain.ToolManage; @@ -30,7 +28,6 @@ import javax.validation.constraints.NotNull; import java.io.IOException; import java.util.Arrays; import java.util.List; -import java.util.Map; /** * 测试包管理 diff --git a/tp-admin/src/main/resources/application-dev.yml b/tp-admin/src/main/resources/application-dev.yml index d29661c..9af80c3 100644 --- a/tp-admin/src/main/resources/application-dev.yml +++ b/tp-admin/src/main/resources/application-dev.yml @@ -5,7 +5,7 @@ spring: # 动态数据源文档 https://www.kancloud.cn/tracy5546/dynamic-datasource/content dynamic: # 性能分析插件(有性能损耗 不建议生产环境使用) - p6spy: true + p6spy: false # 设置默认的数据源或者数据源组,默认值即为 master primary: master # 严格模式 匹配不到数据源则报错 @@ -17,7 +17,7 @@ spring: driverClassName: com.mysql.cj.jdbc.Driver # jdbc 所有参数配置参考 https://lionli.blog.csdn.net/article/details/122018562 # rewriteBatchedStatements=true 批处理优化 大幅提升批量插入更新删除性能(对数据库有性能损耗 使用批量操作应考虑性能问题) - url: jdbc:mysql://192.168.3.20:3306/test_platform?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true + url: jdbc:mysql://ly:3306/test_platform?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true username: root password: 123456 # 从库数据源 @@ -41,7 +41,7 @@ spring: spring: redis: # 地址 - host: localhost + host: ly # 端口,默认为6379 port: 6379 # 数据库索引 diff --git a/tp-admin/src/main/resources/application.yml b/tp-admin/src/main/resources/application.yml index b2472cf..02a3d8b 100644 --- a/tp-admin/src/main/resources/application.yml +++ b/tp-admin/src/main/resources/application.yml @@ -135,9 +135,7 @@ security: # swagger 文档配置 - /*/api-docs - /*/api-docs/** - # actuator 监控配置 - - /actuator - - /actuator/** + # MyBatisPlus配置 # https://baomidou.com/config/ @@ -253,13 +251,28 @@ lock4j: expire: 30000 --- # Actuator 监控端点的配置项 -management: - endpoints: - web: - exposure: - include: '*' - endpoint: - health: - show-details: ALWAYS - logfile: - external-file: ./logs/sys-console.log +#management: +# endpoints: +# port: -1 # 修改端口,跳过安全漏洞扫描 +# web: +# exposure: +# include: '*' +# endpoint: +# enabled-by-default: false #关闭监控 +# health: +# show-details: ALWAYS +# logfile: +# external-file: ./logs/sys-console.log + +# api接口加密 +api-decrypt: + # 是否开启全局接口加密 + enabled: true + # AES 加密头标识 + headerFlag: encrypt-key + # 响应加密公钥 非对称算法的公私钥 如:SM2,RSA 使用者请自行更换 + # 对应前端解密私钥 MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAmc3CuPiGL/LcIIm7zryCEIbl1SPzBkr75E2VMtxegyZ1lYRD+7TZGAPkvIsBcaMs6Nsy0L78n2qh+lIZMpLH8wIDAQABAkEAk82Mhz0tlv6IVCyIcw/s3f0E+WLmtPFyR9/WtV3Y5aaejUkU60JpX4m5xNR2VaqOLTZAYjW8Wy0aXr3zYIhhQQIhAMfqR9oFdYw1J9SsNc+CrhugAvKTi0+BF6VoL6psWhvbAiEAxPPNTmrkmrXwdm/pQQu3UOQmc2vCZ5tiKpW10CgJi8kCIFGkL6utxw93Ncj4exE/gPLvKcT+1Emnoox+O9kRXss5AiAMtYLJDaLEzPrAWcZeeSgSIzbL+ecokmFKSDDcRske6QIgSMkHedwND1olF8vlKsJUGK3BcdtM8w4Xq7BpSBwsloE= + publicKey: MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJnNwrj4hi/y3CCJu868ghCG5dUj8wZK++RNlTLcXoMmdZWEQ/u02RgD5LyLAXGjLOjbMtC+/J9qofpSGTKSx/MCAwEAAQ== + # 请求解密私钥 非对称算法的公私钥 如:SM2,RSA 使用者请自行更换 + # 对应前端加密公钥 MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAKoR8mX0rGKLqzcWmOzbfj64K8ZIgOdHnzkXSOVOZbFu/TJhZ7rFAN+eaGkl3C4buccQd/EjEsj9ir7ijT7h96MCAwEAAQ== + privateKey: MIIBVAIBADANBgkqhkiG9w0BAQEFAASCAT4wggE6AgEAAkEAqhHyZfSsYourNxaY7Nt+PrgrxkiA50efORdI5U5lsW79MmFnusUA355oaSXcLhu5xxB38SMSyP2KvuKNPuH3owIDAQABAkAfoiLyL+Z4lf4Myxk6xUDgLaWGximj20CUf+5BKKnlrK+Ed8gAkM0HqoTt2UZwA5E2MzS4EI2gjfQhz5X28uqxAiEA3wNFxfrCZlSZHb0gn2zDpWowcSxQAgiCstxGUoOqlW8CIQDDOerGKH5OmCJ4Z21v+F25WaHYPxCFMvwxpcw99EcvDQIgIdhDTIqD2jfYjPTY8Jj3EDGPbH2HHuffvflECt3Ek60CIQCFRlCkHpi7hthhYhovyloRYsM+IS9h/0BzlEAuO0ktMQIgSPT3aFAgJYwKpqRYKlLDVcflZFCKY7u3UP8iWi1Qw0Y= diff --git a/tp-framework/src/main/java/com/inscloudtech/framework/config/ApiDecryptAutoConfiguration.java b/tp-framework/src/main/java/com/inscloudtech/framework/config/ApiDecryptAutoConfiguration.java new file mode 100644 index 0000000..749ce28 --- /dev/null +++ b/tp-framework/src/main/java/com/inscloudtech/framework/config/ApiDecryptAutoConfiguration.java @@ -0,0 +1,34 @@ +package com.inscloudtech.framework.config; + +import com.inscloudtech.framework.config.properties.ApiDecryptProperties; +import com.inscloudtech.framework.filter.CryptoFilter; +import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; +import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; + +import javax.servlet.DispatcherType; + + +/** + * api 解密自动配置 + * + * @author wdhcr + */ +@AutoConfiguration +@EnableConfigurationProperties(ApiDecryptProperties.class) +@ConditionalOnProperty(value = "api-decrypt.enabled", havingValue = "true") +public class ApiDecryptAutoConfiguration { + + @Bean + public FilterRegistrationBean cryptoFilterRegistration(ApiDecryptProperties properties) { + FilterRegistrationBean registration = new FilterRegistrationBean<>(); + registration.setDispatcherTypes(DispatcherType.REQUEST); + registration.setFilter(new CryptoFilter(properties)); + registration.addUrlPatterns("/*"); + registration.setName("cryptoFilter"); + registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE); + return registration; + } +} diff --git a/tp-framework/src/main/java/com/inscloudtech/framework/config/properties/ApiDecryptProperties.java b/tp-framework/src/main/java/com/inscloudtech/framework/config/properties/ApiDecryptProperties.java new file mode 100644 index 0000000..3c52b9f --- /dev/null +++ b/tp-framework/src/main/java/com/inscloudtech/framework/config/properties/ApiDecryptProperties.java @@ -0,0 +1,36 @@ +package com.inscloudtech.framework.config.properties; + +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.stereotype.Component; + +/** + * api解密属性配置类 + * @author wdhcr + */ +@Data +@Component +@ConfigurationProperties(prefix = "api-decrypt") +public class ApiDecryptProperties { + + /** + * 加密开关 + */ + private Boolean enabled; + + /** + * 头部标识 + */ + private String headerFlag; + + /** + * 响应加密公钥 + */ + private String publicKey; + + /** + * 请求解密私钥 + */ + private String privateKey; + +} diff --git a/tp-framework/src/main/java/com/inscloudtech/framework/encrypt/ApiEncrypt.java b/tp-framework/src/main/java/com/inscloudtech/framework/encrypt/ApiEncrypt.java new file mode 100644 index 0000000..11ec157 --- /dev/null +++ b/tp-framework/src/main/java/com/inscloudtech/framework/encrypt/ApiEncrypt.java @@ -0,0 +1,20 @@ +package com.inscloudtech.framework.encrypt; + +import java.lang.annotation.*; + +/** + * 强制加密注解 + * + * @author Michelle.Chung + */ +@Documented +@Target({ElementType.METHOD}) +@Retention(RetentionPolicy.RUNTIME) +public @interface ApiEncrypt { + + /** + * 响应加密忽略,默认不加密,为 true 时加密 + */ + boolean response() default false; + +} diff --git a/tp-framework/src/main/java/com/inscloudtech/framework/filter/CryptoFilter.java b/tp-framework/src/main/java/com/inscloudtech/framework/filter/CryptoFilter.java new file mode 100644 index 0000000..16a41c9 --- /dev/null +++ b/tp-framework/src/main/java/com/inscloudtech/framework/filter/CryptoFilter.java @@ -0,0 +1,112 @@ +package com.inscloudtech.framework.filter; + +import cn.hutool.core.util.ObjectUtil; + +import com.inscloudtech.common.exception.ServiceException; +import com.inscloudtech.common.utils.StringUtils; +import com.inscloudtech.common.utils.spring.SpringUtils; +import com.inscloudtech.framework.config.properties.ApiDecryptProperties; +import com.inscloudtech.framework.encrypt.ApiEncrypt; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerExceptionResolver; +import org.springframework.web.servlet.HandlerExecutionChain; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; + +import javax.servlet.*; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + + +/** + * Crypto 过滤器 + * + * @author wdhcr + */ +public class CryptoFilter implements Filter { + private final ApiDecryptProperties properties; + + public CryptoFilter(ApiDecryptProperties properties) { + this.properties = properties; + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + HttpServletRequest servletRequest = (HttpServletRequest) request; + HttpServletResponse servletResponse = (HttpServletResponse) response; + // 获取加密注解 + ApiEncrypt apiEncrypt = this.getApiEncryptAnnotation(servletRequest); + boolean responseFlag = apiEncrypt != null && apiEncrypt.response(); + ServletRequest requestWrapper = null; + ServletResponse responseWrapper = null; + EncryptResponseBodyWrapper responseBodyWrapper = null; + + // 是否为 put 或者 post 请求 + if (HttpMethod.PUT.matches(servletRequest.getMethod()) || HttpMethod.POST.matches(servletRequest.getMethod())) { + // 是否存在加密标头 + String headerValue = servletRequest.getHeader(properties.getHeaderFlag()); + if (StringUtils.isNotBlank(headerValue)) { + // 请求解密 + requestWrapper = new DecryptRequestBodyWrapper(servletRequest, properties.getPrivateKey(), properties.getHeaderFlag()); + } else { + // 是否有注解,有就报错,没有放行 + if (ObjectUtil.isNotNull(apiEncrypt)) { + HandlerExceptionResolver exceptionResolver = SpringUtils.getBean("handlerExceptionResolver", HandlerExceptionResolver.class); + exceptionResolver.resolveException( + servletRequest, servletResponse, null, + new ServiceException("没有访问权限,请联系管理员授权", HttpStatus.FORBIDDEN.value())); + return; + } + } + } + + // 判断是否响应加密 + if (responseFlag) { + responseBodyWrapper = new EncryptResponseBodyWrapper(servletResponse); + responseWrapper = responseBodyWrapper; + } + + chain.doFilter( + ObjectUtil.defaultIfNull(requestWrapper, request), + ObjectUtil.defaultIfNull(responseWrapper, response)); + + if (responseFlag) { + servletResponse.reset(); + // 对原始内容加密 + String encryptContent = responseBodyWrapper.getEncryptContent( + servletResponse, properties.getPublicKey(), properties.getHeaderFlag()); + // 对加密后的内容写出 + servletResponse.getWriter().write(encryptContent); + } + } + + /** + * 获取 ApiEncrypt 注解 + */ + private ApiEncrypt getApiEncryptAnnotation(HttpServletRequest servletRequest) { + RequestMappingHandlerMapping handlerMapping = SpringUtils.getBean("requestMappingHandlerMapping", RequestMappingHandlerMapping.class); + // 获取注解 + try { + HandlerExecutionChain mappingHandler = handlerMapping.getHandler(servletRequest); + if (ObjectUtil.isNotNull(mappingHandler)) { + Object handler = mappingHandler.getHandler(); + if (ObjectUtil.isNotNull(handler)) { + // 从handler获取注解 + if (handler instanceof HandlerMethod) { + HandlerMethod handlerMethod = (HandlerMethod)handler; + return handlerMethod.getMethodAnnotation(ApiEncrypt.class); + } + } + } + } catch (Exception e) { + throw new RuntimeException(e); + } + return null; + } + + @Override + public void destroy() { + } +} diff --git a/tp-framework/src/main/java/com/inscloudtech/framework/filter/DecryptRequestBodyWrapper.java b/tp-framework/src/main/java/com/inscloudtech/framework/filter/DecryptRequestBodyWrapper.java new file mode 100644 index 0000000..d74800b --- /dev/null +++ b/tp-framework/src/main/java/com/inscloudtech/framework/filter/DecryptRequestBodyWrapper.java @@ -0,0 +1,95 @@ +package com.inscloudtech.framework.filter; + +import cn.hutool.core.io.IoUtil; + +import com.inscloudtech.common.constant.Constants; +import com.inscloudtech.common.utils.EncryptUtils; +import org.springframework.http.MediaType; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.nio.charset.StandardCharsets; + +/** + * 解密请求参数工具类 + * + * @author wdhcr + */ +public class DecryptRequestBodyWrapper extends HttpServletRequestWrapper { + + private final byte[] body; + + public DecryptRequestBodyWrapper(HttpServletRequest request, String privateKey, String headerFlag) throws IOException { + super(request); + // 获取 AES 密码 采用 RSA 加密 + String headerRsa = request.getHeader(headerFlag); + String decryptAes = EncryptUtils.decryptByRsa(headerRsa, privateKey); + // 解密 AES 密码 + String aesPassword = EncryptUtils.decryptByBase64(decryptAes); + request.setCharacterEncoding(Constants.UTF8); + byte[] readBytes = IoUtil.readBytes(request.getInputStream(), false); + String requestBody = new String(readBytes, StandardCharsets.UTF_8); + // 解密 body 采用 AES 加密 + String decryptBody = EncryptUtils.decryptByAes(requestBody, aesPassword); + body = decryptBody.getBytes(StandardCharsets.UTF_8); + } + + @Override + public BufferedReader getReader() { + return new BufferedReader(new InputStreamReader(getInputStream())); + } + + + @Override + public int getContentLength() { + return body.length; + } + + @Override + public long getContentLengthLong() { + return body.length; + } + + @Override + public String getContentType() { + return MediaType.APPLICATION_JSON_VALUE; + } + + + @Override + public ServletInputStream getInputStream() { + final ByteArrayInputStream bais = new ByteArrayInputStream(body); + return new ServletInputStream() { + @Override + public int read() { + return bais.read(); + } + + @Override + public int available() { + return body.length; + } + + @Override + public boolean isFinished() { + return false; + } + + @Override + public boolean isReady() { + return false; + } + + @Override + public void setReadListener(ReadListener readListener) { + + } + }; + } +} diff --git a/tp-framework/src/main/java/com/inscloudtech/framework/filter/EncryptResponseBodyWrapper.java b/tp-framework/src/main/java/com/inscloudtech/framework/filter/EncryptResponseBodyWrapper.java new file mode 100644 index 0000000..d4b5f14 --- /dev/null +++ b/tp-framework/src/main/java/com/inscloudtech/framework/filter/EncryptResponseBodyWrapper.java @@ -0,0 +1,125 @@ +package com.inscloudtech.framework.filter; + +import cn.hutool.core.util.RandomUtil; +import com.inscloudtech.common.utils.EncryptUtils; + + +import javax.servlet.ServletOutputStream; +import javax.servlet.WriteListener; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpServletResponseWrapper; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.nio.charset.StandardCharsets; + +/** + * 加密响应参数包装类 + * + * @author Michelle.Chung + */ +public class EncryptResponseBodyWrapper extends HttpServletResponseWrapper { + + private final ByteArrayOutputStream byteArrayOutputStream; + private final ServletOutputStream servletOutputStream; + private final PrintWriter printWriter; + + public EncryptResponseBodyWrapper(HttpServletResponse response) throws IOException { + super(response); + this.byteArrayOutputStream = new ByteArrayOutputStream(); + this.servletOutputStream = this.getOutputStream(); + this.printWriter = new PrintWriter(new OutputStreamWriter(byteArrayOutputStream)); + } + + @Override + public PrintWriter getWriter() { + return printWriter; + } + + @Override + public void flushBuffer() throws IOException { + if (servletOutputStream != null) { + servletOutputStream.flush(); + } + if (printWriter != null) { + printWriter.flush(); + } + } + + @Override + public void reset() { + byteArrayOutputStream.reset(); + } + + public byte[] getResponseData() throws IOException { + flushBuffer(); + return byteArrayOutputStream.toByteArray(); + } + + public String getContent() throws IOException { + flushBuffer(); + return byteArrayOutputStream.toString(); + } + + /** + * 获取加密内容 + * + * @param servletResponse response + * @param publicKey RSA公钥 (用于加密 AES 秘钥) + * @param headerFlag 请求头标志 + * @return 加密内容 + * @throws IOException + */ + public String getEncryptContent(HttpServletResponse servletResponse, String publicKey, String headerFlag) throws IOException { + // 生成秘钥 + String aesPassword = RandomUtil.randomString(32); + // 秘钥使用 Base64 编码 + String encryptAes = EncryptUtils.encryptByBase64(aesPassword); + // Rsa 公钥加密 Base64 编码 + String encryptPassword = EncryptUtils.encryptByRsa(encryptAes, publicKey); + + // 设置响应头 + servletResponse.addHeader("Access-Control-Expose-Headers", headerFlag); + servletResponse.setHeader(headerFlag, encryptPassword); + servletResponse.setHeader("Access-Control-Allow-Origin", "*"); + servletResponse.setHeader("Access-Control-Allow-Methods", "*"); + servletResponse.setCharacterEncoding(StandardCharsets.UTF_8.toString()); + + // 获取原始内容 + String originalBody = this.getContent(); + // 对内容进行加密 + return EncryptUtils.encryptByAes(originalBody, aesPassword); + } + + @Override + public ServletOutputStream getOutputStream() throws IOException { + return new ServletOutputStream() { + @Override + public boolean isReady() { + return false; + } + + @Override + public void setWriteListener(WriteListener writeListener) { + + } + + @Override + public void write(int b) throws IOException { + byteArrayOutputStream.write(b); + } + + @Override + public void write(byte[] b) throws IOException { + byteArrayOutputStream.write(b); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + byteArrayOutputStream.write(b, off, len); + } + }; + } + +} diff --git a/tp-functional/pom.xml b/tp-functional/pom.xml index d452827..2818b58 100644 --- a/tp-functional/pom.xml +++ b/tp-functional/pom.xml @@ -15,6 +15,11 @@ com.inscloudtech tp-common + + + org.jsoup + jsoup + diff --git a/tp-functional/src/main/java/com/inscloudtech/functional/controller/CpuInfoController.java b/tp-functional/src/main/java/com/inscloudtech/functional/controller/CpuInfoController.java new file mode 100644 index 0000000..1901fef --- /dev/null +++ b/tp-functional/src/main/java/com/inscloudtech/functional/controller/CpuInfoController.java @@ -0,0 +1,169 @@ +package com.inscloudtech.functional.controller; + +/***/ + + +import cn.hutool.core.util.StrUtil; +import cn.hutool.http.HttpUtil; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.inscloudtech.common.annotation.Log; +import com.inscloudtech.common.annotation.RepeatSubmit; +import com.inscloudtech.common.core.domain.PageQuery; +import com.inscloudtech.common.core.domain.R; +import com.inscloudtech.common.core.page.TableDataInfo; +import com.inscloudtech.common.enums.BusinessType; +import com.inscloudtech.functional.domain.CpuInfo; +import com.inscloudtech.functional.service.CpuInfoService; +import lombok.RequiredArgsConstructor; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; +import org.jsoup.nodes.Element; +import org.jsoup.select.Elements; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +/** + * CPU性能数据库 + * + * @author zfcf + * @date 2024-08-28 + */ +@RestController +@RequiredArgsConstructor +@RequestMapping("/functional/info") +public class CpuInfoController { + + private final CpuInfoService cpuInfoService; + + /** + * 分页查询 + * @param + * @param + * @return + */ + @GetMapping("/page" ) + public TableDataInfo getCpuInfoPage(PageQuery pageQuery, CpuInfo cpuInfo) { + Page page = new Page(); + page.setSize(pageQuery.getPageSize()); + page.setCurrent(pageQuery.getPageNum()); + Page result = cpuInfoService.page(page, Wrappers.query(cpuInfo)); + TableDataInfo dataInfo = new TableDataInfo(); + dataInfo.setTotal(result.getTotal()); + dataInfo.setRows(result.getRecords()); + return dataInfo; + } + + + /** + * 通过id查询cpu信息 + * @param id id + * @return R + */ + @GetMapping("/{id}" ) + public R getById(@PathVariable("id" ) Long id) { + return R.ok(cpuInfoService.getById(id)); + } + + /** + * 新增cpu信息 + * @param + * @return R + */ + @Log(title = "cpu信息", businessType = BusinessType.EXPORT) + @RepeatSubmit() + @PostMapping + public R save(@RequestBody CpuInfo cpuInfo) { + return R.ok(cpuInfoService.save(cpuInfo)); + } + + /** + * 修改cpu信息 + * @param + * @return R + */ + @Log(title = "cpu信息", businessType = BusinessType.EXPORT) + @RepeatSubmit() + @PutMapping + public R updateById(@RequestBody CpuInfo cpuInfo) { + return R.ok(cpuInfoService.updateById(cpuInfo)); + } + + /** + * 通过id删除cpu信息 + * @param id id + * @return R + */ + @DeleteMapping("/{id}" ) + public R removeById(@PathVariable Long id) { + return R.ok(cpuInfoService.removeById(id)); + } + + @GetMapping("/updateOtherInfo" ) + public void updateOtherInfo() { + List list = cpuInfoService.list(); + int i = 0; + for (CpuInfo info : list) { + updateByURL(info); + System.out.println(i++); + try { + cpuInfoService.updateById(info); + }catch (Exception e){ + System.out.println("e.getMessage() = " + e.getMessage()); + } + } + + + } + + static String url = "https://cpu.bmcx.com/{}__cpu/"; + + public static void main(String[] args) { + CpuInfo info = new CpuInfo(); + info.setId("5493"); + updateByURL(info); + } + + static void updateByURL(CpuInfo cpuInfo){ + + String id = cpuInfo.getId(); + String _url = StrUtil.format(url,id); + String html = HttpUtil.get(_url); + Document document = Jsoup.parse(html); + Element mainContent = document.getElementById("main_content"); + Elements tables = mainContent.getElementsByTag("table"); + Elements tds = tables.get(1).getElementsByTag("td"); + for(int i = 0; i < tds.size(); i++){ + if (i < 6) { + continue; + } + + Element td = tds.get(i); + if(i + 1 == tds.size()){ + break; + } + Element valTd = tds.get(i + 1); + String field = td.text(); + String val = valTd.text(); + if(field.equals("TDP")){ + cpuInfo.setTdp(val); + }else if(field.equals("插槽类型")){ + cpuInfo.setSocketType(val); + }else if(field.equals("核心数")){ + cpuInfo.setCoreCount(val); + }else if(field.equals("线程数")){ + cpuInfo.setThreadCount(val); + }else if(field.equals("主频")){ + cpuInfo.setBaseFrequency(val); + }else if(field.equals("睿频")){ + cpuInfo.setBoostFrequency(val); + }else if(field.equals("发布时间")){ + cpuInfo.setReleaseDate(val); + } + } +// System.out.println("cpuInfo = " + cpuInfo); + } + + +} diff --git a/tp-functional/src/main/java/com/inscloudtech/functional/domain/CpuInfo.java b/tp-functional/src/main/java/com/inscloudtech/functional/domain/CpuInfo.java new file mode 100644 index 0000000..c9547ed --- /dev/null +++ b/tp-functional/src/main/java/com/inscloudtech/functional/domain/CpuInfo.java @@ -0,0 +1,72 @@ +package com.inscloudtech.functional.domain; + +import com.baomidou.mybatisplus.annotation.*; +import lombok.Data; +import lombok.EqualsAndHashCode; + + +/** + * cpu信息对象 cpu_info + * + * @author zfcf + * @date 2024-08-28 + */ +@Data +@TableName("cpu_info") +public class CpuInfo { + + private static final long serialVersionUID=1L; + + /** + * 主键 + */ + @TableId(value = "id") + private String id; + /** + * 性能排名 + */ + private String paiMing; + /** + * 名称 + */ + @TableField(condition = SqlCondition.LIKE) + private String mingCheng; + /** + * + */ + private String baiFenBi; + /** + *得分 + */ + private String shuZhi; + /** + * TDP + */ + private String tdp; + /** + * 插槽类型 + */ + private String socketType; + /** + * 核心数 + */ + private String coreCount; + /** + * 线程数 + */ + private String threadCount; + /** + * 主频 + */ + private String baseFrequency; + /** + * 睿频 + */ + private String boostFrequency; + /** + * 发布时间 + */ + private String releaseDate; + +} + diff --git a/tp-functional/src/main/java/com/inscloudtech/functional/mapper/CpuInfoMapper.java b/tp-functional/src/main/java/com/inscloudtech/functional/mapper/CpuInfoMapper.java new file mode 100644 index 0000000..934bef5 --- /dev/null +++ b/tp-functional/src/main/java/com/inscloudtech/functional/mapper/CpuInfoMapper.java @@ -0,0 +1,18 @@ +package com.inscloudtech.functional.mapper; + + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.inscloudtech.functional.domain.CpuInfo; +import org.apache.ibatis.annotations.Mapper; + +/** + * cpu信息 + * + * @author zfcf + * @date 2024-08-28 + */ +@Mapper +public interface CpuInfoMapper extends BaseMapper { + +} diff --git a/tp-functional/src/main/java/com/inscloudtech/functional/service/CpuInfoService.java b/tp-functional/src/main/java/com/inscloudtech/functional/service/CpuInfoService.java new file mode 100644 index 0000000..fdb50b0 --- /dev/null +++ b/tp-functional/src/main/java/com/inscloudtech/functional/service/CpuInfoService.java @@ -0,0 +1,16 @@ +package com.inscloudtech.functional.service; + + +import com.baomidou.mybatisplus.extension.service.IService; +import com.inscloudtech.functional.domain.CpuInfo; + + +/** + * cpu信息Service接口 + * @author zfcf + * @date 2024-08-28 + */ +public interface CpuInfoService extends IService { + +} + diff --git a/tp-functional/src/main/java/com/inscloudtech/functional/service/impl/CpuInfoServiceImpl.java b/tp-functional/src/main/java/com/inscloudtech/functional/service/impl/CpuInfoServiceImpl.java new file mode 100644 index 0000000..a7342d7 --- /dev/null +++ b/tp-functional/src/main/java/com/inscloudtech/functional/service/impl/CpuInfoServiceImpl.java @@ -0,0 +1,21 @@ +package com.inscloudtech.functional.service.impl; + + + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; + +import com.inscloudtech.functional.domain.CpuInfo; +import com.inscloudtech.functional.mapper.CpuInfoMapper; +import com.inscloudtech.functional.service.CpuInfoService; +import org.springframework.stereotype.Service; + +/** + * cpu信息 + * + * @author zfcf + * @date 2024-08-28 + */ +@Service +public class CpuInfoServiceImpl extends ServiceImpl implements CpuInfoService { + +} diff --git a/tp-system/src/main/java/com/inscloudtech/system/service/impl/ToolManageServiceImpl.java b/tp-system/src/main/java/com/inscloudtech/system/service/impl/ToolManageServiceImpl.java index e745f6f..5e4f170 100644 --- a/tp-system/src/main/java/com/inscloudtech/system/service/impl/ToolManageServiceImpl.java +++ b/tp-system/src/main/java/com/inscloudtech/system/service/impl/ToolManageServiceImpl.java @@ -61,6 +61,7 @@ public class ToolManageServiceImpl implements IToolManageService { @Override public TableDataInfo queryPageList(ToolManage bo, PageQuery pageQuery) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); + lqw.orderByDesc(ToolManage::getCreateTime); Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); return TableDataInfo.build(result); }