浏览代码

first commit

qrs 1 月之前
当前提交
ce990d6a19
共有 100 个文件被更改,包括 5568 次插入0 次删除
  1. 34 0
      .gitignore
  2. 0 0
      README.md
  3. 35 0
      alien-api/.gitignore
  4. 3 0
      alien-api/README.md
  5. 203 0
      alien-api/pom.xml
  6. 28 0
      alien-api/src/main/java/shop/alien/api/ApiApplication.java
  7. 57 0
      alien-api/src/main/java/shop/alien/api/config/SwaggerConfig.java
  8. 119 0
      alien-api/src/main/java/shop/alien/api/controller/GaoDeController.java
  9. 82 0
      alien-api/src/main/java/shop/alien/api/feign/GaoDeFeign.java
  10. 31 0
      alien-api/src/main/java/shop/alien/api/feign/JuHeFeign.java
  11. 39 0
      alien-api/src/main/java/shop/alien/api/feign/QWeatherAirQualityFeign.java
  12. 44 0
      alien-api/src/main/java/shop/alien/api/feign/QWeatherGeoFeign.java
  13. 202 0
      alien-api/src/main/java/shop/alien/api/feign/QWeatherWeatherFeign.java
  14. 399 0
      alien-api/src/main/java/shop/alien/api/feign/RollFeign.java
  15. 32 0
      alien-api/src/main/java/shop/alien/api/feign/TencentMapFeign.java
  16. 20 0
      alien-api/src/main/java/shop/alien/api/feign/TimeOutFeign.java
  17. 97 0
      alien-api/src/main/java/shop/alien/api/feign/WawaFeign.java
  18. 28 0
      alien-api/src/main/java/shop/alien/api/feign/WeatherBureauFeign.java
  19. 11 0
      alien-api/src/main/resources/banner.txt
  20. 30 0
      alien-api/src/main/resources/bootstrap.yml
  21. 173 0
      alien-api/src/main/resources/logback-spring.xml
  22. 33 0
      alien-config/.gitignore
  23. 1 0
      alien-config/README.md
  24. 82 0
      alien-config/pom.xml
  25. 66 0
      alien-config/src/main/java/shop/alien/config/databases/DruidConfig.java
  26. 40 0
      alien-config/src/main/java/shop/alien/config/databases/MyBatisFieldHandler.java
  27. 16 0
      alien-config/src/main/java/shop/alien/config/databases/MyBatisPlusPageConfig.java
  28. 64 0
      alien-config/src/main/java/shop/alien/config/feign/FeignBodyLogger.java
  29. 26 0
      alien-config/src/main/java/shop/alien/config/feign/FeignNacosConfig.java
  30. 58 0
      alien-config/src/main/java/shop/alien/config/feign/FeignOptionConfig.java
  31. 75 0
      alien-config/src/main/java/shop/alien/config/feign/GzipResponseDecoder.java
  32. 109 0
      alien-config/src/main/java/shop/alien/config/feign/OkHttpConfig.java
  33. 34 0
      alien-config/src/main/java/shop/alien/config/filter/FilterConfig.java
  34. 23 0
      alien-config/src/main/java/shop/alien/config/filter/HttpRequestConfig.java
  35. 21 0
      alien-config/src/main/java/shop/alien/config/filter/ReplaceStreamFilter.java
  36. 75 0
      alien-config/src/main/java/shop/alien/config/filter/RequestInterceptor.java
  37. 105 0
      alien-config/src/main/java/shop/alien/config/filter/RequestWrapper.java
  38. 39 0
      alien-config/src/main/java/shop/alien/config/http/HttpConfig.java
  39. 152 0
      alien-config/src/main/java/shop/alien/config/redis/BaseRedisService.java
  40. 33 0
      alien-entity/.gitignore
  41. 1 0
      alien-entity/README.md
  42. 78 0
      alien-entity/pom.xml
  43. 82 0
      alien-entity/src/main/java/shop/alien/entity/analysis/entity/AnalysisLog.java
  44. 58 0
      alien-entity/src/main/java/shop/alien/entity/analysis/entity/AnalysisToken.java
  45. 61 0
      alien-entity/src/main/java/shop/alien/entity/analysis/entity/AnalysisUser.java
  46. 61 0
      alien-entity/src/main/java/shop/alien/entity/analysis/entity/DouYinAnalysis.java
  47. 16 0
      alien-entity/src/main/java/shop/alien/entity/analysis/mapper/AnalysisLogMapper.java
  48. 16 0
      alien-entity/src/main/java/shop/alien/entity/analysis/mapper/AnalysisTokenMapper.java
  49. 16 0
      alien-entity/src/main/java/shop/alien/entity/analysis/mapper/AnalysisUserMapper.java
  50. 59 0
      alien-entity/src/main/java/shop/alien/entity/area/entity/AreaCode.java
  51. 103 0
      alien-entity/src/main/java/shop/alien/entity/area/entity/QweatherLocationCode.java
  52. 16 0
      alien-entity/src/main/java/shop/alien/entity/area/mapper/AreaCodeMapper.java
  53. 14 0
      alien-entity/src/main/java/shop/alien/entity/area/mapper/QweatherLocationCodeMapper.java
  54. 22 0
      alien-entity/src/main/java/shop/alien/entity/area/service/AreaCodeService.java
  55. 14 0
      alien-entity/src/main/java/shop/alien/entity/area/service/QweatherLocationCodeService.java
  56. 32 0
      alien-entity/src/main/java/shop/alien/entity/area/service/impl/AreaCodeServiceImpl.java
  57. 18 0
      alien-entity/src/main/java/shop/alien/entity/area/service/impl/QweatherLocationCodeServiceImpl.java
  58. 79 0
      alien-entity/src/main/java/shop/alien/entity/bot/entity/MsgFootballInfo.java
  59. 53 0
      alien-entity/src/main/java/shop/alien/entity/bot/entity/WeChatBot.java
  60. 33 0
      alien-entity/src/main/java/shop/alien/entity/bot/entity/WeChatBotReturn.java
  61. 34 0
      alien-entity/src/main/java/shop/alien/entity/bot/entity/WeChatSend.java
  62. 76 0
      alien-entity/src/main/java/shop/alien/entity/bot/entity/ZhugeLots.java
  63. 14 0
      alien-entity/src/main/java/shop/alien/entity/bot/mapper/MsgFootballInfoMapper.java
  64. 14 0
      alien-entity/src/main/java/shop/alien/entity/bot/mapper/ZhugeLotsMapper.java
  65. 80 0
      alien-entity/src/main/java/shop/alien/entity/device/entity/DeviceInfo.java
  66. 60 0
      alien-entity/src/main/java/shop/alien/entity/device/entity/MsgAppVersion.java
  67. 68 0
      alien-entity/src/main/java/shop/alien/entity/device/entity/MsgDeviceStyle.java
  68. 80 0
      alien-entity/src/main/java/shop/alien/entity/device/entity/MsgImportantDate.java
  69. 40 0
      alien-entity/src/main/java/shop/alien/entity/device/entity/MsgImportantDateDto.java
  70. 68 0
      alien-entity/src/main/java/shop/alien/entity/device/entity/MsgPushLog.java
  71. 64 0
      alien-entity/src/main/java/shop/alien/entity/device/entity/MsgUserDeviceBind.java
  72. 84 0
      alien-entity/src/main/java/shop/alien/entity/device/entity/MsgWechatUserInfo.java
  73. 31 0
      alien-entity/src/main/java/shop/alien/entity/device/entity/UserBindDeviceInfo.java
  74. 37 0
      alien-entity/src/main/java/shop/alien/entity/device/mapper/DeviceInfoMapper.java
  75. 18 0
      alien-entity/src/main/java/shop/alien/entity/device/mapper/MsgAppVersionMapper.java
  76. 18 0
      alien-entity/src/main/java/shop/alien/entity/device/mapper/MsgDeviceStyleMapper.java
  77. 20 0
      alien-entity/src/main/java/shop/alien/entity/device/mapper/MsgImportantDateMapper.java
  78. 35 0
      alien-entity/src/main/java/shop/alien/entity/device/mapper/MsgPushLogMapper.java
  79. 20 0
      alien-entity/src/main/java/shop/alien/entity/device/mapper/MsgUserDeviceBindMapper.java
  80. 20 0
      alien-entity/src/main/java/shop/alien/entity/device/mapper/MsgWechatUserInfoMapper.java
  81. 69 0
      alien-entity/src/main/java/shop/alien/entity/device/service/DeviceInfoService.java
  82. 23 0
      alien-entity/src/main/java/shop/alien/entity/device/service/MsgAppVersionService.java
  83. 16 0
      alien-entity/src/main/java/shop/alien/entity/device/service/MsgDeviceStyleService.java
  84. 54 0
      alien-entity/src/main/java/shop/alien/entity/device/service/MsgImportantDateService.java
  85. 43 0
      alien-entity/src/main/java/shop/alien/entity/device/service/MsgPushLogService.java
  86. 167 0
      alien-entity/src/main/java/shop/alien/entity/device/service/impl/DeviceInfoServiceImpl.java
  87. 33 0
      alien-entity/src/main/java/shop/alien/entity/device/service/impl/MsgAppVersionServiceImpl.java
  88. 20 0
      alien-entity/src/main/java/shop/alien/entity/device/service/impl/MsgDeviceStyleServiceImpl.java
  89. 303 0
      alien-entity/src/main/java/shop/alien/entity/device/service/impl/MsgImportantDateServiceImpl.java
  90. 71 0
      alien-entity/src/main/java/shop/alien/entity/device/service/impl/MsgPushLogServiceImpl.java
  91. 57 0
      alien-entity/src/main/java/shop/alien/entity/idiom/entity/IdiomLibrary.java
  92. 16 0
      alien-entity/src/main/java/shop/alien/entity/idiom/mapper/IdiomLibraryMapper.java
  93. 14 0
      alien-entity/src/main/java/shop/alien/entity/idiom/service/IdiomLibraryService.java
  94. 18 0
      alien-entity/src/main/java/shop/alien/entity/idiom/service/impl/IdiomLibraryServiceImpl.java
  95. 29 0
      alien-entity/src/main/java/shop/alien/entity/msg/dingding/entity/DingDingMsgDto.java
  96. 72 0
      alien-entity/src/main/java/shop/alien/entity/msg/dingding/entity/DingDingMsgLog.java
  97. 66 0
      alien-entity/src/main/java/shop/alien/entity/msg/dingding/entity/DingDingRobotConfig.java
  98. 18 0
      alien-entity/src/main/java/shop/alien/entity/msg/dingding/mapper/DingDingMsgLogMapper.java
  99. 18 0
      alien-entity/src/main/java/shop/alien/entity/msg/dingding/mapper/DingDingRobotConfigMapper.java
  100. 29 0
      alien-entity/src/main/java/shop/alien/entity/msg/email/entity/EmailContent.java

+ 34 - 0
.gitignore

@@ -0,0 +1,34 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+/log/

+ 0 - 0
README.md


+ 35 - 0
alien-api/.gitignore

@@ -0,0 +1,35 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/
+
+reebel.xml

+ 3 - 0
alien-api/README.md

@@ -0,0 +1,3 @@
+# openfeign 接口提供
+
+# openfeign 接口调用

+ 203 - 0
alien-api/pom.xml

@@ -0,0 +1,203 @@
+<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>shop.alien</groupId>
+        <artifactId>alien-cloud</artifactId>
+        <version>1.0.0</version>
+    </parent>
+
+    <artifactId>alien-api</artifactId>
+    <version>1.0.0</version>
+    <name>alien-api</name>
+    <description>alien-api</description>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    </properties>
+
+    <dependencies>
+
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+            <exclusions>
+                <exclusion>
+                    <groupId>org.springframework.boot</groupId>
+                    <artifactId>spring-boot-starter-tomcat</artifactId>
+                </exclusion>
+            </exclusions>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-undertow</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+
+<!--        <dependency>-->
+<!--            <groupId>org.springframework.boot</groupId>-->
+<!--            <artifactId>spring-boot-starter-amqp</artifactId>-->
+<!--        </dependency>-->
+
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.github.openfeign</groupId>
+            <artifactId>feign-okhttp</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.github.pagehelper</groupId>
+            <artifactId>pagehelper-spring-boot-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.swagger</groupId>
+            <artifactId>swagger-annotations</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.swagger</groupId>
+            <artifactId>swagger-models</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger-ui</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.github.xiaoymin</groupId>
+            <artifactId>swagger-bootstrap-ui</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>shop.alien</groupId>
+            <artifactId>alien-util</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>shop.alien</groupId>
+            <artifactId>alien-entity</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+
+        <dependency>
+            <groupId>shop.alien</groupId>
+            <artifactId>alien-config</artifactId>
+            <version>1.0.0</version>
+        </dependency>
+
+        <!--        <dependency>-->
+        <!--            <groupId>cc.xiaokuihua</groupId>-->
+        <!--            <artifactId>xiaokuihua-config</artifactId>-->
+        <!--            <version>1.0.0</version>-->
+        <!--        </dependency>-->
+
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-dependency-plugin</artifactId>
+                <version>3.1.2</version> <!-- 使用最新版本 -->
+                <executions>
+                    <execution>
+                        <id>copy-dependencies</id>
+                        <phase>prepare-package</phase> <!-- 在package之前执行 -->
+                        <goals>
+                            <goal>copy-dependencies</goal>
+                        </goals>
+                        <configuration>
+                            <outputDirectory>${project.build.directory}/lib</outputDirectory> <!-- 指定输出目录 -->
+                            <includeScope>runtime</includeScope> <!-- 仅包含运行时依赖 -->
+                        </configuration>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <configuration>
+                    <mainClass>shop.alien.api.ApiApplication</mainClass>
+                    <layout>ZIP</layout>
+                    <includes>
+                        <include>
+                            <groupId>nothing</groupId>
+                            <artifactId>nothing</artifactId>
+                        </include>
+                    </includes>
+                </configuration>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>8</source>
+                    <target>8</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+</project>

+ 28 - 0
alien-api/src/main/java/shop/alien/api/ApiApplication.java

@@ -0,0 +1,28 @@
+package shop.alien.api;
+
+import com.github.xiaoymin.swaggerbootstrapui.annotations.EnableSwaggerBootstrapUI;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.annotation.ComponentScan;
+
+@ComponentScan({
+        //配置
+        "cc.xiaokuihua.config.databases",
+        "cc.xiaokuihua.config.feign",
+//        "cc.xiaokuihua.config.filter",
+        "cc.xiaokuihua.config.http",
+        "cc.xiaokuihua.config.redis",
+        //此项目
+        "cc.xiaokuihua.api.*"
+})
+@EnableFeignClients(basePackages = {"cc.xiaokuihua.api.feign"})
+@EnableSwaggerBootstrapUI
+@SpringBootApplication
+public class ApiApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(ApiApplication.class, args);
+    }
+
+}

+ 57 - 0
alien-api/src/main/java/shop/alien/api/config/SwaggerConfig.java

@@ -0,0 +1,57 @@
+package shop.alien.api.config;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import springfox.documentation.builders.ApiInfoBuilder;
+import springfox.documentation.builders.PathSelectors;
+import springfox.documentation.builders.RequestHandlerSelectors;
+import springfox.documentation.service.ApiInfo;
+import springfox.documentation.service.Contact;
+import springfox.documentation.spi.DocumentationType;
+import springfox.documentation.spring.web.plugins.Docket;
+import springfox.documentation.swagger2.annotations.EnableSwagger2;
+
+/**
+ * swagger配置类
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2022/07/07 09:07
+ */
+@Configuration
+@EnableSwagger2
+public class SwaggerConfig {
+
+    /**
+     * controller扫描
+     *
+     * @return controller扫描
+     */
+    @Bean
+    public Docket docket() {
+        return new Docket(DocumentationType.SWAGGER_2)
+                .apiInfo(apiInfo())
+                .groupName("第三方Api服务")
+                .select()
+                .apis(RequestHandlerSelectors.any())
+                .paths(PathSelectors.any())
+                .build();
+    }
+
+    /**
+     * Api标题信息
+     *
+     * @return api标题Api标题信息
+     */
+    public ApiInfo apiInfo() {
+        Contact contact = new Contact("ssk", "https://api.xiaokuihua.cc", "172380199@qq.com");
+        return new ApiInfoBuilder()
+                .title("第三方Api服务")
+                .description("第三方Api服务")
+                .license("ssk")
+                .contact(contact)
+                .termsOfServiceUrl("https://api.xiaokuihua.cc")
+                .version("1.0.0")
+                .build();
+    }
+}

+ 119 - 0
alien-api/src/main/java/shop/alien/api/controller/GaoDeController.java

@@ -0,0 +1,119 @@
+package shop.alien.api.controller;
+
+import shop.alien.api.feign.GaoDeFeign;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import io.swagger.annotations.*;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import shop.alien.entity.result.R;
+
+/**
+ * Api_高德
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/10/24 10:23
+ */
+@Api(tags = {"Api_高德"})
+@ApiSort(1)
+@CrossOrigin
+@RestController
+@RequestMapping("/gaode")
+@RequiredArgsConstructor
+public class GaoDeController {
+
+    private final GaoDeFeign gaoDeFeign;
+
+    @Value("${api.gaode.web}")
+    private String gaoDeKey;
+
+    /**
+     * 高德-地理编码
+     * 每日配额5000,并发每秒30
+     * https://lbs.amap.com/api/webservice/guide/api/georegeo
+     *
+     * @param address 结构化地址信息, 规则遵循:国家、省份、城市、区县、城镇、乡村、街道、门牌号码、屋邨、大厦,如:北京市朝阳区阜通东大街6号。
+     * @return R<Object>
+     */
+    @ApiOperation("地理编码")
+    @ApiOperationSupport(order = 1)
+    @ApiImplicitParams({@ApiImplicitParam(name = "address", value = "结构化地址信息", dataType = "String", paramType = "query", required = true)})
+    @GetMapping("/geo")
+    public R<Object> geo(String address) {
+        String output = "JSON";
+        return R.data(gaoDeFeign.geo(output, address, gaoDeKey));
+    }
+
+    /**
+     * 高德-逆地理编码
+     * 每日配额5000,并发每秒30
+     * https://lbs.amap.com/api/webservice/guide/api/georegeo
+     *
+     * @param longitude 经度
+     * @param latitude  纬度
+     * @return R<Object>
+     */
+    @ApiOperation(value = "逆地理编码", notes = "每日配额5000,并发每秒30, 可用经纬度: longitude=121.573163&latitude=39.006614")
+    @ApiOperationSupport(order = 2)
+    @ApiImplicitParams({@ApiImplicitParam(name = "longitude", value = "经度", dataType = "String", paramType = "query", required = true), @ApiImplicitParam(name = "latitude", value = "纬度", dataType = "String", paramType = "query", required = true)})
+    @GetMapping("/regeo")
+    public R<Object> regeo(String longitude, String latitude) {
+        String output = "JSON";
+        String location = longitude + "," + latitude;
+        String radius = "1000";
+        String extensions = "all";
+        return R.data(gaoDeFeign.reGeo(output, location, gaoDeKey, radius, extensions));
+    }
+
+    /**
+     * 高德-天气查询
+     * 每日配额300000,并发每秒200
+     * https://lbs.amap.com/api/webservice/guide/api/weatherinfo
+     *
+     * @param areaCode   区域code
+     * @param extensions 查询类型(base:查询当天,all:查询当天加未来)
+     * @return R<Object>
+     */
+    @ApiOperation(value = "天气查询", notes = "每日配额300000,并发每秒200, 可用参数: areaCode=210200&extensions=base")
+    @ApiOperationSupport(order = 3)
+    @ApiImplicitParams({@ApiImplicitParam(name = "areaCode", value = "区域code", dataType = "String", paramType = "query", required = true),
+            @ApiImplicitParam(name = "extensions", value = "查询类型(base:查询当天,all:查询当天加未来)", dataType = "String", paramType = "query", required = true)})
+    @GetMapping("/weatherInfo")
+    public R<Object> weatherInfo(String areaCode, String extensions) {
+        String output = "JSON";
+        JSONObject jsonObject = gaoDeFeign.weatherInfo(output, gaoDeKey, areaCode, extensions);
+        if ("all".equals(extensions)) {
+            //预报天气信息数据
+            JSONArray forecastsArray = jsonObject.getJSONArray("forecasts");
+            return R.data(forecastsArray.getJSONObject(0));
+        } else {
+            //实况天气数据信息
+            JSONArray lives = jsonObject.getJSONArray("lives");
+            if (lives != null && !lives.isEmpty()) {
+                return R.data(lives.getJSONObject(0));
+            }
+            return null;
+        }
+    }
+
+    /**
+     * 高德-IP定位
+     * 每日配额5000,并发每秒3
+     * https://lbs.amap.com/api/webservice/guide/api/ipconfig
+     *
+     * @param ip ip地址, 需要搜索的 IP 地址(仅支持国内)若用户不填写 IP,则取客户 http 之中的请求来进行定位
+     * @return R<Object>
+     */
+    @ApiOperation("IP定位")
+    @ApiOperationSupport(order = 4)
+    @ApiImplicitParams({@ApiImplicitParam(name = "ip", value = "ip地址", dataType = "String", paramType = "query", required = true)})
+    @GetMapping("/ip")
+    public R<Object> ip(String ip) {
+        return R.data(gaoDeFeign.ip(ip, gaoDeKey));
+    }
+}

+ 82 - 0
alien-api/src/main/java/shop/alien/api/feign/GaoDeFeign.java

@@ -0,0 +1,82 @@
+package shop.alien.api.feign;
+
+import com.alibaba.fastjson.JSONObject;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * 调用高德接口
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/10/24 10:19
+ */
+@FeignClient(url = "https://restapi.amap.com/v3", name = "gaode")
+public interface GaoDeFeign {
+
+    /**
+     * 高德-地理编码
+     * 每日配额5000,并发每秒30
+     * https://lbs.amap.com/api/webservice/guide/api/georegeo
+     *
+     * @param output  返回数据格式类型,可选输入内容包括:JSON,XML。设置 JSON 返回结果数据将会以 JSON 结构构成;如果设置 XML 返回结果数据将以 XML 结构构成。
+     * @param address 结构化地址信息, 规则遵循:国家、省份、城市、区县、城镇、乡村、街道、门牌号码、屋邨、大厦,如:北京市朝阳区阜通东大街6号。
+     * @param key     高德Key
+     * @return JSONObject
+     */
+    @GetMapping("/geocode/geo")
+    JSONObject geo(@RequestParam(value = "output") String output,
+                   @RequestParam(value = "address") String address,
+                   @RequestParam(value = "key") String key);
+
+    /**
+     * 高德-逆地理编码
+     * 每日配额5000,并发每秒30
+     * https://lbs.amap.com/api/webservice/guide/api/georegeo
+     *
+     * @param output     返回数据格式类型, 可选输入内容包括:JSON,XML。设置 JSON 返回结果数据将会以 JSON 结构构成;如果设置 XML 返回结果数据将以 XML 结构构成。
+     * @param location   经纬度坐标, 传入内容规则:经度在前,纬度在后,经纬度间以“,”分割,经纬度小数点后不要超过 6 位。
+     * @param key        高德Key
+     * @param radius     搜索半径, radius 取值范围:0~3000,默认值:1000。单位:米
+     * @param extensions 返回结果控制, extensions 参数默认取值是 base,也就是返回基本地址信息;xtensions 参数取值为 all 时会返回基本地址信息、附近 POI 内容、道路信息以及道路交叉口信息。
+     * @return JSONObject
+     */
+    @GetMapping("/geocode/regeo")
+    JSONObject reGeo(@RequestParam(value = "output") String output,
+                     @RequestParam(value = "location") String location,
+                     @RequestParam(value = "key") String key,
+                     @RequestParam(value = "radius") String radius,
+                     @RequestParam(value = "extensions") String extensions);
+
+    /**
+     * 高德-天气查询
+     * 每日配额300000,并发每秒200
+     * https://lbs.amap.com/api/webservice/guide/api/weatherinfo
+     *
+     * @param output     返回数据格式类型, 可选输入内容包括:JSON,XML。设置 JSON 返回结果数据将会以 JSON 结构构成;如果设置 XML 返回结果数据将以 XML 结构构成。
+     * @param key        高德Key
+     * @param city       城市编码, 输入城市的 adcode,adcode 信息可参考 城市编码表
+     * @param extensions 气象类型, 可选值:base/all, base:返回实况天气, all:返回预报天气
+     * @return JSONObject
+     */
+    @GetMapping("/weather/weatherInfo")
+    JSONObject weatherInfo(@RequestParam(value = "output") String output,
+                           @RequestParam(value = "key") String key,
+                           @RequestParam(value = "city") String city,
+                           @RequestParam(value = "extensions") String extensions);
+
+    /**
+     * 高德-IP定位
+     * 每日配额5000,并发每秒3
+     * https://lbs.amap.com/api/webservice/guide/api/ipconfig
+     *
+     * @param ip  ip地址
+     * @param key 高德Key
+     * @return JSONObject
+     */
+    @GetMapping("/ip")
+    JSONObject ip(@RequestParam(value = "ip") String ip,
+                  @RequestParam(value = "key") String key);
+
+}

+ 31 - 0
alien-api/src/main/java/shop/alien/api/feign/JuHeFeign.java

@@ -0,0 +1,31 @@
+package shop.alien.api.feign;
+
+import com.alibaba.fastjson.JSONObject;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * 调用聚合接口
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/10/24 14:19
+ */
+@FeignClient(url = "https://v.juhe.cn", name = "juhe")
+public interface JuHeFeign {
+
+    /**
+     * 聚合-万年历-获取当天的详细信息
+     * 每日配额50,会员无限制
+     * https://www.juhe.cn/docs/api/id/177
+     *
+     * @param date 指定日期,格式为YYYY-MM-DD,如月份和日期小于10,则取个位,如:2012-1-1
+     * @param key  您申请的appKey
+     * @return JSONObject
+     */
+    @GetMapping("/calendar/day")
+    JSONObject calendarDay(@RequestParam(value = "date") String date,
+                           @RequestParam(value = "key") String key);
+
+}

+ 39 - 0
alien-api/src/main/java/shop/alien/api/feign/QWeatherAirQualityFeign.java

@@ -0,0 +1,39 @@
+package shop.alien.api.feign;
+
+import com.alibaba.fastjson.JSONObject;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * 和风空气质量
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2025/3/17 16:28
+ */
+@FeignClient(url = "https://devapi.qweather.com/airquality/v1", name = "heFengAirQualityApi")
+public interface QWeatherAirQualityFeign {
+
+    /**
+     * 空气质量
+     *
+     * @param key       和风天气密钥
+     * @param lang      多语言设置,请阅读多语言文档,了解我们的多语言是如何工作、如何设置以及数据是否支持多语言。
+     * @param current   current:实时, hourly: 每小时, daily: 每日
+     * @param longitude (必选)所需位置的经度。十进制,最多支持小数点后两位。例如 116.41
+     * @param latitude  (必选)所需位置的纬度。十进制,最多支持小数点后两位。例如 39.92
+     * @return https://dev.qweather.com/docs/api/air-quality/
+     */
+    @GetMapping(value = "/{current}/{latitude}/{longitude}")
+    JSONObject airQuality(
+            @RequestParam(value = "key") String key,
+            @RequestParam(value = "lang") String lang,
+            @PathVariable(value = "current") String current,
+            @PathVariable(value = "longitude") String longitude,
+            @PathVariable(value = "latitude") String latitude
+    );
+
+
+}

+ 44 - 0
alien-api/src/main/java/shop/alien/api/feign/QWeatherGeoFeign.java

@@ -0,0 +1,44 @@
+package shop.alien.api.feign;
+
+import com.alibaba.fastjson.JSONObject;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * 和风GeoAPI
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2025/3/17 13:17
+ */
+@FeignClient(url = "https://geoapi.qweather.com/v2", name = "heFengGeoApi")
+public interface QWeatherGeoFeign {
+
+    /**
+     * 城市搜索
+     *
+     * @param key      和风天气密钥
+     * @param location 需要查询地区的名称,支持文字、以英文逗号分隔的经度,纬度坐标(十进制,最多支持小数点后两位)、LocationID或Adcode(仅限中国城市)。例如 location=北京 或 location=116.41,39.92
+     * @return code 请参考状态码
+     * location.name 地区/城市名称
+     * location.id 地区/城市ID
+     * location.lat 地区/城市纬度
+     * location.lon 地区/城市经度
+     * location.adm2 地区/城市的上级行政区划名称
+     * location.adm1 地区/城市所属一级行政区域
+     * location.country 地区/城市所属国家名称
+     * location.tz 地区/城市所在时区
+     * location.utcOffset 地区/城市目前与UTC时间偏移的小时数,参考详细说明
+     * location.isDst 地区/城市是否当前处于夏令时。1 表示当前处于夏令时,0 表示当前不是夏令时。
+     * location.type 地区/城市的属性
+     * location.rank 地区评分
+     * location.fxLink 该地区的天气预报网页链接,便于嵌入你的网站或应用
+     * refer.sources 原始数据来源,或数据源说明,可能为空
+     * refer.license 数据许可或版权声明,可能为空
+     */
+    @GetMapping(value = "/city/lookup")
+    JSONObject cityLookup(@RequestParam(value = "key") String key, @RequestParam(value = "location") String location);
+
+
+}

+ 202 - 0
alien-api/src/main/java/shop/alien/api/feign/QWeatherWeatherFeign.java

@@ -0,0 +1,202 @@
+package shop.alien.api.feign;
+
+import com.alibaba.fastjson.JSONObject;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * 和风城市天气
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2025/3/19 13:18
+ */
+@FeignClient(url = "https://devapi.qweather.com/v7", name = "heFengWeather")
+public interface QWeatherWeatherFeign {
+
+    /**
+     * 实时天气
+     *
+     * @param key      和风天气密钥
+     * @param location (必选)需要查询地区的LocationID或以英文逗号分隔的经度,纬度坐标(十进制,最多支持小数点后两位),LocationID可通过GeoAPI获取。例如 location=101010100 或 location=116.41,39.92
+     * @param lang     多语言设置,请阅读多语言文档,了解我们的多语言是如何工作、如何设置以及数据是否支持多语言。
+     * @param unit     数据单位设置,可选值包括unit=m(公制单位,默认)和unit=i(英制单位)。更多选项和说明参考度量衡单位。
+     * @return code 请参考状态码
+     * updateTime 当前API的最近更新时间
+     * fxLink 当前数据的响应式页面,便于嵌入网站或应用
+     * now.obsTime 数据观测时间
+     * now.temp 温度,默认单位:摄氏度
+     * now.feelsLike 体感温度,默认单位:摄氏度
+     * now.icon 天气状况的图标代码,另请参考天气图标项目
+     * now.text 天气状况的文字描述,包括阴晴雨雪等天气状态的描述
+     * now.wind360 风向360角度
+     * now.windDir 风向
+     * now.windScale 风力等级
+     * now.windSpeed 风速,公里/小时
+     * now.humidity 相对湿度,百分比数值
+     * now.precip 过去1小时降水量,默认单位:毫米
+     * now.pressure 大气压强,默认单位:百帕
+     * now.vis 能见度,默认单位:公里
+     * now.cloud 云量,百分比数值。可能为空
+     * now.dew 露点温度。可能为空
+     * refer.sources 原始数据来源,或数据源说明,可能为空
+     * refer.license 数据许可或版权声明,可能为空
+     */
+    @GetMapping(value = "/weather/now")
+    JSONObject weatherNow(
+            @RequestParam(value = "key") String key,
+            @RequestParam(value = "location") String location,
+            @RequestParam(value = "lang") String lang,
+            @RequestParam(value = "unit") String unit
+    );
+
+    /**
+     * 每日天气预报
+     *
+     * @param key      和风天气密钥
+     * @param location (必选)需要查询地区的LocationID或以英文逗号分隔的经度,纬度坐标(十进制,最多支持小数点后两位),LocationID可通过GeoAPI获取。例如 location=101010100 或 location=116.41,39.92
+     * @param lang     多语言设置,请阅读多语言文档,了解我们的多语言是如何工作、如何设置以及数据是否支持多语言。
+     * @param unit     数据单位设置,可选值包括unit=m(公制单位,默认)和unit=i(英制单位)。更多选项和说明参考度量衡单位。
+     * @param days     3d/7d/10d/15d/30d
+     * @return code 请参考状态码
+     * updateTime 当前API的最近更新时间
+     * fxLink 当前数据的响应式页面,便于嵌入网站或应用
+     * daily.fxDate 预报日期
+     * daily.sunrise 日出时间,在高纬度地区可能为空
+     * daily.sunset 日落时间,在高纬度地区可能为空
+     * daily.moonrise 当天月升时间,可能为空
+     * daily.moonset 当天月落时间,可能为空
+     * daily.moonPhase 月相名称
+     * daily.moonPhaseIcon 月相图标代码,另请参考天气图标项目
+     * daily.tempMax 预报当天最高温度
+     * daily.tempMin 预报当天最低温度
+     * daily.iconDay 预报白天天气状况的图标代码,另请参考天气图标项目
+     * daily.textDay 预报白天天气状况文字描述,包括阴晴雨雪等天气状态的描述
+     * daily.iconNight 预报夜间天气状况的图标代码,另请参考天气图标项目
+     * daily.textNight 预报晚间天气状况文字描述,包括阴晴雨雪等天气状态的描述
+     * daily.wind360Day 预报白天风向360角度
+     * daily.windDirDay 预报白天风向
+     * daily.windScaleDay 预报白天风力等级
+     * daily.windSpeedDay 预报白天风速,公里/小时
+     * daily.wind360Night 预报夜间风向360角度
+     * daily.windDirNight 预报夜间当天风向
+     * daily.windScaleNight 预报夜间风力等级
+     * daily.windSpeedNight 预报夜间风速,公里/小时
+     * daily.precip 预报当天总降水量,默认单位:毫米
+     * daily.uvIndex 紫外线强度指数
+     * daily.humidity 相对湿度,百分比数值
+     * daily.pressure 大气压强,默认单位:百帕
+     * daily.vis 能见度,默认单位:公里
+     * daily.cloud 云量,百分比数值。可能为空
+     * refer.sources 原始数据来源,或数据源说明,可能为空
+     * refer.license 数据许可或版权声明,可能为空
+     */
+    @GetMapping(value = "/weather/{days}")
+    JSONObject weatherFutureDays(
+            @RequestParam(value = "key") String key,
+            @RequestParam(value = "location") String location,
+            @RequestParam(value = "lang") String lang,
+            @RequestParam(value = "unit") String unit,
+            @PathVariable(value = "days") String days);
+
+    /**
+     * 逐小时天气预报
+     *
+     * @param key      和风天气密钥
+     * @param location (必选)需要查询地区的LocationID或以英文逗号分隔的经度,纬度坐标(十进制,最多支持小数点后两位),LocationID可通过GeoAPI获取。例如 location=101010100 或 location=116.41,39.92
+     * @param lang     多语言设置,请阅读多语言文档,了解我们的多语言是如何工作、如何设置以及数据是否支持多语言。
+     * @param unit     数据单位设置,可选值包括unit=m(公制单位,默认)和unit=i(英制单位)。更多选项和说明参考度量衡单位。
+     * @param hour     24h/72/168h
+     * @return code 请参考状态码
+     * updateTime 当前API的最近更新时间
+     * fxLink 当前数据的响应式页面,便于嵌入网站或应用
+     * hourly.fxTime 预报时间
+     * hourly.temp 温度,默认单位:摄氏度
+     * hourly.icon 天气状况的图标代码,另请参考天气图标项目
+     * hourly.text 天气状况的文字描述,包括阴晴雨雪等天气状态的描述
+     * hourly.wind360 风向360角度
+     * hourly.windDir 风向
+     * hourly.windScale 风力等级
+     * hourly.windSpeed 风速,公里/小时
+     * hourly.humidity 相对湿度,百分比数值
+     * hourly.precip 当前小时累计降水量,默认单位:毫米
+     * hourly.pop 逐小时预报降水概率,百分比数值,可能为空
+     * hourly.pressure 大气压强,默认单位:百帕
+     * hourly.cloud 云量,百分比数值。可能为空
+     * hourly.dew 露点温度。可能为空
+     * refer.sources 原始数据来源,或数据源说明,可能为空
+     * refer.license 数据许可或版权声明,可能为空
+     */
+    @GetMapping(value = "/weather/{hour}")
+    JSONObject weatherFutureHour(
+            @RequestParam(value = "key") String key,
+            @RequestParam(value = "location") String location,
+            @RequestParam(value = "lang") String lang,
+            @RequestParam(value = "unit") String unit,
+            @PathVariable(value = "hour") String hour);
+
+    /**
+     * 天气灾害预警
+     *
+     * @param key      和风天气密钥
+     * @param location (必选)需要查询地区的LocationID或以英文逗号分隔的经度,纬度坐标(十进制,最多支持小数点后两位),LocationID可通过GeoAPI获取。例如 location=101010100 或 location=116.41,39.92
+     * @param lang     多语言设置,请阅读多语言文档,了解我们的多语言是如何工作、如何设置以及数据是否支持多语言。
+     * @return code 请参考状态码
+     * updateTime 当前API的最近更新时间
+     * fxLink 当前数据的响应式页面,便于嵌入网站或应用
+     * warning.id 本条预警的唯一标识,可判断本条预警是否已经存在
+     * warning.sender 预警发布单位,可能为空
+     * warning.pubTime 预警发布时间
+     * warning.title 预警信息标题
+     * warning.startTime 预警开始时间,可能为空
+     * warning.endTime 预警结束时间,可能为空
+     * warning.status 预警信息的发布状态
+     * warning.level 预警等级(已弃用),不要再使用这个字段,该字段已弃用,目前返回为空或未更新的值。请使用severity和severityColor代替
+     * warning.severity 预警严重等级
+     * warning.severityColor 预警严重等级颜色,可能为空
+     * warning.type 预警类型ID
+     * warning.typeName 预警类型名称
+     * warning.urgency 预警信息的紧迫程度,可能为空
+     * warning.certainty 预警信息的确定性,可能为空
+     * warning.text 预警详细文字描述
+     * warning.related 与本条预警相关联的预警ID,当预警状态为cancel或update时返回。可能为空
+     * refer.sources 原始数据来源,或数据源说明,可能为空
+     * refer.license 数据许可或版权声明,可能为空
+     */
+    @GetMapping(value = "/warning/now")
+    JSONObject weatherWarningNow(
+            @RequestParam(value = "key") String key,
+            @RequestParam(value = "location") String location,
+            @RequestParam(value = "lang") String lang);
+
+    /**
+     * 天气指数预报
+     *
+     * @param key      和风天气密钥
+     * @param location (必选)需要查询地区的LocationID或以英文逗号分隔的经度,纬度坐标(十进制,最多支持小数点后两位),LocationID可通过GeoAPI获取。例如 location=101010100 或 location=116.41,39.92
+     * @param type     (必选)生活指数的类型ID,包括洗车指数、穿衣指数、钓鱼指数等。可以一次性获取多个类型的生活指数,多个类型用英文,分割。例如type=3,5。具体生活指数的ID和等级参考天气指数信息。各项生活指数并非适用于所有城市。
+     * @param lang     多语言设置,请阅读多语言文档,了解我们的多语言是如何工作、如何设置以及数据是否支持多语言。
+     * @param days     1d/3d
+     * @return code 请参考状态码
+     * updateTime 当前API的最近更新时间
+     * fxLink 当前数据的响应式页面,便于嵌入网站或应用
+     * daily.date 预报日期
+     * daily.type 生活指数类型ID
+     * daily.name 生活指数类型的名称
+     * daily.level 生活指数预报等级
+     * daily.category 生活指数预报级别名称
+     * daily.text 生活指数预报的详细描述,可能为空
+     * refer.sources 原始数据来源,或数据源说明,可能为空
+     * refer.license 数据许可或版权声明,可能为空
+     */
+    @GetMapping(value = "/indices/{days}")
+    JSONObject weatherIndices(
+            @RequestParam(value = "key") String key,
+            @RequestParam(value = "location") String location,
+            @RequestParam(value = "type") Integer type,
+            @RequestParam(value = "lang") String lang,
+            @PathVariable(value = "days") String days);
+
+}

+ 399 - 0
alien-api/src/main/java/shop/alien/api/feign/RollFeign.java

@@ -0,0 +1,399 @@
+package shop.alien.api.feign;
+
+import com.alibaba.fastjson.JSONObject;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * 调用Roll接口
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/10/24 15:04
+ */
+@FeignClient(url = "https://www.mxnzp.com/api", name = "roll")
+public interface RollFeign {
+
+    /**
+     * 全国城市列表
+     * https://www.mxnzp.com/doc/detail?id=8
+     *
+     * @param appId     id
+     * @param appSecret secret
+     * @return JSONObject
+     */
+    @GetMapping("/address/list")
+    JSONObject addressList(@RequestParam(value = "app_id") String appId,
+                           @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 搜索全国城市列表
+     * https://www.mxnzp.com/doc/detail?id=8
+     *
+     * @param type      类型 0-查询省份 1-查询城市
+     * @param value     被查询的省份或者城市名称
+     * @param appId     id
+     * @param appSecret secret
+     * @return JSONObject
+     */
+    @GetMapping("/address/search")
+    JSONObject addressSearch(@RequestParam(value = "type") String type,
+                             @RequestParam(value = "value") String value,
+                             @RequestParam(value = "app_id") String appId,
+                             @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 每日推荐精美语句
+     * https://www.mxnzp.com/doc/detail?id=25
+     *
+     * @param count     被查询的语句条数,范围【1~20】
+     * @param appId     id
+     * @param appSecret secret
+     * @return JSONObject
+     */
+    @GetMapping("/daily_word/recommend")
+    JSONObject dailyWord(@RequestParam(value = "count") Integer count,
+                         @RequestParam(value = "app_id") String appId,
+                         @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 获取食物的分类列表
+     * https://www.mxnzp.com/doc/detail?id=32
+     *
+     * @param appId     id
+     * @param appSecret secret
+     * @return JSONObject
+     */
+    @GetMapping("/food_heat/type/list")
+    JSONObject foodHeatTypeList(@RequestParam(value = "app_id") String appId,
+                                @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 获取分类下的食物列表
+     * https://www.mxnzp.com/doc/detail?id=32
+     *
+     * @param id        分类id
+     * @param page      分页页数
+     * @param appId     id
+     * @param appSecret secret
+     * @return JSONObject
+     */
+    @GetMapping("/food_heat/food/list")
+    JSONObject foodHeatFoodList(@RequestParam(value = "id") String id,
+                                @RequestParam(value = "page") Integer page,
+                                @RequestParam(value = "app_id") String appId,
+                                @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 搜索食物
+     * https://www.mxnzp.com/doc/detail?id=32
+     *
+     * @param keyword   搜索关键字
+     * @param page      分页页数
+     * @param appId     id
+     * @param appSecret secret
+     * @return JSONObject
+     */
+    @GetMapping("/food_heat/food/search")
+    JSONObject foodHeatSearch(@RequestParam(value = "keyword") String keyword,
+                              @RequestParam(value = "page") Integer page,
+                              @RequestParam(value = "app_id") String appId,
+                              @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 获取食物详情
+     * https://www.mxnzp.com/doc/detail?id=32
+     *
+     * @param foodId    食物id
+     * @param appId     id
+     * @param appSecret secret
+     * @return JSONObject
+     */
+    @GetMapping("/food_heat/food/details")
+    JSONObject foodHeatDetail(@RequestParam(value = "foodId") String foodId,
+                              @RequestParam(value = "app_id") String appId,
+                              @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 获取历史上的今天数据
+     * https://www.mxnzp.com/doc/detail?id=18
+     *
+     * @param type      是否需要详情,0:不需要详情 1:需要详情 默认值 0 可不传
+     * @param appId     id
+     * @param appSecret secret
+     * @return JSONObject
+     */
+    @GetMapping("/history/today")
+    JSONObject historyToday(@RequestParam(value = "type") Integer type,
+                            @RequestParam(value = "app_id") String appId,
+                            @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 获取指定日期的节假日及万年历信息
+     * https://www.mxnzp.com/doc/detail?id=1
+     *
+     * @param date          日期 格式 yyyyMMdd
+     * @param ignoreHoliday 是否忽略节假日,仅仅获取万年历,默认值false
+     * @param appId         id
+     * @param appSecret     secret
+     * @return JSONObject
+     */
+    @GetMapping("/holiday/single/{date}")
+    JSONObject holidaySingle(@PathVariable(value = "date") String date,
+                             @RequestParam(value = "ignoreHoliday") boolean ignoreHoliday,
+                             @RequestParam(value = "app_id") String appId,
+                             @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 获取指定多个日期的节假日及万年历信息
+     * https://www.mxnzp.com/doc/detail?id=1
+     *
+     * @param dates         日期组 格式 yyyyMMdd,yyyyMMdd,yyyyMMdd (中间用英文逗号隔开)
+     * @param ignoreHoliday 是否忽略节假日,仅仅获取万年历,默认值false
+     * @param appId         id
+     * @param appSecret     secret
+     * @return JSONObject
+     */
+    @GetMapping("/holiday/multi/{dates}")
+    JSONObject holidayMulti(@PathVariable(value = "dates") String dates,
+                            @RequestParam(value = "ignoreHoliday") boolean ignoreHoliday,
+                            @RequestParam(value = "app_id") String appId,
+                            @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 获取指定月份的节假日及万年历信息
+     * https://www.mxnzp.com/doc/detail?id=1
+     *
+     * @param date          查询的月份 格式 yyyyMM (只有年月)
+     * @param ignoreHoliday 是否忽略节假日,仅仅获取万年历,默认值false
+     * @param appId         id
+     * @param appSecret     secret
+     * @return JSONObject
+     */
+    @GetMapping("/holiday/list/month/{date}")
+    JSONObject holidayListMonth(@PathVariable(value = "date") String date,
+                                @RequestParam(value = "ignoreHoliday") boolean ignoreHoliday,
+                                @RequestParam(value = "app_id") String appId,
+                                @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 获取指定月份的指定类型节假日及万年历信息
+     * https://www.mxnzp.com/doc/detail?id=1
+     *
+     * @param date          查询的月份 格式 yyyyMM (只有年月)
+     * @param type          需要查询的类型{可选值:类型 workday 工作日 holiday 节假日 rest 休息日 festival 节日
+     * @param ignoreHoliday 是否忽略节假日,仅仅获取万年历,默认值false
+     * @param appId         id
+     * @param appSecret     secret
+     * @return JSONObject
+     */
+    @GetMapping("/holiday/list/month/{date}/{type}")
+    JSONObject holidayListMonthType(@PathVariable(value = "date") String date,
+                                    @PathVariable(value = "type") String type,
+                                    @RequestParam(value = "ignoreHoliday") boolean ignoreHoliday,
+                                    @RequestParam(value = "app_id") String appId,
+                                    @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 获取指定年份的节假日及万年历信息
+     * https://www.mxnzp.com/doc/detail?id=1
+     *
+     * @param date          查询的年份 格式 yyyy (只有年份)
+     * @param ignoreHoliday 是否忽略节假日,仅仅获取万年历,默认值false
+     * @param appId         id
+     * @param appSecret     secret
+     * @return JSONObject
+     */
+    @GetMapping("/holiday/list/year/{date}")
+    JSONObject holidayListYear(@PathVariable(value = "date") String date,
+                               @RequestParam(value = "ignoreHoliday") boolean ignoreHoliday,
+                               @RequestParam(value = "app_id") String appId,
+                               @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 获取指定年份的指定类型节假日及万年历信息
+     * https://www.mxnzp.com/doc/detail?id=1
+     *
+     * @param date          查询的月份 格式 yyyy (只有年份)
+     * @param type          需要查询的类型{可选值:类型 workday 工作日 holiday 节假日 rest 休息日 festival 节日
+     * @param ignoreHoliday 是否忽略节假日,仅仅获取万年历,默认值false
+     * @param appId         id
+     * @param appSecret     secret
+     * @return JSONObject
+     */
+    @GetMapping("/holiday/list/year/{date}/{type}")
+    JSONObject holidayListYearType(@PathVariable(value = "date") String date,
+                                   @PathVariable(value = "type") String type,
+                                   @RequestParam(value = "ignoreHoliday") boolean ignoreHoliday,
+                                   @RequestParam(value = "app_id") String appId,
+                                   @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 获取最近前后七个节日信息
+     * https://www.mxnzp.com/doc/detail?id=1
+     *
+     * @param appId     id
+     * @param appSecret secret
+     * @return JSONObject
+     */
+    @GetMapping("/holiday/recent/list")
+    JSONObject holidayRecentList(@RequestParam(value = "app_id") String appId,
+                                 @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 分页获取笑话段子列表
+     * https://www.mxnzp.com/doc/detail?id=5
+     *
+     * @param page      分页
+     * @param appId     id
+     * @param appSecret secret
+     * @return JSONObject
+     */
+    @GetMapping("/jokes/list")
+    JSONObject jokesList(@RequestParam(value = "page") Integer page,
+                         @RequestParam(value = "app_id") String appId,
+                         @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 随机获取笑话段子列表
+     * https://www.mxnzp.com/doc/detail?id=5
+     *
+     * @param appId     id
+     * @param appSecret secret
+     * @return JSONObject
+     */
+    @GetMapping("/jokes/list/random")
+    JSONObject jokesListRandom(@RequestParam(value = "app_id") String appId,
+                               @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 获取所有新闻类型列表
+     * https://www.mxnzp.com/doc/detail?id=12
+     *
+     * @param appId     id
+     * @param appSecret secret
+     * @return JSONObject
+     */
+    @GetMapping("/news/types/v2")
+    JSONObject newsTypes(@RequestParam(value = "app_id") String appId,
+                         @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 根据新闻类型获取新闻列表
+     * https://www.mxnzp.com/doc/detail?id=1
+     *
+     * @param typeId    类型id,从上面的V2新闻类型列表中获取
+     * @param page      当前页数
+     * @param appId     id
+     * @param appSecret secret
+     * @return JSONObject
+     */
+    @GetMapping("/news/list/v2")
+    JSONObject newsList(@RequestParam(value = "typeId") String typeId,
+                        @RequestParam(value = "page") String page,
+                        @RequestParam(value = "app_id") String appId,
+                        @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 根据新闻id获取新闻详情
+     * https://www.mxnzp.com/doc/detail?id=5
+     *
+     * @param newsId    新闻唯一id,从上面的V2新闻列表中获取
+     * @param appId     id
+     * @param appSecret secret
+     * @return JSONObject
+     */
+    @GetMapping("/news/details/v2")
+    JSONObject newsDetails(@RequestParam(value = "newsId") String newsId,
+                           @RequestParam(value = "app_id") String appId,
+                           @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 获取访问者的ip地址信息
+     * https://www.mxnzp.com/doc/detail?id=4
+     *
+     * @param appId     id
+     * @param appSecret secret
+     * @return JSONObject
+     */
+    @GetMapping("/ip/self")
+    JSONObject ipSelf(@RequestParam(value = "app_id") String appId,
+                      @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 获取指定ip的ip地址信息
+     * https://www.mxnzp.com/doc/detail?id=4
+     *
+     * @param ip        被查询的ip地址 需保证是正确的ip地址格式
+     * @param appId     id
+     * @param appSecret secret
+     * @return JSONObject
+     */
+    @GetMapping("/ip/aim_ip")
+    JSONObject ipAimIp(@RequestParam(value = "ip") String ip,
+                       @RequestParam(value = "app_id") String appId,
+                       @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 生成随机图片验证码
+     * https://www.mxnzp.com/doc/detail?id=24
+     *
+     * @param len       生成验证码的长度,不传默认5位
+     * @param type      返回类型,0-生成图片的地址链接 1-生成验证码图片的base64字符串(注:Base64字符串前面默认添加了“data:image/jpg;base64,”,取值的时候请根据需要对这个内容进行处理)
+     * @param appId     id
+     * @param appSecret secret
+     * @return JSONObject
+     */
+    @GetMapping("/verifycode/code")
+    JSONObject verifyCode(@RequestParam(value = "len") Integer len,
+                          @RequestParam(value = "type") Integer type,
+                          @RequestParam(value = "app_id") String appId,
+                          @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 获取特定城市今日天气
+     * https://www.mxnzp.com/doc/detail?id=7
+     *
+     * @param city      传入你需要查询的城市,请尽量传入完整值,否则系统会自行匹配,可能会有误差
+     * @param appId     id
+     * @param appSecret secret
+     * @return JSONObject
+     */
+    @GetMapping("/weather/current/{city}")
+    JSONObject weatherCurrent(@PathVariable(value = "city") String city,
+                              @RequestParam(value = "app_id") String appId,
+                              @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 获取特定城市今天及未来天气
+     * https://www.mxnzp.com/doc/detail?id=7
+     *
+     * @param city      传入你需要查询的城市,请尽量传入完整值,否则系统会自行匹配,可能会有误差
+     * @param appId     id
+     * @param appSecret secret
+     * @return JSONObject
+     */
+    @GetMapping("/weather/forecast/{city}")
+    JSONObject weatherForecast(@PathVariable(value = "city") String city,
+                               @RequestParam(value = "app_id") String appId,
+                               @RequestParam(value = "app_secret") String appSecret);
+
+    /**
+     * 今日油价查询
+     * https://www.mxnzp.com/doc/detail?id=34
+     *
+     * @param province  省份,合法值为:【安徽、北京、重庆、福建、甘肃、广东、广西、贵州、海南、河北、黑龙江、河南、湖北、湖南、江苏、江西、吉林、辽宁、内蒙古、宁夏、青海、陕西、上海、山东、山西、四川、天津、西藏、新疆、云南、浙江】
+     * @param appId     id
+     * @param appSecret secret
+     * @return JSONObject
+     */
+    @GetMapping("/oil/search")
+    JSONObject oilSearch(@RequestParam(value = "province") String province,
+                         @RequestParam(value = "app_id") String appId,
+                         @RequestParam(value = "app_secret") String appSecret);
+}
+
+
+

+ 32 - 0
alien-api/src/main/java/shop/alien/api/feign/TencentMapFeign.java

@@ -0,0 +1,32 @@
+package shop.alien.api.feign;
+
+import com.alibaba.fastjson.JSONObject;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * 调用腾讯地图
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/10/25 13:49
+ */
+@FeignClient(url = "https://apis.map.qq.com", name = "tencentMap")
+public interface TencentMapFeign {
+
+    /**
+     * 腾讯
+     * 逆地理编码获取详细地址
+     * 每日配额10000,并发每秒5
+     * https://apis.map.qq.com/ws/geocoder/v1/
+     *
+     * @param location 经纬度
+     * @param key      key
+     * @return JSONObject
+     */
+    @GetMapping("/ws/geocoder/v1")
+    JSONObject getLocationInfo(@RequestParam(value = "location") String location,
+                               @RequestParam(value = "key") String key);
+
+}

+ 20 - 0
alien-api/src/main/java/shop/alien/api/feign/TimeOutFeign.java

@@ -0,0 +1,20 @@
+package shop.alien.api.feign;
+
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * 请求超时测试
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/10/24 10:19
+ */
+@FeignClient(url = "http://localhost:8008", name = "timeOut")
+public interface TimeOutFeign {
+
+    @GetMapping("/timeout/timeout")
+    String timeout(@RequestParam(value = "timeout") Long timeout);
+
+}

+ 97 - 0
alien-api/src/main/java/shop/alien/api/feign/WawaFeign.java

@@ -0,0 +1,97 @@
+package shop.alien.api.feign;
+
+import com.alibaba.fastjson.JSONObject;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestHeader;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * 蛙蛙工具Feign
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/11/28 15:52
+ */
+@FeignClient(url = "https://www.iamwawa.cn", name = "wawa")
+public interface WawaFeign {
+
+    /**
+     * 蛙蛙工具
+     * 一句诗词
+     * https://www.iamwawa.cn/shici.html
+     *
+     * @param userAgent ua信息
+     * @return JSONObject
+     */
+    @GetMapping("/home/shici/ajax")
+    JSONObject shiCi(@RequestHeader(name = "User-Agent") String userAgent);
+
+    /**
+     * 蛙蛙工具
+     * 励志句子
+     * https://www.iamwawa.cn/lizhi.html
+     *
+     * @param userAgent ua信息
+     * @return JSONObject
+     */
+    @GetMapping("/home/lizhi/ajax")
+    JSONObject liZhi(@RequestHeader(name = "User-Agent") String userAgent);
+
+    /**
+     * 蛙蛙工具
+     * 毒鸡汤
+     * https://www.iamwawa.cn/dujitang.html
+     *
+     * @param userAgent ua信息
+     * @return JSONObject
+     */
+    @GetMapping("/home/dujitang/ajax_test")
+    JSONObject jiTang(@RequestHeader(name = "User-Agent") String userAgent);
+
+    /**
+     * 蛙蛙工具
+     * 农历公历转换器
+     * 每分钟限请求10次
+     * https://www.iamwawa.cn/nongli.html
+     *
+     * @param userAgent ua信息
+     * @param type      solar/lunar,发送的日期是公历还是农历
+     * @param year      年
+     * @param month     月
+     * @param day       日
+     * @return JSONObject
+     */
+    @GetMapping("/nongli/api")
+    JSONObject nongLi(@RequestHeader(name = "User-Agent") String userAgent,
+                      @RequestParam(value = "type") String type,
+                      @RequestParam(value = "year") Integer year,
+                      @RequestParam(value = "month") Integer month,
+                      @RequestParam(value = "day") Integer day);
+
+    /**
+     * 蛙蛙工具
+     * 放假调休安排
+     * https://www.iamwawa.cn/holiday.html
+     *
+     * @param userAgent ua信息
+     * @return JSONObject
+     */
+    @GetMapping("/holiday/api")
+    JSONObject holiday(@RequestHeader(name = "User-Agent") String userAgent);
+
+    /**
+     * 蛙蛙工具
+     * 油价查询API接口
+     * 每分钟限请求10次
+     * https://www.iamwawa.cn/oilprice.html
+     *
+     * @param userAgent ua信息
+     * @param area      支持地区:北京,上海,江苏,天津,重庆,江西,辽宁,安徽,内蒙古,福建,宁夏,甘肃,青海,广东,山东,广西,山西,贵州,陕西,海南,四川,河北,西藏,河南,新疆,黑龙江,吉林,云南,湖北,浙江,湖南
+     * @return JSONObject
+     */
+    @GetMapping("/oilprice/api")
+    JSONObject oilPrice(@RequestHeader(name = "User-Agent") String userAgent,
+                        @RequestParam(value = "area") String area);
+
+}

+ 28 - 0
alien-api/src/main/java/shop/alien/api/feign/WeatherBureauFeign.java

@@ -0,0 +1,28 @@
+package shop.alien.api.feign;
+
+import com.alibaba.fastjson.JSONObject;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+
+/**
+ * 调用气象局接口
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/10/25 10:56
+ */
+@FeignClient(url = "https://weather.cma.cn/api", name = "weatherBureau")
+public interface WeatherBureauFeign {
+
+    /**
+     * 中国气象局-气象预警
+     * https://weather.cma.cn/web/alarm/map.html
+     *
+     * @param adcode 区域code,省市code前两位
+     * @return JSONObject
+     */
+    @GetMapping("/map/alarm")
+    JSONObject weatherAlarm(@RequestParam(value = "adcode") String adcode);
+
+}

+ 11 - 0
alien-api/src/main/resources/banner.txt

@@ -0,0 +1,11 @@
+${AnsiColor.BLUE}
+${AnsiStyle.BOLD}
+       _             _          _ _                                   _
+      (_)           | |        (_) |                                 (_)
+ __  ___  __ _  ___ | | ___   _ _| |__  _   _  __ _ ______ __ _ _ __  _
+ \ \/ / |/ _` |/ _ \| |/ / | | | | '_ \| | | |/ _` |______/ _` | '_ \| |
+  >  <| | (_| | (_) |   <| |_| | | | | | |_| | (_| |     | (_| | |_) | |
+ /_/\_\_|\__,_|\___/|_|\_\\__,_|_|_| |_|\__,_|\__,_|      \__,_| .__/|_|
+                                                               | |
+                                                               |_|
+1.0.0--小葵花

+ 30 - 0
alien-api/src/main/resources/bootstrap.yml

@@ -0,0 +1,30 @@
+spring:
+  application:
+    name: xiaokuihua-api
+
+  cloud:
+    nacos:
+      #注册中心
+      discovery:
+        server-addr: localhost:8848
+#        server-addr: xiaokuihua.cc:8848
+        username: nacos
+        password: .,ZyL021405
+
+      #配置中心
+      config:
+
+        enabled: true
+        server-addr: localhost:8848
+#        server-addr: xiaokuihua.cc:8848
+        username: nacos
+        password: .,ZyL021405
+        group: DEFAULT_GROUP
+        file-extension: yml
+        #命名空间
+#        namespace: test
+#        #多配置,数越大优先级越高
+#        shared-configs[0]:
+#          data-id: test.yml
+#          group: DEFAULT_GROUP
+#          refresh: true

+ 173 - 0
alien-api/src/main/resources/logback-spring.xml

@@ -0,0 +1,173 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- 日志级别从低到高分为TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果设置为WARN,则低于WARN的信息都不会输出 -->
+<!-- scan:当此属性设置为true时,配置文档如果发生改变,将会被重新加载,默认值为true -->
+<!-- scanPeriod:设置监测配置文档是否有修改的时间间隔,如果没有给出时间单位,默认单位是毫秒。当scan为true时,此属性生效。默认的时间间隔为1分钟。 -->
+<!-- debug:当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。 -->
+<!-- 该信息是由于设置了当配置文件变化时重新加载,所以每当达到扫描时间的时候就会检查配置文件是否错误。但是由于一般配置文件都放在了JAR包中,
+    而扫描的时候无法扫描JAR包内,因此会提示没有可以检查的文件,所以每隔一段时间就输出一次-->
+<configuration scan="false" scanPeriod="60 seconds" debug="true">
+    <contextName>logback-spring</contextName>
+
+    <!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义后,可以使“${}”来使用变量。 -->
+    <!-- 定义全局参数常量 -->
+    <property name="log.level" value="debug"/>
+    <property name="log.maxHistory" value="30"/><!-- 30表示30个 -->
+    <property name="logging.path" value="/javaLog/apiLog"/>
+    <!--输出文件前缀-->
+    <property name="FILENAME" value="xiaokuihua_api"/>
+
+    <!--0. 日志格式和颜色渲染 -->
+    <!-- 彩色日志依赖的渲染类 -->
+    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
+    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/>
+    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/>
+
+    <!-- 文件输出格式 -->
+    <property name="FILE_LOG_PATTERN" value="[%d{MM/dd HH:mm:ss.SSS}][%-10.10thread][%-5level][%-40.40c{1}:%5line]:[%15method] || %m%n"/>
+    <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
+
+    <!--1. 输出到控制台-->
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+        <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->
+        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+            <level>${log.level}</level>
+        </filter>
+        <encoder>
+            <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
+            <!-- 设置字符集 -->
+            <charset>UTF-8</charset>
+        </encoder>
+    </appender>
+
+    <!--2. 输出到文档-->
+    <!-- DEBUG 日志 -->
+    <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <!-- 当前的日志文件存放路径 -->
+        <file>${logging.path}/DEBUG.log</file>
+        <!-- 日志滚动策略 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 历史日志文件的存放路径和名称 -->
+            <fileNamePattern>${logging.path}/%d{yyyy-MM-dd}_${FILENAME}_DEBUG.log.gz</fileNamePattern>
+            <!-- 日志文件最大的保存历史 数量-->
+            <maxHistory>${log.maxHistory}</maxHistory>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
+            <pattern>${FILE_LOG_PATTERN}</pattern>
+        </encoder>
+        <!--日志文件最大的大小-->
+        <!--        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">-->
+        <!--            <MaxFileSize>10MB</MaxFileSize>-->
+        <!--        </triggeringPolicy>-->
+        <!-- 此日志文档只记录debug级别的 -->
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>DEBUG</level>
+            <onMatch>ACCEPT</onMatch>  <!-- 用过滤器,只接受DEBUG级别的日志信息,其余全部过滤掉 -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- INFO 日志 -->
+    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${logging.path}/INFO.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>${logging.path}/%d{yyyy-MM-dd}_${FILENAME}_INFO.log.gz</fileNamePattern>
+            <maxHistory>${log.maxHistory}</maxHistory>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <pattern>${FILE_LOG_PATTERN}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>INFO</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- WARN 日志 -->
+    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${logging.path}/WARN.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>${logging.path}/%d{yyyy-MM-dd}_${FILENAME}_WARN.log.gz</fileNamePattern>
+            <maxHistory>${log.maxHistory}</maxHistory>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <pattern>${FILE_LOG_PATTERN}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>WARN</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
+        <file>${logging.path}/ERROR.log</file>
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <fileNamePattern>${logging.path}/%d{yyyy-MM-dd}_${FILENAME}_ERROR.log.gz</fileNamePattern>
+            <maxHistory>${log.maxHistory}</maxHistory>
+        </rollingPolicy>
+        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
+            <pattern>${FILE_LOG_PATTERN}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <level>ERROR</level>
+            <onMatch>ACCEPT</onMatch>
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!--
+      <logger>用来设置某一个包或者具体的某一个类的日志打印级别、
+      以及指定<appender>。<logger>仅有一个name属性,
+      一个可选的level和一个可选的addtivity属性。
+      name:用来指定受此logger约束的某一个包或者具体的某一个类。
+      level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
+         还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。
+         如果未设置此属性,那么当前logger将会继承上级的级别。
+      addtivity:是否向上级logger传递打印信息。默认是true。
+      <logger name="org.springframework.web" level="info"/>
+      <logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>
+    -->
+
+    <!--
+      使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作:
+      第一种把<root level="info">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息
+      第二种就是单独给dao下目录配置debug模式,代码如下,这样配置sql语句会打印,其他还是正常info级别:
+      【logging.level.org.mybatis=debug logging.level.dao=debug】
+     -->
+    <!-- mybatis显示sql,修改此处扫描包名 -->
+
+
+    <!--
+      root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性
+      level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,
+      不能设置为INHERITED或者同义词NULL。默认是DEBUG
+      可以包含零个或多个元素,标识这个appender将会添加到这个logger。
+    -->
+
+    <!-- 4. 最终的策略 -->
+    <!-- 4.1 开发环境:打印控制台-->
+    <!--打印sql-->
+    <!--    <logger name="com.veryhappy.music.dao" level="debug"/>-->
+
+    <!--打印log-->
+    <root level="info">
+        <appender-ref ref="CONSOLE"/>
+        <appender-ref ref="DEBUG_FILE"/>
+        <appender-ref ref="INFO_FILE"/>
+        <appender-ref ref="WARN_FILE"/>
+        <appender-ref ref="ERROR_FILE"/>
+    </root>
+
+    <!--   4.2 生产环境:输出到文档-->
+    <springProfile name="pro">
+        <root level="info">
+            <appender-ref ref="CONSOLE"/>
+            <appender-ref ref="DEBUG_FILE"/>
+            <appender-ref ref="INFO_FILE"/>
+            <appender-ref ref="ERROR_FILE"/>
+            <appender-ref ref="WARN_FILE"/>
+        </root>
+    </springProfile>
+</configuration>

+ 33 - 0
alien-config/.gitignore

@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/

+ 1 - 0
alien-config/README.md

@@ -0,0 +1 @@
+# 统一配置

+ 82 - 0
alien-config/pom.xml

@@ -0,0 +1,82 @@
+<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>shop.alien</groupId>
+        <artifactId>alien-cloud</artifactId>
+        <version>1.0.0</version>
+    </parent>
+
+    <artifactId>alien-config</artifactId>
+    <version>1.0.0</version>
+    <name>alien-config</name>
+    <description>alien-config</description>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    </properties>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.cloud</groupId>
+            <artifactId>spring-cloud-starter-openfeign</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.github.openfeign</groupId>
+            <artifactId>feign-okhttp</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-boot-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-redis</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-core</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-extension</artifactId>
+        </dependency>
+
+    </dependencies>
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>8</source>
+                    <target>8</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 66 - 0
alien-config/src/main/java/shop/alien/config/databases/DruidConfig.java

@@ -0,0 +1,66 @@
+package shop.alien.config.databases;
+
+import com.alibaba.druid.pool.DruidDataSource;
+import com.alibaba.druid.support.http.StatViewServlet;
+import com.alibaba.druid.support.http.WebStatFilter;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.boot.web.servlet.ServletRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.sql.DataSource;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Druid
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2023/8/29 17:41
+ */
+@Configuration
+public class DruidConfig {
+
+    @ConfigurationProperties(prefix = "spring.datasource.druid")
+    @Bean
+    public DataSource druid() {
+        return new DruidDataSource();
+    }
+
+    /**
+     * 配置一个管理后台的Servlet
+     *
+     * @return
+     */
+    @Bean
+    public ServletRegistrationBean statViewServlet() {
+        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(), "/druid/*");
+        Map<String, String> initParams = new HashMap<>();
+        initParams.put("loginUsername", "admin");
+        initParams.put("loginPassword", ".,ZyL021405");
+        initParams.put("allow", "");//默认就是允许所有访问
+        //initParams.put("deny","127.0.0.1");
+        bean.setInitParameters(initParams);
+        return bean;
+    }
+
+    /**
+     * 配置一个web监控的filter
+     *
+     * @return
+     */
+    @Bean
+    public FilterRegistrationBean webStatFilter() {
+        FilterRegistrationBean bean = new FilterRegistrationBean();
+        bean.setFilter(new WebStatFilter());
+        Map<String, String> initParams = new HashMap<>();
+        initParams.put("exclusions", "*.js,*.css,/druid/*");
+        bean.setInitParameters(initParams);
+        bean.setUrlPatterns(Arrays.asList("/*"));
+        return bean;
+    }
+
+}

+ 40 - 0
alien-config/src/main/java/shop/alien/config/databases/MyBatisFieldHandler.java

@@ -0,0 +1,40 @@
+package shop.alien.config.databases;
+
+import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+import org.apache.ibatis.reflection.MetaObject;
+import org.springframework.stereotype.Component;
+
+import java.util.Date;
+
+/**
+ * Mybatis日期填充
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/12/6 10:19
+ */
+@Component
+public class MyBatisFieldHandler implements MetaObjectHandler {
+
+    /**
+     * insert操作时填充方法
+     *
+     * @param metaObject 元对象
+     */
+    @Override
+    public void insertFill(MetaObject metaObject) {
+        //字段为实体类名, 不是表字段名
+        this.setFieldValByName("createdTime", new Date(), metaObject);
+    }
+
+    /**
+     * update操作时填充方法
+     *
+     * @param metaObject 元对象
+     */
+    @Override
+    public void updateFill(MetaObject metaObject) {
+        //字段为实体类名, 不是表字段名
+        this.setFieldValByName("updatedTime", new Date(), metaObject);
+    }
+}

+ 16 - 0
alien-config/src/main/java/shop/alien/config/databases/MyBatisPlusPageConfig.java

@@ -0,0 +1,16 @@
+package shop.alien.config.databases;
+
+import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * MybatisPlus分页
+ */
+@Configuration
+public class MyBatisPlusPageConfig {
+    @Bean
+    public PaginationInterceptor paginationInterceptor() {
+        return new PaginationInterceptor();
+    }
+}

+ 64 - 0
alien-config/src/main/java/shop/alien/config/feign/FeignBodyLogger.java

@@ -0,0 +1,64 @@
+package shop.alien.config.feign;
+
+import feign.Logger;
+import feign.Request;
+import feign.Response;
+import feign.Util;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
+
+/**
+ * 实现 Feign 日志拦截器
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2025/3/19 9:51
+ */
+@Slf4j
+public class FeignBodyLogger extends Logger {
+
+    @Override
+    protected void logRequest(String configKey, Level logLevel, Request request) {
+        // 可选:打印请求日志
+    }
+
+    @Override
+    protected Response logAndRebufferResponse(String configKey, Level logLevel, Response response, long elapsedTime) throws IOException {
+        // 打印状态码和头信息
+        log.info("状态码: {}", response.status());
+        log.info("响应头: {}", response.headers());
+        if (!isGzipResponse(response)) {
+            // 读取并打印响应体(已自动解压)
+            if (response.body() != null && !(response.status() == 204 || response.status() == 205)) {
+                byte[] bodyData = Util.toByteArray(response.body().asInputStream());
+                String body = new String(bodyData, StandardCharsets.UTF_8);
+                log.info("响应体: {}", body);
+                // 重建响应对象避免流关闭
+                return response.toBuilder().body(bodyData).build();
+            }
+        }
+        return response;
+    }
+
+    @Override
+    protected void log(String configKey, String format, Object... args) {
+        // 默认日志输出(可选)
+    }
+
+    /**
+     * 判断是否为 GZip 压缩响应
+     *
+     * @param response 请求内容
+     * @return 是否为 GZip 压缩响应
+     */
+    private boolean isGzipResponse(Response response) {
+        Collection<String> strings = response.headers().get("Content-Encoding");
+        if (null == strings) {
+            return false;
+        }
+        return response.headers().get("Content-Encoding").stream().anyMatch(enc -> enc.contains("gzip"));
+    }
+}

+ 26 - 0
alien-config/src/main/java/shop/alien/config/feign/FeignNacosConfig.java

@@ -0,0 +1,26 @@
+package shop.alien.config.feign;
+
+import lombok.Data;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.cloud.context.config.annotation.RefreshScope;
+import org.springframework.stereotype.Component;
+
+/**
+ * 从 Nacos读取Feign配置
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2025/3/24 14:18
+ */
+@Data
+@Component
+@RefreshScope
+public class FeignNacosConfig {
+
+    @Value("${openfeign.timeout.connect}")
+    private int connectTimeout;
+
+    @Value("${openfeign.timeout.read}")
+    private int readTimeout;
+
+}

+ 58 - 0
alien-config/src/main/java/shop/alien/config/feign/FeignOptionConfig.java

@@ -0,0 +1,58 @@
+package shop.alien.config.feign;
+
+import feign.Logger;
+import feign.Request;
+import feign.codec.Decoder;
+import lombok.RequiredArgsConstructor;
+import org.springframework.beans.factory.ObjectFactory;
+import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
+import org.springframework.cloud.openfeign.support.SpringDecoder;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * 从 Openfeign配置
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/10/21 19:52
+ */
+@Configuration
+@RequiredArgsConstructor
+public class FeignOptionConfig {
+
+    private final FeignNacosConfig feignNacosConfig;
+
+    @Bean
+    public Request.Options options() {
+        return new Request.Options(feignNacosConfig.getConnectTimeout(), feignNacosConfig.getReadTimeout(), true);
+    }
+
+    /**
+     * OpenFeign打印日志, 需在配置文件中指定feign类位置
+     * <p>
+     * NONE, 默认,不显示任何日志
+     * BASIC, 仅记录请求方法、url、响应状态码及执行时间
+     * HEADERS, 除记录BASIC信息外,还记录请求头和响应头
+     * FULL,除了HEADERS信息外,还有请求和响应正文以及元数据
+     *
+     * @return 日志等级
+     */
+    @Bean
+    Logger.Level feignLoggerLevel() {
+        return Logger.Level.BASIC;
+//        return Logger.Level.FULL; // 必须设置为 FULL 才能获取响应体
+    }
+
+//    @Bean
+//    public FeignBodyLogger feignLogger() {
+//        return new FeignBodyLogger();
+//    }
+
+    @Bean
+    public Decoder feignDecoder(ObjectFactory<HttpMessageConverters> converters) {
+        return new GzipResponseDecoder(new SpringDecoder(converters));
+    }
+
+
+}

+ 75 - 0
alien-config/src/main/java/shop/alien/config/feign/GzipResponseDecoder.java

@@ -0,0 +1,75 @@
+package shop.alien.config.feign;
+
+import feign.Response;
+import feign.codec.Decoder;
+import lombok.extern.slf4j.Slf4j;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.zip.GZIPInputStream;
+
+/**
+ * 实现支持 GZip 的解码器
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2025/3/19 9:47
+ */
+@Slf4j
+public class GzipResponseDecoder implements Decoder {
+
+    private final Decoder delegate;
+
+    public GzipResponseDecoder(Decoder delegate) {
+        this.delegate = delegate;
+    }
+
+    @Override
+    public Object decode(Response response, Type type) throws IOException {
+        // 判断是否为 GZip 压缩响应
+        if (isGzipResponse(response)) {
+            try (InputStream is = response.body().asInputStream();
+                 GZIPInputStream gzipIs = new GZIPInputStream(is)) {
+                // 读取解压后的数据
+                ByteArrayOutputStream baos = new ByteArrayOutputStream();
+                byte[] buffer = new byte[1024];
+                int len;
+                while ((len = gzipIs.read(buffer)) > 0) {
+                    baos.write(buffer, 0, len);
+                }
+//                // 打印解压后的原始内容
+//                String rawBody = baos.toString("UTF-8");
+//                System.out.println("[GZip 解压内容] " + rawBody);
+                // 构造新的响应对象供后续解析
+                Response modifiedResponse = Response.builder()
+                        .body(baos.toByteArray())
+                        .headers(response.headers())
+                        .status(response.status())
+                        .request(response.request())
+                        .build();
+                return delegate.decode(modifiedResponse, type);
+            }
+        }
+        return delegate.decode(response, type);
+    }
+
+    /**
+     * 判断是否为 GZip 压缩响应
+     *
+     * @param response 请求内容
+     * @return 是否为 GZip 压缩响应
+     */
+    private boolean isGzipResponse(Response response) {
+        Collection<String> strings = response.headers().get("Content-Encoding");
+        if (null == strings) {
+            return false;
+        }
+        return response.headers().get("Content-Encoding")
+                .stream()
+                .anyMatch(enc -> enc.contains("gzip"));
+    }
+
+}

+ 109 - 0
alien-config/src/main/java/shop/alien/config/feign/OkHttpConfig.java

@@ -0,0 +1,109 @@
+package shop.alien.config.feign;
+
+import okhttp3.ConnectionPool;
+import okhttp3.OkHttpClient;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.net.ssl.*;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.SecureRandom;
+import java.security.cert.X509Certificate;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * OkHttp配置
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/10/27 10:29
+ */
+@Configuration
+public class OkHttpConfig {
+
+    /**
+     * OkHttp 客户端配置
+     *
+     * @return OkHttp 客户端配
+     */
+    @Bean
+    public OkHttpClient okHttpClient() {
+        return new OkHttpClient.Builder()
+                .sslSocketFactory(sslSocketFactory(), x509TrustManager())
+                .hostnameVerifier(hostnameVerifier())
+                //是否开启缓存
+                .retryOnConnectionFailure(false)
+                //连接池
+                .connectionPool(pool())
+                //连接超时时间
+                .connectTimeout(15L, TimeUnit.SECONDS)
+                //读取超时时间
+                .readTimeout(15L, TimeUnit.SECONDS)
+                //是否允许重定向
+                .followRedirects(true)
+                .build();
+    }
+
+    /**
+     * 忽略证书校验
+     *
+     * @return 证书信任管理器
+     */
+    @Bean
+    public X509TrustManager x509TrustManager() {
+        return new X509TrustManager() {
+            @Override
+            public void checkClientTrusted(X509Certificate[] x509Certificates, String s) {
+            }
+
+            @Override
+            public void checkServerTrusted(X509Certificate[] x509Certificates, String s) {
+            }
+
+            @Override
+            public X509Certificate[] getAcceptedIssuers() {
+                return new X509Certificate[0];
+            }
+        };
+    }
+
+    /**
+     * 信任所有 SSL 证书
+     *
+     * @return
+     */
+    @Bean
+    public SSLSocketFactory sslSocketFactory() {
+        try {
+            TrustManager[] trustManagers = new TrustManager[]{x509TrustManager()};
+            SSLContext sslContext = SSLContext.getInstance("SSL");
+            sslContext.init(null, trustManagers, new SecureRandom());
+            return sslContext.getSocketFactory();
+        } catch (NoSuchAlgorithmException | KeyManagementException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * 连接池配置
+     *
+     * @return 连接池
+     */
+    @Bean
+    public ConnectionPool pool() {
+        // 最大连接数、连接存活时间、存活时间单位(分钟)
+        return new ConnectionPool(200, 5, TimeUnit.MINUTES);
+    }
+
+    /**
+     * 信任所有主机名
+     *
+     * @return 主机名校验
+     */
+    @Bean
+    public HostnameVerifier hostnameVerifier() {
+        return (s, sslSession) -> true;
+    }
+}

+ 34 - 0
alien-config/src/main/java/shop/alien/config/filter/FilterConfig.java

@@ -0,0 +1,34 @@
+package shop.alien.config.filter;
+
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.servlet.Filter;
+
+/**
+ * 过滤器配置类
+ **/
+@Configuration
+public class FilterConfig {
+
+    /**
+     * 注册过滤器
+     */
+    @Bean
+    public FilterRegistrationBean someFilterRegistration() {
+        FilterRegistrationBean registration = new FilterRegistrationBean();
+        registration.setFilter(replaceStreamFilter());
+        registration.addUrlPatterns("/*");
+        registration.setName("streamFilter");
+        return registration;
+    }
+
+    /**
+     * 实例化StreamFilter
+     */
+    @Bean(name = "replaceStreamFilter")
+    public Filter replaceStreamFilter() {
+        return new ReplaceStreamFilter();
+    }
+}

+ 23 - 0
alien-config/src/main/java/shop/alien/config/filter/HttpRequestConfig.java

@@ -0,0 +1,23 @@
+package shop.alien.config.filter;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * 可以集中在这里配置拦截器、过滤器、静态资源缓存等
+ */
+@Configuration
+public class HttpRequestConfig implements WebMvcConfigurer {
+
+    @Bean
+    public RequestInterceptor getSignatureInterceptor() {
+        return new RequestInterceptor();
+    }
+
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        registry.addInterceptor(getSignatureInterceptor()).addPathPatterns("/**");
+    }
+}

+ 21 - 0
alien-config/src/main/java/shop/alien/config/filter/ReplaceStreamFilter.java

@@ -0,0 +1,21 @@
+package shop.alien.config.filter;
+
+import lombok.extern.slf4j.Slf4j;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import java.io.IOException;
+
+/**
+ * 替换HttpServletRequest
+ **/
+@Slf4j
+public class ReplaceStreamFilter implements Filter {
+
+    @Override
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+        ServletRequest requestWrapper = new RequestWrapper((HttpServletRequest) request);
+        chain.doFilter(requestWrapper, response);
+    }
+
+}

+ 75 - 0
alien-config/src/main/java/shop/alien/config/filter/RequestInterceptor.java

@@ -0,0 +1,75 @@
+package shop.alien.config.filter;
+
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.core.env.Environment;
+import org.springframework.http.MediaType;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * 编写拦截器
+ **/
+@Slf4j
+public class RequestInterceptor implements HandlerInterceptor {
+
+    private Environment environment;
+
+    @Autowired
+    public void setEnvironment(Environment environment) {
+        this.environment = environment;
+    }
+
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
+        StringBuffer requestURL = request.getRequestURL();
+        String serviceName = environment.getProperty("server.name");
+        if (requestURL.indexOf(serviceName) > -1) {
+            if (isJson(request)) {
+                log.info("--------------Post请求--------------");
+                log.info("请求地址: {}", requestURL);
+                // 获取json字符串
+                try {
+                    String jsonParam = new RequestWrapper(request).getBodyString();
+                    log.info("请求参数: {}", jsonParam);
+                } catch (Exception e) {
+                    log.error("请求参数获取异常: {}", e.getMessage());
+                }
+            } else {
+                log.info("--------------Get请求--------------");
+                log.info("请求地址: {}", requestURL);
+                //获取请求参数
+                String queryString = request.getQueryString();
+                if (queryString != null) {
+                    log.info("请求参数: {}", queryString);
+                }
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
+    }
+
+    @Override
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
+    }
+
+    /**
+     * 判断本次请求的数据类型是否为json
+     */
+    private boolean isJson(HttpServletRequest request) {
+        //判断form-data, application/json, application/json;charset=UTF-8
+        if (request.getContentType() != null) {
+            return request.getContentType().equals(MediaType.APPLICATION_JSON_VALUE) ||
+                    request.getContentType().equals(MediaType.APPLICATION_JSON_UTF8_VALUE) ||
+                    request.getContentType().equals(MediaType.MULTIPART_FORM_DATA_VALUE) ||
+                    request.getContentType().equals("application/json; charset=UTF-8");
+        }
+        return false;
+    }
+}

+ 105 - 0
alien-config/src/main/java/shop/alien/config/filter/RequestWrapper.java

@@ -0,0 +1,105 @@
+package shop.alien.config.filter;
+
+import lombok.extern.slf4j.Slf4j;
+
+import javax.servlet.ReadListener;
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import java.io.*;
+import java.nio.charset.Charset;
+
+/**
+ * 包装HttpServletRequest,目的是让其输入流可重复读
+ **/
+@Slf4j
+public class RequestWrapper extends HttpServletRequestWrapper {
+
+    /**
+     * 存储body数据的容器
+     */
+    private final byte[] body;
+
+    public RequestWrapper(HttpServletRequest request) {
+        super(request);
+        // 将body数据存储起来
+        String bodyStr = getBodyString(request);
+        body = bodyStr.getBytes(Charset.defaultCharset());
+    }
+
+    /**
+     * 获取请求Body
+     */
+    public String getBodyString(final ServletRequest request) {
+        try {
+            return inputStream2String(request.getInputStream());
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * 获取请求Body
+     */
+    public String getBodyString() {
+        final InputStream inputStream = new ByteArrayInputStream(body);
+        return inputStream2String(inputStream);
+    }
+
+    /**
+     * 将inputStream里的数据读取出来并转换成字符串
+     */
+    private String inputStream2String(InputStream inputStream) {
+        StringBuilder sb = new StringBuilder();
+        BufferedReader reader = null;
+        try {
+            reader = new BufferedReader(new InputStreamReader(inputStream, Charset.defaultCharset()));
+            String line;
+            while ((line = reader.readLine()) != null) {
+                sb.append(line);
+            }
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        } finally {
+            if (reader != null) {
+                try {
+                    reader.close();
+                } catch (IOException e) {
+                    log.error("", e);
+                }
+            }
+        }
+        return sb.toString();
+    }
+
+    @Override
+    public BufferedReader getReader() {
+        return new BufferedReader(new InputStreamReader(getInputStream()));
+    }
+
+    @Override
+    public ServletInputStream getInputStream() {
+        final ByteArrayInputStream inputStream = new ByteArrayInputStream(body);
+        return new ServletInputStream() {
+            @Override
+            public int read() {
+                return inputStream.read();
+            }
+
+            @Override
+            public boolean isFinished() {
+                return false;
+            }
+
+            @Override
+            public boolean isReady() {
+                return false;
+            }
+
+            @Override
+            public void setReadListener(ReadListener readListener) {
+            }
+        };
+    }
+}

+ 39 - 0
alien-config/src/main/java/shop/alien/config/http/HttpConfig.java

@@ -0,0 +1,39 @@
+package shop.alien.config.http;
+
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.http.client.ClientHttpRequestFactory;
+import org.springframework.http.client.SimpleClientHttpRequestFactory;
+import org.springframework.web.client.RestTemplate;
+
+/**
+ * @author ssk
+ * @version 1.0
+ * @date 2022/7/11 14:35
+ */
+@Configuration
+public class HttpConfig {
+
+    //单位为ms
+    private static final Integer READ_TIME_OUT = 50000;
+    private static final Integer CONNECTION_TIME_OUT = 50000;
+
+    /**
+     * restTemplate用于发送post请求
+     *
+     * @param factory ClientHttpRequestFactory
+     * @return RestTemplate
+     */
+    @Bean
+    public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
+        return new RestTemplate(factory);
+    }
+
+    @Bean
+    public ClientHttpRequestFactory simpleClientHttpRequestFactory() {
+        SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
+        factory.setReadTimeout(READ_TIME_OUT);
+        factory.setConnectTimeout(CONNECTION_TIME_OUT);
+        return factory;
+    }
+}

+ 152 - 0
alien-config/src/main/java/shop/alien/config/redis/BaseRedisService.java

@@ -0,0 +1,152 @@
+package shop.alien.config.redis;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author ssk
+ * @version 1.0
+ * @date 2022/3/14 15:14
+ */
+@Component
+@RequiredArgsConstructor
+public class BaseRedisService {
+
+    private final StringRedisTemplate stringRedisTemplate;
+
+    /**
+     * 添加List值, 向右
+     *
+     * @param key   键
+     * @param value 值
+     */
+    public void setListRight(String key, String value) {
+        stringRedisTemplate.opsForList().rightPush(key, value);
+    }
+
+    /**
+     * 添加List, 所有
+     *
+     * @param key   键
+     * @param value 值
+     */
+    public void setList(String key, List<String> value) {
+        stringRedisTemplate.opsForList().rightPushAll(key, value);
+    }
+
+    /**
+     * 从List左边取值并删除
+     *
+     * @param key 键
+     * @return 删除的值
+     */
+    public String getListLeft(String key) {
+        return stringRedisTemplate.opsForList().leftPop(key);
+    }
+
+    /**
+     * 获取List所有
+     *
+     * @param key 键
+     * @return List<String>
+     */
+    public List<String> getList(String key) {
+        return stringRedisTemplate.opsForList().range(key, 0, -1);
+    }
+
+
+    /**
+     * 添加Set
+     *
+     * @param key   键
+     * @param value 值
+     */
+    public void setSetList(String key, String value) {
+        stringRedisTemplate.opsForSet().add(key, value);
+    }
+
+    /**
+     * 获取Set
+     *
+     * @param key 键
+     * @return Set<String>
+     */
+    public Set<String> getSetList(String key) {
+        return stringRedisTemplate.opsForSet().members(key);
+    }
+
+    /**
+     * 添加String值, 不设置过期时间
+     *
+     * @param key   键
+     * @param value 值
+     */
+    public void setString(String key, String value) {
+        set(key, value, null);
+    }
+
+    /**
+     * 添加String值, 并设置过期时间
+     *
+     * @param key     键
+     * @param value   值
+     * @param timeOut 时长(秒)
+     */
+    public void setString(String key, String value, Long timeOut) {
+        set(key, value, timeOut);
+    }
+
+    /**
+     * 设置超时时间
+     *
+     * @param key     键
+     * @param timeOut 时长(秒)
+     */
+    public void setTimeOut(String key, Long timeOut) {
+        stringRedisTemplate.expire(key, timeOut, TimeUnit.SECONDS);
+    }
+
+    /**
+     * 传入object对象
+     *
+     * @param key     键
+     * @param value   值
+     * @param timeOut 时长(秒)
+     */
+    private void set(String key, Object value, Long timeOut) {
+        if (value != null) {
+            if (value instanceof String) {
+                String setValue = (String) value;
+                stringRedisTemplate.opsForValue().set(key, setValue);
+            }
+            //设置有效期
+            if (timeOut != null) {
+                stringRedisTemplate.expire(key, timeOut, TimeUnit.SECONDS);
+            }
+        }
+    }
+
+    /**
+     * 使用key查找redis信息
+     *
+     * @param key 键
+     * @return
+     */
+    public String getString(String key) {
+        return stringRedisTemplate.opsForValue().get(key);
+    }
+
+    /**
+     * 使用key删除redis信息
+     *
+     * @param key 键
+     */
+    public void delete(String key) {
+        stringRedisTemplate.delete(key);
+    }
+}

+ 33 - 0
alien-entity/.gitignore

@@ -0,0 +1,33 @@
+HELP.md
+target/
+!.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/

+ 1 - 0
alien-entity/README.md

@@ -0,0 +1 @@
+# 网关  登录

+ 78 - 0
alien-entity/pom.xml

@@ -0,0 +1,78 @@
+<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>shop.alien</groupId>
+        <artifactId>alien-cloud</artifactId>
+        <version>1.0.0</version>
+    </parent>
+
+    <artifactId>alien-entity</artifactId>
+    <version>1.0.0</version>
+    <name>alien-entity</name>
+    <description>alien-entity</description>
+
+    <properties>
+        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
+    </properties>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>io.springfox</groupId>
+            <artifactId>springfox-swagger2</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.swagger</groupId>
+            <artifactId>swagger-annotations</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>io.swagger</groupId>
+            <artifactId>swagger-models</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-annotation</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.baomidou</groupId>
+            <artifactId>mybatis-plus-extension</artifactId>
+        </dependency>
+
+        <!--农历转公历-->
+        <dependency>
+            <groupId>cn.6tail</groupId>
+            <artifactId>lunar</artifactId>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>8</source>
+                    <target>8</target>
+                </configuration>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 82 - 0
alien-entity/src/main/java/shop/alien/entity/analysis/entity/AnalysisLog.java

@@ -0,0 +1,82 @@
+package shop.alien.entity.analysis.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * 解析记录
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2022/10/31 14:08
+ */
+@Data
+@ApiModel(value = "AnalysisLog对象", description = "解析记录")
+@TableName("analysis_log")
+public class AnalysisLog {
+
+    @ApiModelProperty(value = "主键id")
+    private Integer id;
+
+    @ApiModelProperty(value = "标题")
+    private String title;
+
+    @ApiModelProperty(value = "类别")
+    private String type;
+
+    @ApiModelProperty(value = "视频来源")
+    private String source;
+
+    @ApiModelProperty(value = "解析的链接")
+    private String link;
+
+    @TableField("item_id")
+    @ApiModelProperty(value = "项目id")
+    private String itemId;
+
+    @TableField("nickname")
+    @ApiModelProperty(value = "昵称")
+    private String nickname;
+
+    @TableField("uid")
+    @ApiModelProperty(value = "用户id")
+    private String uid;
+
+    @ApiModelProperty(value = "存放位置(0 本地 1 Nas)")
+    private Integer position;
+
+    @ApiModelProperty(value = "文件名")
+    private String fileName;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+
+}

+ 58 - 0
alien-entity/src/main/java/shop/alien/entity/analysis/entity/AnalysisToken.java

@@ -0,0 +1,58 @@
+package shop.alien.entity.analysis.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * 解析用户Token
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2023/5/23 16:14
+ */
+@Data
+@ApiModel(value = "AnalysisToken对象", description = "解析用户Token")
+public class AnalysisToken {
+
+    @ApiModelProperty(value = "主键id")
+    private Integer id;
+
+    @ApiModelProperty(value = "用户id")
+    private Integer analysisUserId;
+
+    @ApiModelProperty(value = "token")
+    private String token;
+
+    @ApiModelProperty(value = "token有效时间(分)")
+    private Integer tokenExpiryMinutes;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+}

+ 61 - 0
alien-entity/src/main/java/shop/alien/entity/analysis/entity/AnalysisUser.java

@@ -0,0 +1,61 @@
+package shop.alien.entity.analysis.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * 解析用户
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2023/5/22 15:44
+ */
+@Data
+@ApiModel(value = "AnalysisUser对象", description = "解析用户")
+public class AnalysisUser {
+
+    @ApiModelProperty(value = "主键id")
+    private Integer id;
+
+    @ApiModelProperty(value = "邮箱")
+    private String email;
+
+    @ApiModelProperty(value = "密码")
+    private String password;
+
+    @ApiModelProperty(value = "剩余次数")
+    private String remainingTimes;
+
+    @ApiModelProperty(value = "上次签到时间")
+    private Date lastCheckIn;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+}

+ 61 - 0
alien-entity/src/main/java/shop/alien/entity/analysis/entity/DouYinAnalysis.java

@@ -0,0 +1,61 @@
+package shop.alien.entity.analysis.entity;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * 抖音解析
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2022/12/27 11:02
+ */
+@Data
+public class DouYinAnalysis {
+
+    /**
+     * 链接
+     */
+    private String link;
+
+    /**
+     * 类型
+     */
+    private String type;
+
+    /**
+     * 来源
+     */
+    private String source;
+
+    /**
+     * 描述
+     */
+    private String desc;
+
+    /**
+     * 用户昵称
+     */
+    private String nickname;
+
+    /**
+     * 用户id
+     */
+    private String uid;
+
+    /**
+     * 项目id
+     */
+    private String itemId;
+
+    /**
+     * 视频集合
+     */
+    private List<String> video_list;
+
+    /**
+     * 图片集合
+     */
+    private List<String> image_list;
+}

+ 16 - 0
alien-entity/src/main/java/shop/alien/entity/analysis/mapper/AnalysisLogMapper.java

@@ -0,0 +1,16 @@
+package shop.alien.entity.analysis.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import shop.alien.entity.analysis.entity.AnalysisLog;
+
+/**
+ * 解析记录Mapper
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2022/10/31 14:17
+ */
+@Mapper
+public interface AnalysisLogMapper extends BaseMapper<AnalysisLog> {
+}

+ 16 - 0
alien-entity/src/main/java/shop/alien/entity/analysis/mapper/AnalysisTokenMapper.java

@@ -0,0 +1,16 @@
+package shop.alien.entity.analysis.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import shop.alien.entity.analysis.entity.AnalysisToken;
+
+/**
+ * 解析用户TokenMapper
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2023/5/22 16:17
+ */
+@Mapper
+public interface AnalysisTokenMapper extends BaseMapper<AnalysisToken> {
+}

+ 16 - 0
alien-entity/src/main/java/shop/alien/entity/analysis/mapper/AnalysisUserMapper.java

@@ -0,0 +1,16 @@
+package shop.alien.entity.analysis.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import shop.alien.entity.analysis.entity.AnalysisUser;
+
+/**
+ * 解析用户Mapper
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2023/5/22 16:10
+ */
+@Mapper
+public interface AnalysisUserMapper extends BaseMapper<AnalysisUser> {
+}

+ 59 - 0
alien-entity/src/main/java/shop/alien/entity/area/entity/AreaCode.java

@@ -0,0 +1,59 @@
+package shop.alien.entity.area.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * @author ssk
+ * @version 1.0
+ * @date 2024/3/5 16:36
+ */
+@Data
+@ApiModel(value = "AreaCode对象", description = "区域编码")
+@TableName("area_code")
+public class AreaCode {
+
+    @ApiModelProperty(value = "主键id")
+    private Integer id;
+
+    @ApiModelProperty(value = "地区名称")
+    private String areaName;
+
+    @ApiModelProperty(value = "地区编码")
+    private String areaCode;
+
+    @ApiModelProperty(value = "城市编码")
+    private String cityCode;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+
+}

+ 103 - 0
alien-entity/src/main/java/shop/alien/entity/area/entity/QweatherLocationCode.java

@@ -0,0 +1,103 @@
+package shop.alien.entity.area.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * 和风天气区域编码
+ *
+ * @author ssk
+ * @since 2025-04-01
+ */
+@Data
+@TableName("qweather_location_code")
+@ApiModel(value = "QweatherLocationCode对象", description = "和风天气区域编码")
+public class QweatherLocationCode extends Model<QweatherLocationCode> {
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "地区id")
+    @TableField("location_id")
+    private String locationId;
+
+    @ApiModelProperty(value = "地区英文名")
+    @TableField("location_name_en")
+    private String locationNameEn;
+
+    @ApiModelProperty(value = "地区中文名")
+    @TableField("location_name_zh")
+    private String locationNameZh;
+
+    @ApiModelProperty(value = "国家代码")
+    @TableField("iso_3166_1")
+    private String iso31661;
+
+    @ApiModelProperty(value = "国家英文名")
+    @TableField("country_region_en")
+    private String countryRegionEn;
+
+    @ApiModelProperty(value = "国家中文名")
+    @TableField("country_region_zh")
+    private String countryRegionZh;
+
+    @ApiModelProperty(value = "省英文名")
+    @TableField("adm1_name_en")
+    private String adm1NameEn;
+
+    @ApiModelProperty(value = "省中文名")
+    @TableField("adm1_name_zh")
+    private String adm1NameZh;
+
+    @ApiModelProperty(value = "市英文名")
+    @TableField("adm2_name_en")
+    private String adm2NameEn;
+
+    @ApiModelProperty(value = "地市中文名")
+    @TableField("adm2_name_zh")
+    private String adm2NameZh;
+
+    @ApiModelProperty(value = "时区")
+    @TableField("timezone")
+    private String timezone;
+
+    @ApiModelProperty(value = "纬度")
+    @TableField("latitude")
+    private String latitude;
+
+    @ApiModelProperty(value = "经度")
+    @TableField("longitude")
+    private String longitude;
+
+    @ApiModelProperty(value = "邮政编码")
+    @TableField("ad_code")
+    private String adCode;
+
+    @ApiModelProperty(value = "删除标识(0 未删除 1 删除)")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.INSERT_UPDATE)
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+
+}

+ 16 - 0
alien-entity/src/main/java/shop/alien/entity/area/mapper/AreaCodeMapper.java

@@ -0,0 +1,16 @@
+package shop.alien.entity.area.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import shop.alien.entity.area.entity.AreaCode;
+
+/**
+ * 区域编码Mapper
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/3/5 16:40
+ */
+@Mapper
+public interface AreaCodeMapper extends BaseMapper<AreaCode> {
+}

+ 14 - 0
alien-entity/src/main/java/shop/alien/entity/area/mapper/QweatherLocationCodeMapper.java

@@ -0,0 +1,14 @@
+package shop.alien.entity.area.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import shop.alien.entity.area.entity.QweatherLocationCode;
+
+/**
+ * 和风天气区域编码 Mapper 接口
+ *
+ * @author ssk
+ * @since 2025-04-01
+ */
+public interface QweatherLocationCodeMapper extends BaseMapper<QweatherLocationCode> {
+
+}

+ 22 - 0
alien-entity/src/main/java/shop/alien/entity/area/service/AreaCodeService.java

@@ -0,0 +1,22 @@
+package shop.alien.entity.area.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.area.entity.AreaCode;
+
+/**
+ * 区域编码Service
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/3/5 17:11
+ */
+public interface AreaCodeService extends IService<AreaCode> {
+
+    /**
+     * 根据城市名获取城市编码
+     *
+     * @param areaName 城市名
+     * @return 城市编码
+     */
+    AreaCode getAreaCodeByName(String areaName);
+}

+ 14 - 0
alien-entity/src/main/java/shop/alien/entity/area/service/QweatherLocationCodeService.java

@@ -0,0 +1,14 @@
+package shop.alien.entity.area.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.area.entity.QweatherLocationCode;
+
+/**
+ * 和风天气区域编码 服务类
+ *
+ * @author ssk
+ * @since 2025-04-01
+ */
+public interface QweatherLocationCodeService extends IService<QweatherLocationCode> {
+
+}

+ 32 - 0
alien-entity/src/main/java/shop/alien/entity/area/service/impl/AreaCodeServiceImpl.java

@@ -0,0 +1,32 @@
+package shop.alien.entity.area.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import shop.alien.entity.area.entity.AreaCode;
+import shop.alien.entity.area.mapper.AreaCodeMapper;
+import shop.alien.entity.area.service.AreaCodeService;
+
+/**
+ * 区域编码ServiceImpl
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/3/5 17:11
+ */
+@Service
+public class AreaCodeServiceImpl extends ServiceImpl<AreaCodeMapper, AreaCode> implements AreaCodeService {
+
+    /**
+     * 根据城市名获取城市编码
+     *
+     * @param areaName 城市名
+     * @return 城市编码
+     */
+    @Override
+    public AreaCode getAreaCodeByName(String areaName) {
+        QueryWrapper<AreaCode> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("area_name", areaName);
+        return this.getOne(queryWrapper);
+    }
+}

+ 18 - 0
alien-entity/src/main/java/shop/alien/entity/area/service/impl/QweatherLocationCodeServiceImpl.java

@@ -0,0 +1,18 @@
+package shop.alien.entity.area.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import shop.alien.entity.area.entity.QweatherLocationCode;
+import shop.alien.entity.area.mapper.QweatherLocationCodeMapper;
+import shop.alien.entity.area.service.QweatherLocationCodeService;
+
+/**
+ * 和风天气区域编码 服务实现类
+ *
+ * @author ssk
+ * @since 2025-04-01
+ */
+@Service
+public class QweatherLocationCodeServiceImpl extends ServiceImpl<QweatherLocationCodeMapper, QweatherLocationCode> implements QweatherLocationCodeService {
+
+}

+ 79 - 0
alien-entity/src/main/java/shop/alien/entity/bot/entity/MsgFootballInfo.java

@@ -0,0 +1,79 @@
+package shop.alien.entity.bot.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.util.Date;
+
+/**
+ * 消息足球赛程
+ *
+ * @author ssk
+ * @since 2025-02-28
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("msg_football_info")
+@ApiModel(value = "MsgFootballInfo对象", description = "消息足球赛程")
+public class MsgFootballInfo extends Model<MsgFootballInfo> {
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "场次")
+    @TableField("session")
+    private Integer session;
+
+    @ApiModelProperty(value = "比赛时间")
+    @TableField("competition_time")
+    private String competitionTime;
+
+    @ApiModelProperty(value = "比赛日期")
+    @TableField("competition_date")
+    private String competitionDate;
+
+    @ApiModelProperty(value = "星期")
+    @TableField("week")
+    private String week;
+
+    @ApiModelProperty(value = "主场")
+    @TableField("home_court")
+    private String homeCourt;
+
+    @ApiModelProperty(value = "客场")
+    @TableField("away_game")
+    private String awayGame;
+
+    @ApiModelProperty(value = "比赛场地")
+    @TableField("competition_site")
+    private String competitionSite;
+
+    @ApiModelProperty(value = "删除标识(0 未删除 1 删除)")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.INSERT_UPDATE)
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+
+}

+ 53 - 0
alien-entity/src/main/java/shop/alien/entity/bot/entity/WeChatBot.java

@@ -0,0 +1,53 @@
+package shop.alien.entity.bot.entity;
+
+import lombok.Data;
+
+/**
+ * 微信机器人接收类
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/10/12 11:45
+ */
+@Data
+public class WeChatBot {
+
+    /**
+     * 功能类型
+     * ✅ 文字(text)
+     * ✅ 链接卡片(urlLink)
+     * ✅ 图片(file)
+     * ✅ 视频(file)
+     * ✅ 附件(file)
+     * ✅ 语音(file)
+     * ✅ 添加好友邀请(friendship)
+     * 其他类型
+     * 未实现的消息类型(unknown)
+     * 系统类型
+     * ✅ 登录(system_event_login)
+     * ✅ 登出(system_event_logout)
+     * ✅ 异常报错(system_event_error)
+     * ✅ 快捷回复后消息推送状态通知(system_event_push_notify)
+     */
+    String type;
+
+    /**
+     * 传输的内容, 文本或传输的文件共用这个字段,结构映射请看示例
+     */
+    Object content;
+
+    /**
+     * 消息的相关发送方数据, JSON String
+     */
+    String source;
+
+    /**
+     * 该消息是@我的消息
+     */
+    String isMentioned;
+
+    /**
+     * 是否是来自自己的消息
+     */
+    String isMsgFromSelf;
+}

+ 33 - 0
alien-entity/src/main/java/shop/alien/entity/bot/entity/WeChatBotReturn.java

@@ -0,0 +1,33 @@
+package shop.alien.entity.bot.entity;
+
+import lombok.Data;
+
+/**
+ * 微信机器人返回类
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/10/12 12:00
+ */
+@Data
+public class WeChatBotReturn {
+
+    public WeChatBotReturn() {
+    }
+
+    public WeChatBotReturn(String type, String content) {
+        this.type = type;
+        this.content = content;
+    }
+
+    /**
+     * 消息类型,该字段不填默认当文本类型传输
+     * text/fileUrl
+     */
+    String type;
+
+    /**
+     * 消息内容,如果希望发多个Url并解析,type 指定为 fileUrl 同时,content 里填 url 以英文逗号分隔
+     */
+    String content;
+}

+ 34 - 0
alien-entity/src/main/java/shop/alien/entity/bot/entity/WeChatSend.java

@@ -0,0 +1,34 @@
+package shop.alien.entity.bot.entity;
+
+import lombok.Data;
+
+/**
+ * 向微信发送消息类
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/10/12 18:57
+ */
+@Data
+public class WeChatSend {
+
+    /**
+     * 昵称
+     */
+    String nickname;
+
+    /**
+     * 消息
+     */
+    String msg;
+
+    /**
+     * 消息类型
+     */
+    String type;
+
+    /**
+     * 是否为群聊
+     */
+    boolean isRoom;
+}

+ 76 - 0
alien-entity/src/main/java/shop/alien/entity/bot/entity/ZhugeLots.java

@@ -0,0 +1,76 @@
+package shop.alien.entity.bot.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * 诸葛神算
+ *
+ * @author ssk
+ * @since 2025-02-11
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("zhuge_lots")
+@ApiModel(value="ZhugeLots对象", description="诸葛神算")
+public class ZhugeLots extends Model<ZhugeLots> {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "主键id")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "排序")
+    @TableField("sort")
+    private Integer sort;
+
+    @ApiModelProperty(value = "签文")
+    @TableField("lots_content")
+    private String lotsContent;
+
+    @ApiModelProperty(value = "解释")
+    @TableField("`explain`")
+    private String explain;
+
+    @ApiModelProperty(value = "解签")
+    @TableField("lots_explain")
+    private String lotsExplain;
+
+    @ApiModelProperty(value = "删除标识(0 未删除 1 删除)")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.INSERT_UPDATE)
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+
+
+    @Override
+    protected Serializable pkVal() {
+        return this.id;
+    }
+
+}

+ 14 - 0
alien-entity/src/main/java/shop/alien/entity/bot/mapper/MsgFootballInfoMapper.java

@@ -0,0 +1,14 @@
+package shop.alien.entity.bot.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import shop.alien.entity.bot.entity.MsgFootballInfo;
+
+/**
+ * 消息足球赛程 Mapper 接口
+ *
+ * @author ssk
+ * @since 2025-02-28
+ */
+public interface MsgFootballInfoMapper extends BaseMapper<MsgFootballInfo> {
+
+}

+ 14 - 0
alien-entity/src/main/java/shop/alien/entity/bot/mapper/ZhugeLotsMapper.java

@@ -0,0 +1,14 @@
+package shop.alien.entity.bot.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import shop.alien.entity.bot.entity.ZhugeLots;
+
+/**
+ * 诸葛神算 Mapper 接口
+ *
+ * @author ssk
+ * @since 2025-02-11
+ */
+public interface ZhugeLotsMapper extends BaseMapper<ZhugeLots> {
+
+}

+ 80 - 0
alien-entity/src/main/java/shop/alien/entity/device/entity/DeviceInfo.java

@@ -0,0 +1,80 @@
+package shop.alien.entity.device.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * 设备信息表
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-03-29
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("msg_device_info")
+@ApiModel(value = "MsgDeviceInfo对象", description = "设备信息表")
+public class DeviceInfo extends Model<DeviceInfo> {
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "设备名称")
+    @TableField("device_name")
+    private String deviceName;
+
+    @ApiModelProperty(value = "设备品牌")
+    @TableField("device_brand")
+    private String deviceBrand;
+
+    @ApiModelProperty(value = "设备型号")
+    @TableField("device_model")
+    private String deviceModel;
+
+    @ApiModelProperty(value = "设备系统")
+    @TableField("device_system")
+    private String deviceSystem;
+
+    @ApiModelProperty(value = "设备imei")
+    @TableField("device_id")
+    private String deviceId;
+
+    @ApiModelProperty(value = "客户端id")
+    @TableField("client_id")
+    private String clientId;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+
+}

+ 60 - 0
alien-entity/src/main/java/shop/alien/entity/device/entity/MsgAppVersion.java

@@ -0,0 +1,60 @@
+package shop.alien.entity.device.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * app版本号
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-05-31
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("msg_app_version")
+@ApiModel(value = "MsgAppVersion对象", description = "app版本号")
+public class MsgAppVersion extends Model<MsgAppVersion> {
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "版本号")
+    @TableField("version")
+    private String version;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+
+}

+ 68 - 0
alien-entity/src/main/java/shop/alien/entity/device/entity/MsgDeviceStyle.java

@@ -0,0 +1,68 @@
+package shop.alien.entity.device.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * 设备个性修改
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-05-13
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("msg_device_style")
+@ApiModel(value = "MsgDeviceImg对象", description = "设备背景图片")
+public class MsgDeviceStyle extends Model<MsgDeviceStyle> {
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "设备id")
+    @TableField("device_id")
+    private Integer deviceId;
+
+    @ApiModelProperty(value = "图片地址")
+    @TableField("img_url")
+    private String imgUrl;
+
+    @ApiModelProperty(value = "文字颜色")
+    @TableField("font_color")
+    private String fontColor;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+
+}

+ 80 - 0
alien-entity/src/main/java/shop/alien/entity/device/entity/MsgImportantDate.java

@@ -0,0 +1,80 @@
+package shop.alien.entity.device.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * 消息重要日期提醒
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-04-12
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("msg_important_date")
+@ApiModel(value = "MsgImportantDate对象", description = "消息重要日期提醒")
+public class MsgImportantDate extends Model<MsgImportantDate> {
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "用户id")
+    @TableField("user_id")
+    private Integer userId;
+
+    @ApiModelProperty(value = "日期名称")
+    @TableField("date_name")
+    private String dateName;
+
+    @ApiModelProperty(value = "出生日期")
+    @TableField("born_date")
+    private String bornDate;
+
+    @ApiModelProperty(value = "农历日期")
+    @TableField("old_date")
+    private String oldDate;
+
+    @ApiModelProperty(value = "新历日期")
+    @TableField("new_date")
+    private String newDate;
+
+    @ApiModelProperty(value = "提醒选项(0:全部提醒,1:农历,2:新历,3:不提醒)")
+    @TableField("remind_with")
+    private Integer remindWith;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+
+}

+ 40 - 0
alien-entity/src/main/java/shop/alien/entity/device/entity/MsgImportantDateDto.java

@@ -0,0 +1,40 @@
+package shop.alien.entity.device.entity;
+
+import lombok.Data;
+
+/**
+ * 重要日期,返回前端用
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/4/12 14:17
+ */
+@Data
+public class MsgImportantDateDto {
+
+    /**
+     * id
+     */
+    private Integer id;
+
+    /**
+     * 日期名称
+     */
+    private String dateName;
+
+    /**
+     * 日期
+     */
+    private String oldDate;
+
+    /**
+     * 新日期
+     */
+    private String newDate;
+
+    /**
+     * 剩余时间
+     */
+    private Integer remainingDays;
+
+}

+ 68 - 0
alien-entity/src/main/java/shop/alien/entity/device/entity/MsgPushLog.java

@@ -0,0 +1,68 @@
+package shop.alien.entity.device.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * 消息推送记录
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-04-11
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("msg_push_log")
+@ApiModel(value = "MsgPushLog对象", description = "消息推送记录")
+public class MsgPushLog extends Model<MsgPushLog> {
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "用户id")
+    @TableField("user_id")
+    private Integer userId;
+
+    @ApiModelProperty(value = "设备主键")
+    @TableField("device_id")
+    private Integer deviceId;
+
+    @ApiModelProperty(value = "消息内容")
+    @TableField("msg_content")
+    private String msgContent;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+
+}

+ 64 - 0
alien-entity/src/main/java/shop/alien/entity/device/entity/MsgUserDeviceBind.java

@@ -0,0 +1,64 @@
+package shop.alien.entity.device.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * 微信用户和设备绑定表
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-04-21
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("msg_user_device_bind")
+@ApiModel(value = "MsgUserDeviceBind对象", description = "微信用户和设备绑定表")
+public class MsgUserDeviceBind extends Model<MsgUserDeviceBind> {
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "设备id")
+    @TableField("device_id")
+    private Integer deviceId;
+
+    @ApiModelProperty(value = "用户id")
+    @TableField("user_id")
+    private Integer userId;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+
+}

+ 84 - 0
alien-entity/src/main/java/shop/alien/entity/device/entity/MsgWechatUserInfo.java

@@ -0,0 +1,84 @@
+package shop.alien.entity.device.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * <p>
+ * 消息用微信用户表
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-04-21
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@Accessors(chain = true)
+@TableName("msg_wechat_user_info")
+@ApiModel(value = "MsgWechatUserInfo对象", description = "消息用微信用户表")
+public class MsgWechatUserInfo extends Model<MsgWechatUserInfo> {
+
+    @ApiModelProperty(value = "主键")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Integer id;
+
+    @ApiModelProperty(value = "用户昵称")
+    @TableField("nickname")
+    private String nickname;
+
+    @ApiModelProperty(value = "用户头像")
+    @TableField("img_url")
+    private String imgUrl;
+
+    @ApiModelProperty(value = "微信用户id")
+    @TableField("open_id")
+    private String openId;
+
+    @ApiModelProperty(value = "手机号")
+    @TableField("phone")
+    private String phone;
+
+    @ApiModelProperty(value = "微信号")
+    @TableField("wechat_no")
+    private String wechatNo;
+
+    @ApiModelProperty(value = "微信原始id")
+    @TableField("wechat_uid")
+    private String wechatUid;
+
+    @ApiModelProperty(value = "是否为管理员(0:否,1:是)")
+    @TableField("is_admin")
+    private Integer isAdmin;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+
+}

+ 31 - 0
alien-entity/src/main/java/shop/alien/entity/device/entity/UserBindDeviceInfo.java

@@ -0,0 +1,31 @@
+package shop.alien.entity.device.entity;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 用户与设备绑定
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/4/10 10:45
+ */
+@EqualsAndHashCode(callSuper = true)
+@Data
+@ApiModel(value = "用户与设备绑定", description = "用户与设备绑定")
+public class UserBindDeviceInfo extends DeviceInfo {
+
+    /**
+     * 表id
+     */
+    @ApiModelProperty(value = "表id")
+    private Integer userId;
+
+    /**
+     * 微信用户id
+     */
+    @ApiModelProperty(value = "微信用户id")
+    private String openId;
+}

+ 37 - 0
alien-entity/src/main/java/shop/alien/entity/device/mapper/DeviceInfoMapper.java

@@ -0,0 +1,37 @@
+package shop.alien.entity.device.mapper;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.springframework.stereotype.Repository;
+import shop.alien.entity.device.entity.DeviceInfo;
+import shop.alien.entity.device.entity.UserBindDeviceInfo;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 设备信息表 Mapper 接口
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-03-29
+ */
+@Mapper
+@Repository
+public interface DeviceInfoMapper extends BaseMapper<DeviceInfo> {
+
+    /**
+     * 查询用户与设备绑定关系
+     *
+     * @param queryWrapper 查询条件
+     * @return List<UserBindDeviceInfo>
+     */
+    @Select("select a.*, c.id userId, c.open_id from msg_device_info a left join msg_user_device_bind b " +
+            "on a.id = b.device_id left join msg_wechat_user_info c on b.user_id = c.id ${ew.customSqlSegment}")
+    List<UserBindDeviceInfo> getUserBindInfo(@Param(Constants.WRAPPER) QueryWrapper<UserBindDeviceInfo> queryWrapper);
+
+}

+ 18 - 0
alien-entity/src/main/java/shop/alien/entity/device/mapper/MsgAppVersionMapper.java

@@ -0,0 +1,18 @@
+package shop.alien.entity.device.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import shop.alien.entity.device.entity.MsgAppVersion;
+
+/**
+ * <p>
+ * app版本号 Mapper 接口
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-05-31
+ */
+@Mapper
+public interface MsgAppVersionMapper extends BaseMapper<MsgAppVersion> {
+
+}

+ 18 - 0
alien-entity/src/main/java/shop/alien/entity/device/mapper/MsgDeviceStyleMapper.java

@@ -0,0 +1,18 @@
+package shop.alien.entity.device.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import shop.alien.entity.device.entity.MsgDeviceStyle;
+
+/**
+ * <p>
+ * 设备个性修改 Mapper 接口
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-05-13
+ */
+@Mapper
+public interface MsgDeviceStyleMapper extends BaseMapper<MsgDeviceStyle> {
+
+}

+ 20 - 0
alien-entity/src/main/java/shop/alien/entity/device/mapper/MsgImportantDateMapper.java

@@ -0,0 +1,20 @@
+package shop.alien.entity.device.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+import shop.alien.entity.device.entity.MsgImportantDate;
+
+/**
+ * <p>
+ * 消息重要日期提醒 Mapper 接口
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-04-12
+ */
+@Mapper
+@Repository
+public interface MsgImportantDateMapper extends BaseMapper<MsgImportantDate> {
+
+}

+ 35 - 0
alien-entity/src/main/java/shop/alien/entity/device/mapper/MsgPushLogMapper.java

@@ -0,0 +1,35 @@
+package shop.alien.entity.device.mapper;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.toolkit.Constants;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Select;
+import org.springframework.stereotype.Repository;
+import shop.alien.entity.device.entity.MsgPushLog;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 消息推送记录 Mapper 接口
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-04-11
+ */
+@Mapper
+@Repository
+public interface MsgPushLogMapper extends BaseMapper<MsgPushLog> {
+
+    /**
+     * 获取待办内容
+     *
+     * @param queryWrapper 查询条件
+     * @return List<MsgPushLog>
+     */
+    @Select("select a.* from msg_push_log a left join msg_wechat_user_info b on a.user_id = b.id " +
+            "left join msg_device_info c on a.device_id = c.id  ${ew.customSqlSegment}")
+    List<MsgPushLog> getMsg(@Param(Constants.WRAPPER) QueryWrapper<MsgPushLog> queryWrapper);
+}

+ 20 - 0
alien-entity/src/main/java/shop/alien/entity/device/mapper/MsgUserDeviceBindMapper.java

@@ -0,0 +1,20 @@
+package shop.alien.entity.device.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+import shop.alien.entity.device.entity.MsgUserDeviceBind;
+
+/**
+ * <p>
+ * 微信用户和设备绑定表 Mapper 接口
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-04-21
+ */
+@Mapper
+@Repository
+public interface MsgUserDeviceBindMapper extends BaseMapper<MsgUserDeviceBind> {
+
+}

+ 20 - 0
alien-entity/src/main/java/shop/alien/entity/device/mapper/MsgWechatUserInfoMapper.java

@@ -0,0 +1,20 @@
+package shop.alien.entity.device.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+import shop.alien.entity.device.entity.MsgWechatUserInfo;
+
+/**
+ * <p>
+ * 消息用微信用户表 Mapper 接口
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-04-21
+ */
+@Mapper
+@Repository
+public interface MsgWechatUserInfoMapper extends BaseMapper<MsgWechatUserInfo> {
+
+}

+ 69 - 0
alien-entity/src/main/java/shop/alien/entity/device/service/DeviceInfoService.java

@@ -0,0 +1,69 @@
+package shop.alien.entity.device.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.device.entity.DeviceInfo;
+import shop.alien.entity.device.entity.MsgDeviceStyle;
+import shop.alien.entity.device.entity.UserBindDeviceInfo;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 设备信息表 服务类
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-03-29
+ */
+public interface DeviceInfoService extends IService<DeviceInfo> {
+
+    /**
+     * 绑定设备
+     *
+     * @param openId      微信用户id
+     * @param deviceId    设备id
+     * @param deviceBrand 设备厂商
+     * @param deviceModel 设备型号
+     * @param system      设备系统
+     * @param clientId    客户端id
+     * @param deviceName  设备别名
+     * @return boolean
+     */
+    boolean addOne(String openId, String deviceId, String deviceBrand, String deviceModel, String system, String clientId, String deviceName);
+
+    /**
+     * 查询用户与设备绑定关系
+     *
+     * @param openId     微信用户id
+     * @param deviceName 设备名称
+     * @param deviceId   设备id
+     * @return List<UserBindDeviceInfo>
+     */
+    List<UserBindDeviceInfo> getUserBindInfo(String openId, String deviceName, String deviceId);
+
+    /**
+     * 获取设备
+     *
+     * @param deviceInfo 设备信息
+     * @return DeviceInfo
+     */
+    DeviceInfo getOneDevice(DeviceInfo deviceInfo);
+
+    /**
+     * 设置设备图片地址
+     *
+     * @param deviceId  设备id
+     * @param url       图片url
+     * @param fontColor 文字颜色
+     * @return int
+     */
+    boolean setDeviceStyle(String deviceId, String url, String fontColor);
+
+    /**
+     * 获取设备图片地址
+     *
+     * @param deviceId 设备id
+     * @return String
+     */
+    MsgDeviceStyle getDeviceStyle(String deviceId);
+}

+ 23 - 0
alien-entity/src/main/java/shop/alien/entity/device/service/MsgAppVersionService.java

@@ -0,0 +1,23 @@
+package shop.alien.entity.device.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.device.entity.MsgAppVersion;
+
+/**
+ * <p>
+ * app版本号 服务类
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-05-31
+ */
+public interface MsgAppVersionService extends IService<MsgAppVersion> {
+
+
+    /**
+     * 获取最新版本
+     *
+     * @return MsgAppVersion
+     */
+    MsgAppVersion getLatestVersion();
+}

+ 16 - 0
alien-entity/src/main/java/shop/alien/entity/device/service/MsgDeviceStyleService.java

@@ -0,0 +1,16 @@
+package shop.alien.entity.device.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.device.entity.MsgDeviceStyle;
+
+/**
+ * <p>
+ * 设备个性修改 服务类
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-05-13
+ */
+public interface MsgDeviceStyleService extends IService<MsgDeviceStyle> {
+
+}

+ 54 - 0
alien-entity/src/main/java/shop/alien/entity/device/service/MsgImportantDateService.java

@@ -0,0 +1,54 @@
+package shop.alien.entity.device.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.device.entity.MsgImportantDate;
+import shop.alien.entity.device.entity.MsgImportantDateDto;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 消息重要日期提醒 服务类
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-04-12
+ */
+public interface MsgImportantDateService extends IService<MsgImportantDate> {
+
+    /**
+     * 根据用户id查询重要日期
+     *
+     * @param userId 用户id
+     * @return List<MsgImportantDate>
+     */
+    List<MsgImportantDateDto> getDate(String userId);
+
+    /**
+     * 获取最近三年的重要日期
+     *
+     * @param userId 用户id
+     * @return List<MsgImportantDate>
+     */
+    List<MsgImportantDateDto> getRecentlyThreeYearsImportantDate(String userId);
+
+    /**
+     * 添加重要日期
+     *
+     * @param userId     用户id
+     * @param dateName   日期名称
+     * @param oldDate    农历日期
+     * @param newDate    阳历日期
+     * @param remindWith 提醒选项(0:全部提醒,1:农历,2:新历,3:不提醒)
+     * @return boolean
+     */
+    boolean addImportantDate(String userId, String dateName, String oldDate, String newDate, Integer remindWith);
+
+    /**
+     * 删除重要日期
+     *
+     * @param id 表id
+     * @return boolean
+     */
+    boolean deleteMsg(Integer id);
+}

+ 43 - 0
alien-entity/src/main/java/shop/alien/entity/device/service/MsgPushLogService.java

@@ -0,0 +1,43 @@
+package shop.alien.entity.device.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.device.entity.MsgPushLog;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 消息推送记录 服务类
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-04-11
+ */
+public interface MsgPushLogService extends IService<MsgPushLog> {
+
+    /**
+     * 根据设备id获取待办列表
+     *
+     * @param deviceId 设备id
+     * @param openId   微信用户id
+     * @return List<MsgPushLog>
+     */
+    List<MsgPushLog> getMsg(String deviceId, String openId);
+
+    /**
+     * 删除消息
+     *
+     * @param id 表id
+     * @return boolean
+     */
+    boolean deleteMsg(Integer id);
+
+    /**
+     * 消息置顶
+     *
+     * @param id 表id
+     * @return boolean
+     */
+    boolean topMsg(Integer id);
+
+}

+ 167 - 0
alien-entity/src/main/java/shop/alien/entity/device/service/impl/DeviceInfoServiceImpl.java

@@ -0,0 +1,167 @@
+package shop.alien.entity.device.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import shop.alien.entity.device.entity.*;
+import shop.alien.entity.device.mapper.DeviceInfoMapper;
+import shop.alien.entity.device.mapper.MsgDeviceStyleMapper;
+import shop.alien.entity.device.mapper.MsgUserDeviceBindMapper;
+import shop.alien.entity.device.mapper.MsgWechatUserInfoMapper;
+import shop.alien.entity.device.service.DeviceInfoService;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 设备信息表 服务实现类
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-03-29
+ */
+@Service
+@RequiredArgsConstructor
+public class DeviceInfoServiceImpl extends ServiceImpl<DeviceInfoMapper, DeviceInfo> implements DeviceInfoService {
+
+    private final DeviceInfoMapper deviceInfoMapper;
+
+    private final MsgUserDeviceBindMapper msgUserDeviceBindMapper;
+
+    private final MsgWechatUserInfoMapper msgWechatUserInfoMapper;
+
+    private final MsgDeviceStyleMapper msgDeviceImgMapper;
+
+    /**
+     * 绑定设备
+     *
+     * @param openId      微信用户id
+     * @param deviceId    设备id
+     * @param deviceBrand 设备厂商
+     * @param deviceModel 设备型号
+     * @param system      设备系统
+     * @param clientId    客户端id
+     * @param deviceName  设备别名
+     * @return boolean
+     */
+    @Override
+    public boolean addOne(String openId, String deviceId, String deviceBrand, String deviceModel, String system, String clientId, String deviceName) {
+        //填写设备信息
+        DeviceInfo deviceInfo = new DeviceInfo();
+        deviceInfo.setDeviceId(deviceId);
+        deviceInfo.setDeviceBrand(deviceBrand);
+        deviceInfo.setDeviceModel(deviceModel);
+        deviceInfo.setDeviceSystem(system);
+        deviceInfo.setClientId(clientId);
+        deviceInfo.setDeviceName(deviceName);
+        QueryWrapper<MsgWechatUserInfo> msgWechatUserInfoQuery = new QueryWrapper<>();
+        msgWechatUserInfoQuery.eq("open_id", openId);
+        MsgWechatUserInfo msgWechatUserInfo = msgWechatUserInfoMapper.selectOne(msgWechatUserInfoQuery);
+        deviceInfo.setCreatedUserId(msgWechatUserInfo.getId());
+        boolean save = this.save(deviceInfo);
+        //填写绑定信息
+        MsgUserDeviceBind msgUserDeviceBind = new MsgUserDeviceBind();
+        msgUserDeviceBind.setDeviceId(deviceInfo.getId());
+        msgUserDeviceBind.setUserId(msgWechatUserInfo.getId());
+        msgUserDeviceBind.setCreatedUserId(msgWechatUserInfo.getId());
+        int insert = msgUserDeviceBindMapper.insert(msgUserDeviceBind);
+        return save && insert > 0;
+    }
+
+    /**
+     * 查询用户与设备绑定关系
+     *
+     * @param openId     微信用户id
+     * @param deviceName 设备名称
+     * @param deviceId   设备id
+     * @return List<UserBindDeviceInfo>
+     */
+    @Override
+    public List<UserBindDeviceInfo> getUserBindInfo(String openId, String deviceName, String deviceId) {
+        QueryWrapper<UserBindDeviceInfo> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq(deviceName != null && !deviceName.isEmpty(), "a.device_name", deviceName);
+        queryWrapper.eq(deviceId != null && !deviceId.isEmpty(), "a.device_id", deviceId);
+        queryWrapper.eq(openId != null && !openId.isEmpty(), "c.open_id", openId);
+        queryWrapper.eq("a.delete_flag", 0);
+        queryWrapper.eq("c.delete_flag", 0);
+        return deviceInfoMapper.getUserBindInfo(queryWrapper);
+    }
+
+    /**
+     * 获取设备
+     *
+     * @param deviceInfo 设备信息
+     * @return DeviceInfo
+     */
+    public DeviceInfo getOneDevice(DeviceInfo deviceInfo) {
+        QueryWrapper<DeviceInfo> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq(deviceInfo.getId() != null, "id", deviceInfo.getId());
+        queryWrapper.eq(deviceInfo.getDeviceName() != null, "device_name", deviceInfo.getDeviceName());
+        queryWrapper.eq(deviceInfo.getDeviceId() != null, "device_id", deviceInfo.getDeviceId());
+        queryWrapper.eq(deviceInfo.getClientId() != null, "client_id", deviceInfo.getClientId());
+        return this.getOne(queryWrapper);
+    }
+
+    /**
+     * 设置设备图片地址
+     *
+     * @param deviceId  设备id
+     * @param url       图片url
+     * @param fontColor 文字颜色
+     * @return int
+     */
+    @Override
+    public boolean setDeviceStyle(String deviceId, String url, String fontColor) {
+        DeviceInfo deviceInfo = new DeviceInfo();
+        deviceInfo.setDeviceId(deviceId);
+        DeviceInfo selectDevice = getOneDevice(deviceInfo);
+        QueryWrapper<MsgDeviceStyle> msgDeviceImgQueryWrapper = new QueryWrapper<>();
+        msgDeviceImgQueryWrapper.eq("device_id", selectDevice.getId());
+        MsgDeviceStyle selectMsgDeviceImg = msgDeviceImgMapper.selectOne(msgDeviceImgQueryWrapper);
+        //修改
+        if (selectMsgDeviceImg != null) {
+            if (url != null && !url.equals("null")) {
+                selectMsgDeviceImg.setImgUrl(url);
+            }
+            if (fontColor != null && !fontColor.equals("null")) {
+                selectMsgDeviceImg.setFontColor("#" + fontColor);
+            }
+            return msgDeviceImgMapper.updateById(selectMsgDeviceImg) > 0;
+        } else {
+            //新增
+            List<UserBindDeviceInfo> userBindInfo = getUserBindInfo(null, null, deviceId);
+            if (!userBindInfo.isEmpty()) {
+                UserBindDeviceInfo userBindDeviceInfo = userBindInfo.get(0);
+                MsgDeviceStyle msgDeviceImg = new MsgDeviceStyle();
+                msgDeviceImg.setDeviceId(userBindDeviceInfo.getId());
+                if (url != null && !url.equals("null")) {
+                    msgDeviceImg.setImgUrl(url);
+                }
+                if (fontColor != null && !fontColor.equals("null")) {
+                    msgDeviceImg.setFontColor("#" + fontColor);
+                }
+                msgDeviceImg.setCreatedUserId(userBindDeviceInfo.getId());
+                return msgDeviceImgMapper.insert(msgDeviceImg) > 0;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 获取设备图片地址
+     *
+     * @param deviceId 设备id
+     * @return String
+     */
+    @Override
+    public MsgDeviceStyle getDeviceStyle(String deviceId) {
+        DeviceInfo deviceInfo = new DeviceInfo();
+        deviceInfo.setDeviceId(deviceId);
+        DeviceInfo selectDevice = getOneDevice(deviceInfo);
+        QueryWrapper<MsgDeviceStyle> msgDeviceImgQueryWrapper = new QueryWrapper<>();
+        msgDeviceImgQueryWrapper.eq("device_id", selectDevice.getId());
+        return msgDeviceImgMapper.selectOne(msgDeviceImgQueryWrapper);
+    }
+
+}

+ 33 - 0
alien-entity/src/main/java/shop/alien/entity/device/service/impl/MsgAppVersionServiceImpl.java

@@ -0,0 +1,33 @@
+package shop.alien.entity.device.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import shop.alien.entity.device.entity.MsgAppVersion;
+import shop.alien.entity.device.mapper.MsgAppVersionMapper;
+import shop.alien.entity.device.service.MsgAppVersionService;
+
+/**
+ * <p>
+ * app版本号 服务实现类
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-05-31
+ */
+@Service
+public class MsgAppVersionServiceImpl extends ServiceImpl<MsgAppVersionMapper, MsgAppVersion> implements MsgAppVersionService {
+
+    /**
+     * 获取最新版本
+     *
+     * @return MsgAppVersion
+     */
+    @Override
+    public MsgAppVersion getLatestVersion() {
+        QueryWrapper<MsgAppVersion> queryWrapper = new QueryWrapper<>();
+        queryWrapper.orderByDesc("created_time");
+        queryWrapper.last("limit 1");
+        return this.getOne(queryWrapper);
+    }
+}

+ 20 - 0
alien-entity/src/main/java/shop/alien/entity/device/service/impl/MsgDeviceStyleServiceImpl.java

@@ -0,0 +1,20 @@
+package shop.alien.entity.device.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import shop.alien.entity.device.entity.MsgDeviceStyle;
+import shop.alien.entity.device.mapper.MsgDeviceStyleMapper;
+import shop.alien.entity.device.service.MsgDeviceStyleService;
+
+/**
+ * <p>
+ * 设备个性修改 服务实现类
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-05-13
+ */
+@Service
+public class MsgDeviceStyleServiceImpl extends ServiceImpl<MsgDeviceStyleMapper, MsgDeviceStyle> implements MsgDeviceStyleService {
+
+}

+ 303 - 0
alien-entity/src/main/java/shop/alien/entity/device/service/impl/MsgImportantDateServiceImpl.java

@@ -0,0 +1,303 @@
+package shop.alien.entity.device.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.nlf.calendar.Lunar;
+import com.nlf.calendar.Solar;
+import org.springframework.stereotype.Service;
+import shop.alien.entity.device.entity.MsgImportantDate;
+import shop.alien.entity.device.entity.MsgImportantDateDto;
+import shop.alien.entity.device.mapper.MsgImportantDateMapper;
+import shop.alien.entity.device.service.MsgImportantDateService;
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.time.temporal.ChronoUnit;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * <p>
+ * 消息重要日期提醒 服务实现类
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-04-12
+ */
+@Service
+public class MsgImportantDateServiceImpl extends ServiceImpl<MsgImportantDateMapper, MsgImportantDate> implements MsgImportantDateService {
+
+    /**
+     * 根据用户id查询重要日期
+     *
+     * @param userId 用户id
+     * @return List<MsgImportantDate>
+     */
+    @Override
+    public List<MsgImportantDateDto> getDate(String userId) {
+        LambdaQueryWrapper<MsgImportantDate> lambdaQueryWrapper = new LambdaQueryWrapper<>();
+        lambdaQueryWrapper.eq(MsgImportantDate::getDeleteFlag, 0);
+        lambdaQueryWrapper.in(MsgImportantDate::getUserId, userId);
+        List<MsgImportantDate> list = this.list(lambdaQueryWrapper);
+        List<MsgImportantDateDto> sortList = new ArrayList<>();
+        //添加所有日期
+        for (MsgImportantDate msgImportantDate : list) {
+            MsgImportantDateDto msgImportantDateDto;
+            //提醒选项(0:全部提醒,1:农历,2:新历)
+            if (msgImportantDate.getRemindWith() == 0) {
+                //旧日期
+                MsgImportantDateDto oldDate = new MsgImportantDateDto();
+                oldDate.setId(msgImportantDate.getId());
+                oldDate.setDateName(msgImportantDate.getDateName() + "(农历)");
+                oldDate.setOldDate(msgImportantDate.getOldDate());
+                sortList.add(oldDate);
+                //新日期
+                MsgImportantDateDto newDate = new MsgImportantDateDto();
+                newDate.setId(msgImportantDate.getId());
+                newDate.setDateName(msgImportantDate.getDateName() + "(阳历)");
+                newDate.setNewDate(msgImportantDate.getNewDate());
+                sortList.add(newDate);
+            } else if (msgImportantDate.getRemindWith() == 1) {
+                msgImportantDateDto = new MsgImportantDateDto();
+                msgImportantDateDto.setId(msgImportantDate.getId());
+                msgImportantDateDto.setDateName(msgImportantDate.getDateName() + "(农历)");
+                msgImportantDateDto.setOldDate(msgImportantDate.getOldDate());
+                sortList.add(msgImportantDateDto);
+            } else {
+                msgImportantDateDto = new MsgImportantDateDto();
+                msgImportantDateDto.setId(msgImportantDate.getId());
+                msgImportantDateDto.setDateName(msgImportantDate.getDateName() + "(阳历)");
+                msgImportantDateDto.setNewDate(msgImportantDate.getNewDate());
+                sortList.add(msgImportantDateDto);
+            }
+        }
+        String yearStr = LocalDateTime.now().toString().substring(0, 4);
+        for (MsgImportantDateDto msgImportantDateDto : sortList) {
+            //农历日期计算
+            if (msgImportantDateDto.getDateName().contains("农历")) {
+                //农历转公历
+                int month = Integer.parseInt(msgImportantDateDto.getOldDate().substring(5, 7));
+                int day = Integer.parseInt(msgImportantDateDto.getOldDate().substring(8, 10));
+                Lunar lunar = Lunar.fromYmd(Integer.parseInt(yearStr), month, day);
+                Solar solar = lunar.getSolar();
+                String convertNewDate = solar.toString();//今年阳历日期(农历转)
+                String date = msgImportantDateDto.getOldDate();
+                String thisYearOldDate = yearStr + date.substring(4);//今年农历日期
+                msgImportantDateDto.setOldDate(thisYearOldDate);
+                msgImportantDateDto.setNewDate(convertNewDate);
+                LocalDate thisYearNewDate = LocalDate.of(Integer.parseInt(convertNewDate.substring(0, 4)), Integer.parseInt(convertNewDate.substring(5, 7)), Integer.parseInt(convertNewDate.substring(8, 10)));
+                //判断转阳历是否过去
+                if (thisYearNewDate.isBefore(LocalDate.now())) {
+                    //今年的过完了, 计算明年的
+                    int nextYear = Integer.parseInt(yearStr) + 1;
+                    //明年农历日期
+                    thisYearOldDate = nextYear + date.substring(4);
+                    msgImportantDateDto.setOldDate(thisYearOldDate);
+                    Lunar newlunar = Lunar.fromYmd(Integer.parseInt(thisYearOldDate.substring(0, 4)), Integer.parseInt(thisYearOldDate.substring(5, 7)), Integer.parseInt(thisYearOldDate.substring(8, 10)));
+                    Solar newsolar = newlunar.getSolar();
+                    msgImportantDateDto.setNewDate(newsolar.toString());
+                }
+                //下一个农历转阳历的日期和今天的天数
+                Lunar nextLunar = Lunar.fromYmd(Integer.parseInt(thisYearOldDate.substring(0, 4)), Integer.parseInt(thisYearOldDate.substring(5, 7)), Integer.parseInt(thisYearOldDate.substring(8, 10)));
+                Solar nextSolar = nextLunar.getSolar();
+                String nextConvertNewDate = nextSolar.toString();//下一个农历转阳历日期
+                LocalDate parseDate = LocalDate.parse(nextConvertNewDate, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+                long between = ChronoUnit.DAYS.between(LocalDate.now(), parseDate);
+                msgImportantDateDto.setRemainingDays(Integer.parseInt(String.valueOf(between)));
+            } else {
+                //阳历日期
+                String date = msgImportantDateDto.getNewDate();
+                String thisYearStr = yearStr + date.substring(4);
+                msgImportantDateDto.setNewDate(thisYearStr);
+                LocalDate thisYear = LocalDate.of(Integer.parseInt(yearStr), Integer.parseInt(date.substring(5, 7)), Integer.parseInt(date.substring(8, 10)));
+                if (thisYear.isBefore(LocalDate.now())) {
+                    //今年的过完了, 计算明年的
+                    int nextYear = Integer.parseInt(yearStr) + 1;
+                    thisYearStr = nextYear + date.substring(4);
+                }
+                LocalDate parseDate = LocalDate.parse(thisYearStr, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
+                long between = ChronoUnit.DAYS.between(LocalDate.now(), parseDate);
+                msgImportantDateDto.setRemainingDays(Integer.parseInt(String.valueOf(between)));
+            }
+        }
+        //排序倒数日期
+        sortList.sort(Comparator.comparing(MsgImportantDateDto::getRemainingDays));
+        return sortList;
+    }
+
+    /**
+     * 获取最近三年的重要日期
+     *
+     * @param userId 用户id
+     * @return List<MsgImportantDate>
+     */
+    @Override
+    public List<MsgImportantDateDto> getRecentlyThreeYearsImportantDate(String userId) {
+        List<MsgImportantDateDto> resultList = new ArrayList<>();
+        LambdaQueryWrapper<MsgImportantDate> lambdaQueryWrapper = new LambdaQueryWrapper<>();
+        lambdaQueryWrapper.eq(MsgImportantDate::getDeleteFlag, 0);
+        lambdaQueryWrapper.eq(MsgImportantDate::getUserId, userId);
+        List<MsgImportantDate> importantDateList = this.list(lambdaQueryWrapper);
+        List<MsgImportantDateDto> thisYear = new ArrayList<>();
+        //添加所有日期
+        for (MsgImportantDate msgImportantDate : importantDateList) {
+            MsgImportantDateDto msgImportantDateDto = new MsgImportantDateDto();
+            //提醒选项(0:全部提醒,1:农历,2:新历)
+            if (msgImportantDate.getRemindWith() == 0) {
+                //农历
+                MsgImportantDateDto oldDate = new MsgImportantDateDto();
+                oldDate.setDateName(msgImportantDate.getDateName());
+                oldDate.setOldDate(msgImportantDate.getOldDate());
+                thisYear.add(oldDate);
+                //阳历
+                MsgImportantDateDto newDate = new MsgImportantDateDto();
+                newDate.setDateName(msgImportantDate.getDateName());
+                newDate.setNewDate(msgImportantDate.getNewDate());
+                thisYear.add(newDate);
+            } else if (msgImportantDate.getRemindWith() == 1) {
+                //农历
+                msgImportantDateDto.setDateName(msgImportantDate.getDateName());
+                msgImportantDateDto.setOldDate(msgImportantDate.getOldDate());
+                thisYear.add(msgImportantDateDto);
+            } else if (msgImportantDate.getRemindWith() == 2) {
+                //阳历
+                msgImportantDateDto.setDateName(msgImportantDate.getDateName());
+                msgImportantDateDto.setNewDate(msgImportantDate.getNewDate());
+                thisYear.add(msgImportantDateDto);
+            }
+        }
+
+        //获取今年年份
+        int yearStr = Integer.parseInt(LocalDateTime.now().toString().substring(0, 4));
+        //农历转阳历,并添加今年和明年的日期
+        List<MsgImportantDateDto> lastYear = new ArrayList<>();
+        List<MsgImportantDateDto> nextYear = new ArrayList<>();
+        //thisYear(0000农历, 今年阳历);
+        for (MsgImportantDateDto msgImportantDateDto : thisYear) {
+            //农历
+            if (msgImportantDateDto.getOldDate() != null) {
+                int month = Integer.parseInt(msgImportantDateDto.getOldDate().substring(5, 7));
+                int day = Integer.parseInt(msgImportantDateDto.getOldDate().substring(8, 10));
+                //今年农历
+                msgImportantDateDto.setOldDate(yearStr + "-" + addZero(month) + "-" + addZero(day));
+                //今年阳历
+                msgImportantDateDto.setNewDate(convertNewDate(yearStr, month, day));
+                //去年
+                MsgImportantDateDto msgImportantDateLast = new MsgImportantDateDto();
+                msgImportantDateLast.setDateName(msgImportantDateDto.getDateName());
+                //去年农历
+                msgImportantDateLast.setOldDate(yearStr - 1 + "-" + addZero(month) + "-" + addZero(day));
+                //去年阳历
+                msgImportantDateLast.setNewDate(convertNewDate(yearStr - 1, month, day));
+                lastYear.add(msgImportantDateLast);
+                //明年
+                MsgImportantDateDto msgImportantDateNext = new MsgImportantDateDto();
+                msgImportantDateNext.setDateName(msgImportantDateDto.getDateName());
+                //明年农历
+                msgImportantDateNext.setOldDate(yearStr + 1 + "-" + addZero(month) + "-" + addZero(day));
+                //明年阳历
+                msgImportantDateNext.setNewDate(convertNewDate(yearStr + 1, month, day));
+                nextYear.add(msgImportantDateNext);
+            } else if (msgImportantDateDto.getNewDate() != null) {
+                //阳历
+                int month = Integer.parseInt(msgImportantDateDto.getNewDate().substring(5, 7));
+                int day = Integer.parseInt(msgImportantDateDto.getNewDate().substring(8, 10));
+                //今年阳历
+                msgImportantDateDto.setNewDate(yearStr + "-" + addZero(month) + "-" + addZero(day));
+                //去年
+                MsgImportantDateDto msgImportantDateLast = new MsgImportantDateDto();
+                msgImportantDateLast.setDateName(msgImportantDateDto.getDateName());
+                msgImportantDateLast.setNewDate(yearStr - 1 + "-" + addZero(month) + "-" + addZero(day));
+                lastYear.add(msgImportantDateLast);
+                //明年
+                MsgImportantDateDto msgImportantDateNext = new MsgImportantDateDto();
+                msgImportantDateNext.setDateName(msgImportantDateDto.getDateName());
+                msgImportantDateNext.setNewDate(yearStr + 1 + "-" + addZero(month) + "-" + addZero(day));
+                nextYear.add(msgImportantDateNext);
+            }
+        }
+        resultList.addAll(lastYear);
+        resultList.addAll(thisYear);
+        resultList.addAll(nextYear);
+        return resultList;
+    }
+
+    /**
+     * 添加重要日期
+     *
+     * @param userId     用户id
+     * @param dateName   日期名称
+     * @param oldDate    农历日期
+     * @param newDate    阳历日期
+     * @param remindWith 提醒选项(0:全部提醒,1:农历,2:新历,3:不提醒)
+     * @return boolean
+     */
+    @Override
+    public boolean addImportantDate(String userId, String dateName, String oldDate, String newDate, Integer remindWith) {
+        MsgImportantDate msgImportantDate = new MsgImportantDate();
+        String[] split = userId.split(",");
+        if (split.length > 1) {
+            userId = split[0];
+        }
+        msgImportantDate.setUserId(Integer.parseInt(userId));
+        msgImportantDate.setDateName(dateName);
+        String[] oldDateList = getList(oldDate);
+        msgImportantDate.setOldDate("0000-" + addZero(Integer.parseInt(oldDateList[1])) + "-" + addZero(Integer.parseInt(oldDateList[2])));
+        String[] newDateList = getList(newDate);
+        msgImportantDate.setNewDate("0000-" + addZero(Integer.parseInt(newDateList[1])) + "-" + addZero(Integer.parseInt(newDateList[2])));
+        msgImportantDate.setRemindWith(remindWith);
+        msgImportantDate.setCreatedUserId(Integer.parseInt(userId));
+        return this.save(msgImportantDate);
+    }
+
+    /**
+     * 删除重要日期
+     *
+     * @param id 表id
+     * @return boolean
+     */
+    @Override
+    public boolean deleteMsg(Integer id) {
+        return this.removeById(id);
+    }
+
+    /**
+     * 农历转阳历
+     *
+     * @param year  年
+     * @param month 月
+     * @param day   日
+     * @return 阳历日期
+     */
+    private String convertNewDate(Integer year, Integer month, Integer day) {
+        Lunar lunar = Lunar.fromYmd(year, month, day);
+        Solar solar = lunar.getSolar();
+        return solar.toString();
+    }
+
+    /**
+     * 判断小于十则加0
+     *
+     * @param num 数字
+     * @return string
+     */
+    private String addZero(int num) {
+        if (num < 10) {
+            return "0" + num;
+        }
+        return num + "";
+    }
+
+    /**
+     * 用-分割
+     *
+     * @param str 字符串
+     * @return 数组
+     */
+    private String[] getList(String str) {
+        return str.split("-");
+    }
+
+}

+ 71 - 0
alien-entity/src/main/java/shop/alien/entity/device/service/impl/MsgPushLogServiceImpl.java

@@ -0,0 +1,71 @@
+package shop.alien.entity.device.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import shop.alien.entity.device.entity.MsgPushLog;
+import shop.alien.entity.device.mapper.MsgPushLogMapper;
+import shop.alien.entity.device.service.MsgPushLogService;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * <p>
+ * 消息推送记录 服务实现类
+ * </p>
+ *
+ * @author ssk
+ * @since 2024-04-11
+ */
+@Service
+@RequiredArgsConstructor
+public class MsgPushLogServiceImpl extends ServiceImpl<MsgPushLogMapper, MsgPushLog> implements MsgPushLogService {
+
+    private final MsgPushLogMapper msgPushLogMapper;
+
+    /**
+     * 根据设备id获取待办列表
+     *
+     * @param deviceId 设备id
+     * @param openId   微信用户id
+     * @return List<MsgPushLog>
+     */
+    @Override
+    public List<MsgPushLog> getMsg(String deviceId, String openId) {
+        List<String> openIdList = Arrays.asList(openId.split(","));
+        QueryWrapper<MsgPushLog> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("a.delete_flag", 0);
+        queryWrapper.eq("c.device_id", deviceId);
+        queryWrapper.in("b.open_id", openIdList);
+        queryWrapper.orderByDesc("a.created_time");
+        return msgPushLogMapper.getMsg(queryWrapper);
+    }
+
+    /**
+     * 删除消息
+     *
+     * @param id 表id
+     * @return boolean
+     */
+    @Override
+    public boolean deleteMsg(Integer id) {
+        return this.removeById(id);
+    }
+
+    /**
+     * 消息置顶
+     *
+     * @param id 表id
+     * @return boolean
+     */
+    @Override
+    public boolean topMsg(Integer id) {
+        MsgPushLog msgPushLog = new MsgPushLog();
+        msgPushLog.setId(id);
+        msgPushLog.setCreatedTime(new Date());
+        return this.updateById(msgPushLog);
+    }
+}

+ 57 - 0
alien-entity/src/main/java/shop/alien/entity/idiom/entity/IdiomLibrary.java

@@ -0,0 +1,57 @@
+package shop.alien.entity.idiom.entity;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * 成语库
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/11/13 14:41
+ */
+@Data
+@ApiModel(value = "IdiomLibrary对象", description = "成语库")
+@TableName("idiom_library")
+public class IdiomLibrary {
+
+    @ApiModelProperty(value = "主键id")
+    private Integer id;
+
+    @ApiModelProperty(value = "成语")
+    private String idiom;
+
+    @ApiModelProperty(value = "拼音")
+    private String spell;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+}

+ 16 - 0
alien-entity/src/main/java/shop/alien/entity/idiom/mapper/IdiomLibraryMapper.java

@@ -0,0 +1,16 @@
+package shop.alien.entity.idiom.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import shop.alien.entity.idiom.entity.IdiomLibrary;
+
+/**
+ * 成语库Mapper
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/11/13 14:43
+ */
+@Mapper
+public interface IdiomLibraryMapper extends BaseMapper<IdiomLibrary> {
+}

+ 14 - 0
alien-entity/src/main/java/shop/alien/entity/idiom/service/IdiomLibraryService.java

@@ -0,0 +1,14 @@
+package shop.alien.entity.idiom.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import shop.alien.entity.idiom.entity.IdiomLibrary;
+
+/**
+ * 成语库Service
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/11/13 14:44
+ */
+public interface IdiomLibraryService extends IService<IdiomLibrary> {
+}

+ 18 - 0
alien-entity/src/main/java/shop/alien/entity/idiom/service/impl/IdiomLibraryServiceImpl.java

@@ -0,0 +1,18 @@
+package shop.alien.entity.idiom.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import shop.alien.entity.idiom.entity.IdiomLibrary;
+import shop.alien.entity.idiom.mapper.IdiomLibraryMapper;
+import shop.alien.entity.idiom.service.IdiomLibraryService;
+
+/**
+ * 成语库ServiceImpl
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2024/11/13 14:45
+ */
+@Service
+public class IdiomLibraryServiceImpl extends ServiceImpl<IdiomLibraryMapper, IdiomLibrary> implements IdiomLibraryService {
+}

+ 29 - 0
alien-entity/src/main/java/shop/alien/entity/msg/dingding/entity/DingDingMsgDto.java

@@ -0,0 +1,29 @@
+package shop.alien.entity.msg.dingding.entity;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * 钉钉消息推送
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2022/9/23 16:49
+ */
+@Data
+@ApiModel(value = "DingDingMsgDto对象", description = "钉钉消息推送")
+public class DingDingMsgDto {
+
+    @ApiModelProperty(value = "消息内容")
+    String msgContent;
+
+    @ApiModelProperty(value = "机器人名称(从钉钉机器人列表获取)")
+    String robotName;
+
+    @ApiModelProperty(value = "被@人的账号(目前为系统用户账号,待修改")
+    String accountNumber;
+
+    @ApiModelProperty(value = "@标记(0:不使用; 1:当前指定人; 2:所有人)")
+    Integer atFlag;
+}

+ 72 - 0
alien-entity/src/main/java/shop/alien/entity/msg/dingding/entity/DingDingMsgLog.java

@@ -0,0 +1,72 @@
+package shop.alien.entity.msg.dingding.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * 钉钉消息记录
+ *
+ * @author ssk
+ * @since 2022-07-12
+ */
+@Data
+@TableName("msg_dingding_msg_log")
+@ApiModel(value = "DingDingMsgLog对象", description = "钉钉消息记录")
+public class DingDingMsgLog extends Model<DingDingMsgLog> {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty(value = "主键")
+    @TableId("id")
+    private Integer id;
+
+    @ApiModelProperty(value = "机器人id")
+    @TableField("robot_id")
+    private Integer robotId;
+
+    @ApiModelProperty(value = "消息内容")
+    @TableField("msg_content")
+    private String msgContent;
+
+    @ApiModelProperty(value = "消息类型(1:Text文本类型, 2:Markdown类型, 3:ActionCard类型, 4:FeedCard类型, 5:Link链接消息)")
+    @TableField("msg_type")
+    private Integer msgType;
+
+    @ApiModelProperty(value = "发送状态(0 未发送 1 已发送 2 失败)")
+    @TableField("send_status")
+    private Integer sendStatus;
+
+    @ApiModelProperty(value = "失败原因")
+    @TableField("fail_reason")
+    private String failReason;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+
+}

+ 66 - 0
alien-entity/src/main/java/shop/alien/entity/msg/dingding/entity/DingDingRobotConfig.java

@@ -0,0 +1,66 @@
+package shop.alien.entity.msg.dingding.entity;
+
+import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+
+/**
+ * 钉钉机器人配置
+ *
+ * @author ssk
+ * @since 2022-07-11
+ */
+@Data
+@TableName("msg_dingding_robot_config")
+@ApiModel(value = "DingDingRobotConfig对象", description = "钉钉机器人配置")
+public class DingDingRobotConfig extends Model<DingDingRobotConfig> {
+
+    @ApiModelProperty(value = "主键")
+    @TableId("id")
+    private Integer id;
+
+    @ApiModelProperty(value = "机器人名称")
+    @TableField("robot_name")
+    private String robotName;
+
+    @ApiModelProperty(value = "Token")
+    @TableField("access_token")
+    private String accessToken;
+
+    @ApiModelProperty(value = "密钥")
+    @TableField("secret")
+    private String secret;
+
+    @ApiModelProperty(value = "密钥类型:1:加签(需要加在连接中验证),2:自定义关键词(消息内容必须包括关键字)")
+    @TableField("secret_type")
+    private Integer secretType;
+
+    @ApiModelProperty(value = "删除标记, 0:未删除, 1:已删除")
+    @TableField("delete_flag")
+    @TableLogic
+    private Integer deleteFlag;
+
+    @ApiModelProperty(value = "创建时间")
+    @TableField(value = "created_time", fill = FieldFill.INSERT)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date createdTime;
+
+    @ApiModelProperty(value = "创建人ID")
+    @TableField("created_user_id")
+    private Integer createdUserId;
+
+    @ApiModelProperty(value = "修改时间")
+    @TableField(value = "updated_time", fill = FieldFill.UPDATE)
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date updatedTime;
+
+    @ApiModelProperty(value = "修改人ID")
+    @TableField("updated_user_id")
+    private Integer updatedUserId;
+
+}

+ 18 - 0
alien-entity/src/main/java/shop/alien/entity/msg/dingding/mapper/DingDingMsgLogMapper.java

@@ -0,0 +1,18 @@
+package shop.alien.entity.msg.dingding.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+import shop.alien.entity.msg.dingding.entity.DingDingMsgLog;
+
+/**
+ * 钉钉消息记录Mapper
+ *
+ * @author ssk
+ * @since 2022-07-12
+ */
+@Mapper
+@Repository
+public interface DingDingMsgLogMapper extends BaseMapper<DingDingMsgLog> {
+
+}

+ 18 - 0
alien-entity/src/main/java/shop/alien/entity/msg/dingding/mapper/DingDingRobotConfigMapper.java

@@ -0,0 +1,18 @@
+package shop.alien.entity.msg.dingding.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.springframework.stereotype.Repository;
+import shop.alien.entity.msg.dingding.entity.DingDingRobotConfig;
+
+/**
+ * 钉钉机器人配置Mapper
+ *
+ * @author ssk
+ * @since 2022-07-11
+ */
+@Mapper
+@Repository
+public interface DingDingRobotConfigMapper extends BaseMapper<DingDingRobotConfig> {
+
+}

+ 29 - 0
alien-entity/src/main/java/shop/alien/entity/msg/email/entity/EmailContent.java

@@ -0,0 +1,29 @@
+package shop.alien.entity.msg.email.entity;
+
+import lombok.Data;
+
+/**
+ * 邮件内容
+ *
+ * @author ssk
+ * @version 1.0
+ * @date 2022/8/19 17:18
+ */
+@Data
+public class EmailContent {
+
+    /**
+     * 标题
+     */
+    private String subject;
+
+    /**
+     * 文本
+     */
+    private String text;
+
+    /**
+     * 收件人(邮箱地址)
+     */
+    private String addressee;
+}

部分文件因为文件数量过多而无法显示