Browse Source

opensource init

lym 7 months ago
commit
ce22108d6d
92 changed files with 7664 additions and 0 deletions
  1. 90 0
      .drone.yml
  2. 29 0
      .gitignore
  3. 56 0
      README.md
  4. BIN
      icon.png
  5. 2705 0
      pom-update-schema-and-demo-data.sql
  6. 137 0
      pom-update-schema.sql
  7. 91 0
      pom.xml
  8. 160 0
      replaceAndStart.sh
  9. 23 0
      run.sh
  10. 134 0
      src/main/java/org/lym/pom/PojoMapConverter.java
  11. 24 0
      src/main/java/org/lym/pom/PomUpdateApplication.java
  12. 16 0
      src/main/java/org/lym/pom/annotation/ThirdProjectInfoSpider.java
  13. 45 0
      src/main/java/org/lym/pom/config/DependencyExtInfoProperties.java
  14. 23 0
      src/main/java/org/lym/pom/config/MailProperties.java
  15. 38 0
      src/main/java/org/lym/pom/config/MailSenderConfig.java
  16. 13 0
      src/main/java/org/lym/pom/config/ThirdExtInfoConfig.java
  17. 31 0
      src/main/java/org/lym/pom/config/VersionClientConfig.java
  18. 13 0
      src/main/java/org/lym/pom/constant/ContextKey.java
  19. 30 0
      src/main/java/org/lym/pom/constant/NewVersionNotifyStrategyEnum.java
  20. 47 0
      src/main/java/org/lym/pom/constant/NotifyTimeEnum.java
  21. 32 0
      src/main/java/org/lym/pom/constant/StableVersionPatterns.java
  22. 27 0
      src/main/java/org/lym/pom/constant/StatusEnum.java
  23. 44 0
      src/main/java/org/lym/pom/constant/ThirdProjectInfoSource.java
  24. 107 0
      src/main/java/org/lym/pom/constant/ThirdProjectInfoSourceEnum.java
  25. 39 0
      src/main/java/org/lym/pom/constant/ThirdProjectVersionStatusEnum.java
  26. 85 0
      src/main/java/org/lym/pom/controller/DependencyController.java
  27. 92 0
      src/main/java/org/lym/pom/controller/ProjectController.java
  28. 16 0
      src/main/java/org/lym/pom/controller/ThirdDependencyController.java
  29. 20 0
      src/main/java/org/lym/pom/dto/business/NotifyEmailBO.java
  30. 63 0
      src/main/java/org/lym/pom/dto/business/NotifyProjectBO.java
  31. 43 0
      src/main/java/org/lym/pom/dto/business/NotifyRecordBO.java
  32. 41 0
      src/main/java/org/lym/pom/dto/business/ThirdDependencyUpdateBO.java
  33. 18 0
      src/main/java/org/lym/pom/dto/xml/BuildDTO.java
  34. 20 0
      src/main/java/org/lym/pom/dto/xml/DependencyBaseDTO.java
  35. 11 0
      src/main/java/org/lym/pom/dto/xml/DependencyDTO.java
  36. 17 0
      src/main/java/org/lym/pom/dto/xml/DependencyManagementDTO.java
  37. 11 0
      src/main/java/org/lym/pom/dto/xml/PluginDTO.java
  38. 17 0
      src/main/java/org/lym/pom/dto/xml/PluginManagementDTO.java
  39. 41 0
      src/main/java/org/lym/pom/dto/xml/ProjectDTO.java
  40. 39 0
      src/main/java/org/lym/pom/entity/DependencyEntity.java
  41. 42 0
      src/main/java/org/lym/pom/entity/DependencyIndex.java
  42. 33 0
      src/main/java/org/lym/pom/entity/ListJpaConverter.java
  43. 81 0
      src/main/java/org/lym/pom/entity/NotifyRecordEntity.java
  44. 50 0
      src/main/java/org/lym/pom/entity/ProjectEntity.java
  45. 32 0
      src/main/java/org/lym/pom/entity/SetJpaConverter.java
  46. 95 0
      src/main/java/org/lym/pom/entity/ThirdProjectEntity.java
  47. 30 0
      src/main/java/org/lym/pom/entity/UserEntity.java
  48. 27 0
      src/main/java/org/lym/pom/notify/event/CheckProjectAllDependenciesEvent.java
  49. 27 0
      src/main/java/org/lym/pom/notify/event/DependencyInsertEvent.java
  50. 19 0
      src/main/java/org/lym/pom/notify/event/ProjectReLoadEvent.java
  51. 22 0
      src/main/java/org/lym/pom/notify/event/SendNotifyEvent.java
  52. 27 0
      src/main/java/org/lym/pom/notify/publisher/EventPublisher.java
  53. 38 0
      src/main/java/org/lym/pom/repository/IDependencyRepository.java
  54. 33 0
      src/main/java/org/lym/pom/repository/INotifyRecordRepository.java
  55. 28 0
      src/main/java/org/lym/pom/repository/IProjectRepository.java
  56. 29 0
      src/main/java/org/lym/pom/repository/IThirdProjectRepository.java
  57. 25 0
      src/main/java/org/lym/pom/repository/IUserRepository.java
  58. 261 0
      src/main/java/org/lym/pom/scheduled/SendNotifyTask.java
  59. 82 0
      src/main/java/org/lym/pom/scheduled/VersionWatcherTask.java
  60. 31 0
      src/main/java/org/lym/pom/service/IDependencyService.java
  61. 50 0
      src/main/java/org/lym/pom/service/INotifyRecordService.java
  62. 18 0
      src/main/java/org/lym/pom/service/INotifySendService.java
  63. 19 0
      src/main/java/org/lym/pom/service/IPomAnalyzerService.java
  64. 33 0
      src/main/java/org/lym/pom/service/IProjectService.java
  65. 15 0
      src/main/java/org/lym/pom/service/IThirdProjectInfoRefreshService.java
  66. 37 0
      src/main/java/org/lym/pom/service/IThirdProjectService.java
  67. 17 0
      src/main/java/org/lym/pom/service/IUserService.java
  68. 128 0
      src/main/java/org/lym/pom/service/impl/DependencyServiceImpl.java
  69. 174 0
      src/main/java/org/lym/pom/service/impl/NotifyRecordServiceImpl.java
  70. 80 0
      src/main/java/org/lym/pom/service/impl/NotifySendServiceImpl.java
  71. 24 0
      src/main/java/org/lym/pom/service/impl/PomAnalyzerServiceImpl.java
  72. 209 0
      src/main/java/org/lym/pom/service/impl/ProjectServiceImpl.java
  73. 210 0
      src/main/java/org/lym/pom/service/impl/ThirdProjectInfoRefreshServiceImpl.java
  74. 241 0
      src/main/java/org/lym/pom/service/impl/ThirdProjectServiceImpl.java
  75. 36 0
      src/main/java/org/lym/pom/service/impl/UserServiceImpl.java
  76. 35 0
      src/main/java/org/lym/pom/service/impl/select/BaseVersionSelector.java
  77. 32 0
      src/main/java/org/lym/pom/service/impl/select/DefaultVersionSelector.java
  78. 60 0
      src/main/java/org/lym/pom/service/impl/select/VersionComparators.java
  79. 44 0
      src/main/java/org/lym/pom/service/impl/select/VersionSelector.java
  80. 22 0
      src/main/java/org/lym/pom/service/impl/select/VersionSelectorManager.java
  81. 65 0
      src/main/java/org/lym/pom/test/TestController.java
  82. 49 0
      src/main/java/org/lym/pom/util/CleanIdeaFiles.java
  83. 134 0
      src/main/java/org/lym/pom/util/HttpsClientRequestFactory.java
  84. 23 0
      src/main/java/org/lym/pom/util/UserAgentInterceptor.java
  85. 111 0
      src/main/java/org/lym/pom/util/XmlUtil.java
  86. 43 0
      src/main/resources/application-dev.yml
  87. 41 0
      src/main/resources/application-prod.yml
  88. 97 0
      src/main/resources/application.yml
  89. BIN
      src/main/resources/static/favicon.ico
  90. BIN
      src/main/resources/static/favicon.png
  91. 29 0
      src/main/resources/static/index.html
  92. 88 0
      src/test/java/TestSpiderVersion.java

+ 90 - 0
.drone.yml

@@ -0,0 +1,90 @@
+# drone 自动构建
+name: test-project autodeploy
+kind: pipeline
+type: docker
+
+clone:
+  # 不需要拉取 commit 历史,加快速度
+  depth: 1
+  # 需要 clone
+  disable: false
+
+# drone 构建步骤
+steps:
+  - name: Compile & Package
+    pull: if-not-exists
+    image: cnlym/maven:3-jdk-11-alpine-aliyun
+    commands:
+      # 开始打包maven工程 跳过测试步骤
+      - mvn clean package -Dmaven.test.skip=true -T 1C
+      - cp target/executable.jar ./executable.jar
+
+  - name: Upload Jar
+    pull: if-not-exists
+    image: appleboy/drone-scp
+    settings:
+      host:
+        from_secret: ssh_host
+      username:
+        from_secret: ssh_user
+      password:
+        from_secret: ssh_pwd
+      port:
+        from_secret: ssh_port
+      target: /opt/bin/java
+      #cicd/${DRONE_REPO_NAME}
+      source: ./executable.jar
+
+    when:
+      branch:
+        - master
+
+  - name: SSH & Start
+    pull: if-not-exists
+    image: appleboy/drone-ssh
+    settings:
+      host:
+        from_secret: ssh_host
+      username:
+        from_secret: ssh_user
+      password:
+        from_secret: ssh_pwd
+      port:
+        from_secret: ssh_port
+      # TODO 【优化】cicd部署脚本未返回,而是10min超时,这个现象其他人也有遇到 https://github.com/appleboy/drone-ssh/issues/125
+      command_timeout: 9m
+      script:
+        # 运行部署脚本
+        #- cd /opt/bin/java/cicd
+        # 停掉进程
+        - /opt/bin/java/tryStop.sh
+        # 搬运之前的日志
+        - mkdir /opt/bin/java/historyLogs
+        - mv /opt/bin/java/logs /opt/bin/java/historyLogs/before_build_${DRONE_BUILD_NUMBER}
+        - mkdir /opt/bin/java/logs
+        - echo '${DRONE_BUILD_NUMBER}' > /opt/bin/java/logs/drone_ci_build.no
+        - date > /opt/bin/java/logs/drone_ci_build.time
+        - /opt/bin/java/run.sh
+        # 部署命令一定要放到drone的最后一条命令,这样在脚本中抛出异常退出后,drone可以捕捉到异常退出,将该次构建标记为构建失败
+        - /opt/bin/java/syncDetectAppHasStart.sh PomUpdateApplication
+    when:
+      branch:
+        - master
+    # 每5s检测health端口启动成功,10min超时
+    #  - name: SSH & Start
+    #    pull: if-not-exists
+    #    image: appleboy/drone-ssh
+
+  - name: Build Notification. --- with DingTalk
+    image: guoxudongdocker/drone-dingtalk
+    settings:
+      token:
+        from_secret: ding_token
+      type: markdown
+
+# drone执行触发分支
+trigger:
+  branch:
+    - master
+  event:
+    - push

+ 29 - 0
.gitignore

@@ -0,0 +1,29 @@
+# Compiled class file
+*.class
+target
+
+# Log file
+*.log
+/**/*.log.*
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# IDEA
+.idea
+*.iml
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*

+ 56 - 0
README.md

@@ -0,0 +1,56 @@
+# pom-update
+![icon.png](icon.png)
+## 一句话价值:
+急速检测直接依赖是否有更新 + 通知
+
+## 同类比较
+与 maven 的 `mvn versions:display-dependency-updates` 相比
+
+- pom-update 的第三方版本信息非实时(时间间隔3小时);maven 是实时检测的,每个依赖都需要至少访问一次中央仓库
+- pom-update 的检测时间在毫秒-秒级,并发检测 + 缓存(内存比较无网络);maven 的检测通常在分钟级,大型项目检测时往往几十分钟
+- pom-update 只检测直接依赖 / 自行管理版本的间接依赖,如依赖了 spring-boot,间接依赖(如spring-core) 的版本是不纳入检测的(当且仅当自己在 dependencyManager 中指定了它的版本或显示指定其版本依赖)有利于维护责任独立更轻量;maven 会检测所有依赖以及全部间接依赖
+- pom-update 是部署在服务端,不消耗客户端性能,检测时直接出结果;maven 的必须要客户端等待检测结果
+- pom-update 可定时检测,支持订阅,如每周发送更新邮件,并能根据是否稳定版设置是否发送邮件通知;maven 不可以
+
+**总结:**
+
+- pom-update 秒级出检测结果,不需要数十分钟等待获取一大堆自己部管理也不关心的间接依赖版本
+- pom-update 支持订阅,如每周发送本项目的所有依赖版本变化情况
+
+
+## 本地运行
+
+1. git clone 本工程
+2. 确保有可连接的数据库,将表结构和示例数据导入数据库 [pom-update-schema-and-demo-data.sql](pom-update-schema-and-demo-data.sql)
+3. 修改配置文件 或 添加环境变量(二选一)
+```text
+# 邮箱,如 demo@qq.com
+TEST_SENDER_EMAIL
+# 邮箱 SFTP token,自行搜索获取
+TEST_EMAIL_TOKEN
+# MYSQL 地址、用户名、密码
+MYSQL_ADDR
+MYSQL_PWD
+```
+
+## 测试 API
+http://localhost:12345/index.html
+选择 pom 输入希望接受邮件的邮箱 cn_lym@foxmail.com
+
+http://localhost:12345/test/version
+检查所有工程 version
+
+http://localhost:12345/test/notify
+给所有需要更新的人发邮件通知
+
+调整通知策略
+http://localhost:12345/dependencies/updateNotifyStrategy?projectId=10&notifyStrategy=ALWAYS&email=cn_lym@foxmail.com
+
+```bash
+curl --location --request POST 'http://localhost:12345/projects/create' --form 'email=yourEmail@yourEmail.com' --form 'pomXml=@shoulder-dependencies/pom.xml' --form 'notifyInstantlyAfterCheck=true' --form 'notifyReason=CI-<a href="https://cicd.yourdomain.com/xxx/${DRONE_REPO_NAME}">${DRONE_REPO_NAME}::${DRONE_REPO_BRANCH}</a><br> with <a href="https://cicd.yourdomain.cn/gogs/${DRONE_REPO_NAME}/${DRONE_BUILD_NUMBER}">Drone Build-${DRONE_BUILD_NUMBER}</a><br>' || echo '======= SKIP dependency check. ======='
+```
+
+---
+
+没有服务器的小伙伴若想拥有一个自己的服务器,可以尝试通过 github 的 actions 等 CI 工具、或者留言~
+

BIN
icon.png


+ 2705 - 0
pom-update-schema-and-demo-data.sql

@@ -0,0 +1,2705 @@
+-- MySQL dump 10.13  Distrib 8.0.17, for Win64 (x86_64)
+--
+-- Host: localhost    Database: db_pom_update
+-- ------------------------------------------------------
+-- Server version	8.0.27
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!50503 SET NAMES utf8mb4 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `tb_user`
+--
+
+DROP TABLE IF EXISTS `tb_user`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!50503 SET character_set_client = utf8mb4 */;
+CREATE TABLE `tb_user`
+(
+    `id`                                  varchar(64) COLLATE utf8_unicode_ci NOT NULL,
+    `account`                             varchar(32) COLLATE utf8_unicode_ci  DEFAULT NULL,
+    `password`                            varchar(128) COLLATE utf8_unicode_ci DEFAULT NULL,
+    `name`                                varchar(32) COLLATE utf8_unicode_ci  DEFAULT NULL,
+    `email`                               varchar(64) COLLATE utf8_unicode_ci  DEFAULT NULL,
+    `phone`                               varchar(16) COLLATE utf8_unicode_ci  DEFAULT NULL,
+    `default_new_version_notify_strategy` varchar(16) COLLATE utf8_unicode_ci NOT NULL,
+    `create_time`                         datetime                             DEFAULT NULL,
+    PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `tb_project`
+--
+
+DROP TABLE IF EXISTS `tb_project`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!50503 SET character_set_client = utf8mb4 */;
+CREATE TABLE `tb_project`
+(
+    `id`          bigint                              NOT NULL AUTO_INCREMENT,
+    `group_id`    varchar(64) COLLATE utf8_unicode_ci NOT NULL,
+    `artifact_id` varchar(64) COLLATE utf8_unicode_ci NOT NULL,
+    `version`     varchar(64) COLLATE utf8_unicode_ci  DEFAULT NULL,
+    `name`        varchar(128) COLLATE utf8_unicode_ci DEFAULT NULL,
+    `description` varchar(512) COLLATE utf8_unicode_ci DEFAULT NULL,
+    `user_id`     varchar(64) COLLATE utf8_unicode_ci NOT NULL,
+    `status`      varchar(16) COLLATE utf8_unicode_ci  DEFAULT 'NOMARL',
+    `create_time` datetime                             DEFAULT NULL,
+    `update_time` datetime                             DEFAULT NULL,
+    PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8mb3 COLLATE=utf8_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `tb_dependency`
+--
+
+DROP TABLE IF EXISTS `tb_dependency`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!50503 SET character_set_client = utf8mb4 */;
+CREATE TABLE `tb_dependency`
+(
+    `id`                          bigint                              NOT NULL AUTO_INCREMENT,
+    `project_id`                  bigint                              NOT NULL,
+    `group_id`                    varchar(64) COLLATE utf8_unicode_ci NOT NULL,
+    `artifact_id`                 varchar(64) COLLATE utf8_unicode_ci NOT NULL,
+    `version`                     varchar(64) COLLATE utf8_unicode_ci NOT NULL,
+    `new_version_notify_strategy` varchar(32) COLLATE utf8_unicode_ci DEFAULT 'STABLE_ONLY',
+    PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=5522 DEFAULT CHARSET=utf8mb3 COLLATE=utf8_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `tb_third_project`
+--
+
+DROP TABLE IF EXISTS `tb_third_project`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!50503 SET character_set_client = utf8mb4 */;
+CREATE TABLE `tb_third_project`
+(
+    `group_id`               varchar(64) COLLATE utf8_unicode_ci NOT NULL,
+    `artifact_id`            varchar(64) COLLATE utf8_unicode_ci NOT NULL,
+    `version`                varchar(64) COLLATE utf8_unicode_ci  DEFAULT NULL,
+    `stable_version`         varchar(64) COLLATE utf8_unicode_ci  DEFAULT NULL,
+    `name`                   varchar(128) COLLATE utf8_unicode_ci DEFAULT NULL,
+    `description`            varchar(512) COLLATE utf8_unicode_ci DEFAULT NULL,
+    `home_url`               varchar(512) COLLATE utf8_unicode_ci DEFAULT NULL,
+    `change_log_url`         varchar(512) COLLATE utf8_unicode_ci DEFAULT NULL,
+    `open_source_protocol`   varchar(64) COLLATE utf8_unicode_ci  DEFAULT NULL,
+    `stable_version_pattern` varchar(64) COLLATE utf8_unicode_ci  DEFAULT NULL,
+    `version_rule`           varchar(32) COLLATE utf8_unicode_ci  DEFAULT NULL,
+    `status`                 varchar(32) COLLATE utf8_unicode_ci  DEFAULT NULL,
+    `update_time`            datetime                             DEFAULT NULL,
+    PRIMARY KEY (`group_id`, `artifact_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `tb_notify_record`
+--
+
+DROP TABLE IF EXISTS `tb_notify_record`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!50503 SET character_set_client = utf8mb4 */;
+CREATE TABLE `tb_notify_record`
+(
+    `id`              bigint NOT NULL AUTO_INCREMENT,
+    `project_id`      bigint                              DEFAULT NULL,
+    `group_id`        varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
+    `artifact_id`     varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
+    `current_version` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
+    `new_version`     varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
+    `notified`        tinyint(1) DEFAULT NULL,
+    `notify_time`     datetime                            DEFAULT NULL,
+    PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=843 DEFAULT CHARSET=utf8mb3 COLLATE=utf8_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2023-10-03 17:37:55
+
+
+
+-------------------------------
+
+
+--
+-- Dumping data for table `tb_user`
+--
+
+LOCK
+TABLES `tb_user` WRITE;
+/*!40000 ALTER TABLE `tb_user` DISABLE KEYS */;
+INSERT INTO `tb_user`
+VALUES ('1', 'demoUsername', 'demoPwd', 'demoName', 'demo@mail.com', '12345678901', 'ALWAYS', '2020-03-30 00:07:13');
+/*!40000 ALTER TABLE `tb_user` ENABLE KEYS */;
+UNLOCK
+TABLES;
+/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
+
+--
+-- Dumping data for table `tb_dependency`
+--
+
+LOCK
+TABLES `tb_dependency` WRITE;
+/*!40000 ALTER TABLE `tb_dependency` DISABLE KEYS */;
+INSERT INTO `tb_dependency`
+VALUES (499, 3, 'org.springframework.boot', 'spring-boot-starter-parent', '2.4.5', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (500, 3, 'org.springframework.cloud', 'spring-cloud-dependencies', '2020.0.2', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (501, 3, 'cn.itlym.shoulder', 'lombok', '0.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (502, 3, 'cn.itlym', 'shoulder-core', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (503, 3, 'cn.itlym', 'shoulder-cluster', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (504, 3, 'cn.itlym', 'shoulder-crypto', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (505, 3, 'cn.itlym', 'shoulder-crypto-negotiation', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (506, 3, 'cn.itlym', 'shoulder-operation-log', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (507, 3, 'cn.itlym', 'shoulder-batch', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (508, 3, 'cn.itlym', 'shoulder-security', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (509, 3, 'cn.itlym', 'shoulder-security-code', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (510, 3, 'cn.itlym', 'shoulder-data-db', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (511, 3, 'cn.itlym', 'shoulder-http', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (512, 3, 'cn.itlym', 'shoulder-validation', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (513, 3, 'cn.itlym', 'shoulder-web', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (514, 3, 'cn.itlym', 'shoulder-api-doc', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (515, 3, 'cn.itlym', 'shoulder-monitor', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (516, 3, 'cn.itlym', 'shoulder-autoconfiguration', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (517, 3, 'cn.itlym', 'shoulder-starter', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (518, 3, 'cn.itlym', 'shoulder-starter-mysql', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (519, 3, 'cn.itlym', 'shoulder-starter-web', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (520, 3, 'cn.itlym', 'shoulder-starter-operation-log', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (521, 3, 'cn.itlym', 'shoulder-starter-beanmap', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (522, 3, 'cn.itlym', 'shoulder-starter-auth-session', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (523, 3, 'cn.itlym', 'shoulder-starter-auth-token', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (524, 3, 'cn.itlym', 'shoulder-starter-auth-server', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (525, 3, 'cn.itlym', 'shoulder-starter-security-code', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (526, 3, 'cn.itlym', 'shoulder-starter-crypto', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (527, 3, 'cn.itlym', 'shoulder-starter-monitor', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (528, 3, 'cn.itlym', 'shoulder-ext-common', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (529, 3, 'cn.itlym', 'shoulder-ext-config', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (530, 3, 'cn.itlym', 'shoulder-ext-dictionary', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (531, 3, 'cn.itlym', 'shoulder-ext-autoconfiguration', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (532, 3, 'io.swagger', 'swagger-annotations', '1.6.2', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (533, 3, 'io.swagger.core.v3', 'swagger-annotations', '2.1.9', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (534, 3, 'io.springfox', 'springfox-core', '3.0.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (535, 3, 'io.springfox', 'springfox-boot-starter', '3.0.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (536, 3, 'com.github.xiaoymin', 'knife4j-spring-ui', '3.0.2', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (537, 3, 'com.github.xiaoymin', 'knife4j-spring-boot-starter', '3.0.2', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (538, 3, 'org.springframework.security.oauth.boot', 'spring-security-oauth2-autoconfigure', '2.4.5',
+        'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (539, 3, 'org.springframework.security.oauth', 'spring-security-oauth2', '2.5.0.RELEASE', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (540, 3, 'com.nimbusds', 'nimbus-jose-jwt', '8.21', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (541, 3, 'org.springframework.security.experimental', 'spring-security-oauth2-authorization-server', '0.1.0',
+        'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (542, 3, 'com.univocity', 'univocity-parsers', '2.9.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (543, 3, 'com.thoughtworks.xstream', 'xstream', '1.4.17', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (544, 3, 'commons-codec', 'commons-codec', '1.15', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (545, 3, 'org.apache.commons', 'commons-collections4', '4.4', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (546, 3, 'commons-io', 'commons-io', '2.8.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (547, 3, 'commons-configuration', 'commons-configuration', '1.10', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (548, 3, 'org.apache.commons', 'commons-lang3', '3.11', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (549, 3, 'commons-daemon', 'commons-daemon', '1.2.4', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (550, 3, 'org.javassist', 'javassist', '3.27.0-GA', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (551, 3, 'javax.ws.rs', 'javax.ws.rs-api', '2.1.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (552, 3, 'com.belerweb', 'pinyin4j', '2.5.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (553, 3, 'cn.hutool', 'hutool-core', '5.6.3', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (554, 3, 'cn.hutool', 'hutool-all', '5.6.3', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (555, 3, 'cn.hutool', 'hutool-http', '5.6.3', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (556, 3, 'com.google.guava', 'guava', '30.1.1-jre', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (557, 3, 'com.google.code.findbugs', 'annotations', '3.0.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (558, 3, 'net.java.dev.jna', 'jna', '5.8.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (559, 3, 'org.mapstruct', 'mapstruct', '1.4.2.Final', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (560, 3, 'org.mapstruct', 'mapstruct-processor', '1.4.2.Final', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (561, 3, 'com.alibaba', 'transmittable-thread-local', '2.12.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (562, 3, 'org.bouncycastle', 'bcprov-jdk15on', '1.68', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (563, 3, 'org.bouncycastle', 'bcpkix-jdk15on', '1.68', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (564, 3, 'org.apache.tika', 'tika-core', '1.24.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (565, 3, 'com.github.chris2018998', 'beecp', '3.1.7', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (566, 3, 'p6spy', 'p6spy', '3.9.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (567, 3, 'com.h2database', 'h2', '1.4.200', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (568, 3, 'com.baomidou', 'mybatis-plus-boot-starter', '3.4.2', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (569, 3, 'com.baomidou', 'mybatis-plus-generator', '3.4.2', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (570, 3, 'com.github.pagehelper', 'pagehelper', '5.2.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (571, 3, 'com.github.pagehelper', 'pagehelper-spring-boot-starter', '1.3.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (572, 3, 'org.mockito', 'mockito-all', '1.10.19', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (573, 3, 'org.powermock', 'powermock-module-junit4', '2.0.9', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (574, 3, 'org.powermock', 'powermock-api-mockito', '2.0.9', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (575, 3, 'org.powermock', 'powermock-api-mockito2', '2.0.9', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (576, 3, 'org.springframework.boot', 'spring-boot-starter-parent', '2.4.5', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (577, 3, 'org.springframework.cloud', 'spring-cloud-dependencies', '2020.0.2', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (578, 3, 'cn.itlym.shoulder', 'lombok', '0.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (579, 3, 'cn.itlym', 'shoulder-core', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (580, 3, 'cn.itlym', 'shoulder-cluster', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (581, 3, 'cn.itlym', 'shoulder-crypto', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (582, 3, 'cn.itlym', 'shoulder-crypto-negotiation', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (583, 3, 'cn.itlym', 'shoulder-operation-log', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (584, 3, 'cn.itlym', 'shoulder-batch', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (585, 3, 'cn.itlym', 'shoulder-security', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (586, 3, 'cn.itlym', 'shoulder-security-code', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (587, 3, 'cn.itlym', 'shoulder-data-db', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (588, 3, 'cn.itlym', 'shoulder-http', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (589, 3, 'cn.itlym', 'shoulder-validation', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (590, 3, 'cn.itlym', 'shoulder-web', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (591, 3, 'cn.itlym', 'shoulder-api-doc', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (592, 3, 'cn.itlym', 'shoulder-monitor', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (593, 3, 'cn.itlym', 'shoulder-autoconfiguration', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (594, 3, 'cn.itlym', 'shoulder-starter', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (595, 3, 'cn.itlym', 'shoulder-starter-mysql', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (596, 3, 'cn.itlym', 'shoulder-starter-web', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (597, 3, 'cn.itlym', 'shoulder-starter-operation-log', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (598, 3, 'cn.itlym', 'shoulder-starter-beanmap', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (599, 3, 'cn.itlym', 'shoulder-starter-auth-session', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (600, 3, 'cn.itlym', 'shoulder-starter-auth-token', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (601, 3, 'cn.itlym', 'shoulder-starter-auth-server', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (602, 3, 'cn.itlym', 'shoulder-starter-security-code', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (603, 3, 'cn.itlym', 'shoulder-starter-crypto', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (604, 3, 'cn.itlym', 'shoulder-starter-monitor', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (605, 3, 'cn.itlym', 'shoulder-ext-common', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (606, 3, 'cn.itlym', 'shoulder-ext-config', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (607, 3, 'cn.itlym', 'shoulder-ext-dictionary', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (608, 3, 'cn.itlym', 'shoulder-ext-autoconfiguration', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (609, 3, 'io.swagger', 'swagger-annotations', '1.6.2', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (610, 3, 'io.swagger.core.v3', 'swagger-annotations', '2.1.9', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (611, 3, 'io.springfox', 'springfox-core', '3.0.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (612, 3, 'io.springfox', 'springfox-boot-starter', '3.0.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (613, 3, 'com.github.xiaoymin', 'knife4j-spring-ui', '3.0.2', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (614, 3, 'com.github.xiaoymin', 'knife4j-spring-boot-starter', '3.0.2', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (615, 3, 'org.springframework.security.oauth.boot', 'spring-security-oauth2-autoconfigure', '2.4.5',
+        'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (616, 3, 'org.springframework.security.oauth', 'spring-security-oauth2', '2.5.0.RELEASE', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (617, 3, 'com.nimbusds', 'nimbus-jose-jwt', '8.21', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (618, 3, 'org.springframework.security.experimental', 'spring-security-oauth2-authorization-server', '0.1.0',
+        'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (619, 3, 'com.univocity', 'univocity-parsers', '2.9.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (620, 3, 'com.thoughtworks.xstream', 'xstream', '1.4.17', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (621, 3, 'commons-codec', 'commons-codec', '1.15', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (622, 3, 'org.apache.commons', 'commons-collections4', '4.4', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (623, 3, 'commons-io', 'commons-io', '2.8.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (624, 3, 'commons-configuration', 'commons-configuration', '1.10', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (625, 3, 'org.apache.commons', 'commons-lang3', '3.11', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (626, 3, 'commons-daemon', 'commons-daemon', '1.2.4', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (627, 3, 'org.javassist', 'javassist', '3.27.0-GA', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (628, 3, 'javax.ws.rs', 'javax.ws.rs-api', '2.1.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (629, 3, 'com.belerweb', 'pinyin4j', '2.5.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (630, 3, 'cn.hutool', 'hutool-core', '5.6.3', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (631, 3, 'cn.hutool', 'hutool-all', '5.6.3', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (632, 3, 'cn.hutool', 'hutool-http', '5.6.3', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (633, 3, 'com.google.guava', 'guava', '30.1.1-jre', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (634, 3, 'com.google.code.findbugs', 'annotations', '3.0.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (635, 3, 'net.java.dev.jna', 'jna', '5.8.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (636, 3, 'org.mapstruct', 'mapstruct', '1.4.2.Final', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (637, 3, 'org.mapstruct', 'mapstruct-processor', '1.4.2.Final', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (638, 3, 'com.alibaba', 'transmittable-thread-local', '2.12.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (639, 3, 'org.bouncycastle', 'bcprov-jdk15on', '1.68', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (640, 3, 'org.bouncycastle', 'bcpkix-jdk15on', '1.68', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (641, 3, 'org.apache.tika', 'tika-core', '1.24.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (642, 3, 'com.github.chris2018998', 'beecp', '3.1.7', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (643, 3, 'p6spy', 'p6spy', '3.9.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (644, 3, 'com.h2database', 'h2', '1.4.200', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (645, 3, 'com.baomidou', 'mybatis-plus-boot-starter', '3.4.2', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (646, 3, 'com.baomidou', 'mybatis-plus-generator', '3.4.2', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (647, 3, 'com.github.pagehelper', 'pagehelper', '5.2.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (648, 3, 'com.github.pagehelper', 'pagehelper-spring-boot-starter', '1.3.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (649, 3, 'org.mockito', 'mockito-all', '1.10.19', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (650, 3, 'org.powermock', 'powermock-module-junit4', '2.0.9', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (651, 3, 'org.powermock', 'powermock-api-mockito', '2.0.9', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (652, 3, 'org.powermock', 'powermock-api-mockito2', '2.0.9', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (1786, 11, 'org.jsoup', 'jsoup', '1.15.4', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (1787, 11, 'org.lz4', 'lz4-java', '1.8.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (1788, 11, 'com.aliyun.oss', 'aliyun-sdk-oss', '3.8.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (1789, 11, 'javax.xml.bind', 'jaxb-api', '2.3.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (1790, 11, 'javax.activation', 'activation', '1.1.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (1791, 11, 'org.glassfish.jaxb', 'jaxb-runtime', '2.3.3', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (1792, 11, 'net.sourceforge.tess4j', 'tess4j', '5.6.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (3760, 12, 'cn.itlym', 'shoulder-dependencies', '0.7-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (3761, 12, 'cn.itlym.shoulder', 'shoulder-maven-plugin', '1.2.1-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (3762, 12, 'org.apache.maven.plugins', 'maven-compiler-plugin', '3.11.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (3763, 12, 'org.codehaus.mojo', 'license-maven-plugin', '2.0.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (3764, 12, 'org.apache.maven.plugins', 'maven-source-plugin', '3.2.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (3765, 12, 'org.apache.maven.plugins', 'maven-javadoc-plugin', '3.2.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (3766, 12, 'org.apache.maven.plugins', 'maven-gpg-plugin', '3.1.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (3767, 12, 'org.codehaus.mojo', 'findbugs-maven-plugin', '3.0.5', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (3768, 12, 'org.apache.maven.plugins', 'maven-surefire-plugin', '3.0.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (3769, 12, 'org.codehaus.mojo', 'cobertura-maven-plugin', '2.7', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (3770, 12, 'org.codehaus.mojo', 'sonar-maven-plugin', '3.7.0.1746', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (3771, 12, 'org.codehaus.mojo', 'versions-maven-plugin', '2.7', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (3772, 12, 'org.apache.maven.plugins', 'maven-jar-plugin', '3.3.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (3773, 12, 'pl.project13.maven', 'git-commit-id-plugin', '2.1.5', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (3774, 13, 'org.codehaus.mojo', 'license-maven-plugin', '2.2.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (3775, 13, 'org.sonatype.plugins', 'nexus-staging-maven-plugin', '1.6.13', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (3776, 13, 'org.apache.maven.plugins', 'maven-gpg-plugin', '3.0.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (3864, 23, 'org.apache.maven.plugins', 'maven-resources-plugin', '3.3.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (3865, 23, 'org.apache.maven.plugins', 'maven-archetype-plugin', '3.2.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5443, 10, 'cn.itlym', 'shoulder-framework', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5444, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5445, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5446, 10, 'org.projectlombok', 'lombok', '1.18.30', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5447, 10, 'cn.itlym.shoulder', 'lombok', '0.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5448, 10, 'org.redisson', 'redisson', '3.23.5', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5449, 10, 'cn.itlym', 'shoulder-core', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5450, 10, 'cn.itlym', 'shoulder-cluster', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5451, 10, 'cn.itlym', 'shoulder-crypto', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5452, 10, 'cn.itlym', 'shoulder-crypto-negotiation', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5453, 10, 'cn.itlym', 'shoulder-operation-log', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5454, 10, 'cn.itlym', 'shoulder-batch', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5455, 10, 'cn.itlym', 'shoulder-security', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5456, 10, 'cn.itlym', 'shoulder-security-code', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5457, 10, 'cn.itlym', 'shoulder-data-db', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5458, 10, 'cn.itlym', 'shoulder-http', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5459, 10, 'cn.itlym', 'shoulder-validation', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5460, 10, 'cn.itlym', 'shoulder-web', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5461, 10, 'cn.itlym', 'shoulder-api-doc', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5462, 10, 'cn.itlym', 'shoulder-monitor', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5463, 10, 'cn.itlym', 'shoulder-autoconfiguration', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5464, 10, 'cn.itlym', 'shoulder-starter', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5465, 10, 'cn.itlym', 'shoulder-starter-mysql', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5466, 10, 'cn.itlym', 'shoulder-starter-web', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5467, 10, 'cn.itlym', 'shoulder-starter-operation-log', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5468, 10, 'cn.itlym', 'shoulder-starter-auth-session', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5469, 10, 'cn.itlym', 'shoulder-starter-auth-token', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5470, 10, 'cn.itlym', 'shoulder-starter-auth-server', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5471, 10, 'cn.itlym', 'shoulder-starter-security-code', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5472, 10, 'cn.itlym', 'shoulder-starter-crypto', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5473, 10, 'cn.itlym', 'shoulder-starter-monitor', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5474, 10, 'cn.itlym', 'shoulder-ext-common', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5475, 10, 'cn.itlym', 'shoulder-ext-config', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5476, 10, 'cn.itlym', 'shoulder-ext-dictionary', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5477, 10, 'cn.itlym', 'shoulder-ext-autoconfiguration', '0.8-SNAPSHOT', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5478, 10, 'io.swagger', 'swagger-annotations', '1.6.11', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5479, 10, 'io.swagger.core.v3', 'swagger-annotations', '2.2.16', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5480, 10, 'io.springfox', 'springfox-core', '3.0.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5481, 10, 'io.springfox', 'springfox-boot-starter', '3.0.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5482, 10, 'com.github.xiaoymin', 'knife4j-spring-ui', '3.0.3', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5483, 10, 'com.github.xiaoymin', 'knife4j-spring-boot-starter', '3.0.3', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5484, 10, 'org.springframework.security.oauth.boot', 'spring-security-oauth2-autoconfigure', '2.6.8',
+        'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5485, 10, 'org.springframework.security.oauth', 'spring-security-oauth2', '2.5.2.RELEASE', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5486, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.35', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5487, 10, 'org.springframework.security.experimental', 'spring-security-oauth2-authorization-server', '0.1.2',
+        'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5488, 10, 'com.univocity', 'univocity-parsers', '2.9.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5489, 10, 'com.thoughtworks.xstream', 'xstream', '1.4.20', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5490, 10, 'commons-codec', 'commons-codec', '1.16.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5491, 10, 'org.apache.commons', 'commons-collections4', '4.4', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5492, 10, 'commons-io', 'commons-io', '2.13.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5493, 10, 'commons-configuration', 'commons-configuration', '1.10', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5494, 10, 'org.apache.commons', 'commons-lang3', '3.13.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5495, 10, 'commons-daemon', 'commons-daemon', '1.3.4', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5496, 10, 'org.javassist', 'javassist', '3.29.2-GA', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5497, 10, 'javax.ws.rs', 'javax.ws.rs-api', '2.1.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5498, 10, 'com.belerweb', 'pinyin4j', '2.5.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5499, 10, 'cn.hutool', 'hutool-core', '5.8.22', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5500, 10, 'cn.hutool', 'hutool-all', '5.8.22', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5501, 10, 'cn.hutool', 'hutool-http', '5.8.22', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5502, 10, 'com.google.guava', 'guava', '32.1.2-jre', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5503, 10, 'com.google.code.findbugs', 'annotations', '3.0.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5504, 10, 'net.java.dev.jna', 'jna', '5.13.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5505, 10, 'org.mapstruct', 'mapstruct', '1.5.5.Final', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5506, 10, 'org.mapstruct', 'mapstruct-processor', '1.5.5.Final', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5507, 10, 'com.alibaba', 'transmittable-thread-local', '2.14.3', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5508, 10, 'org.bouncycastle', 'bcprov-jdk15on', '1.70', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5509, 10, 'org.bouncycastle', 'bcpkix-jdk15on', '1.70', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5510, 10, 'org.apache.tika', 'tika-core', '2.9.0', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5511, 10, 'com.github.chris2018998', 'beecp', '3.4.2', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5512, 10, 'p6spy', 'p6spy', '3.9.1', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5513, 10, 'com.h2database', 'h2', '2.2.224', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5514, 10, 'com.baomidou', 'mybatis-plus-boot-starter', '3.5.3.2', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5515, 10, 'com.baomidou', 'mybatis-plus-generator', '3.5.3.2', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5516, 10, 'com.github.pagehelper', 'pagehelper', '5.3.3', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5517, 10, 'com.github.pagehelper', 'pagehelper-spring-boot-starter', '1.4.7', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5518, 10, 'org.mockito', 'mockito-all', '1.10.19', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5519, 10, 'org.powermock', 'powermock-module-junit4', '2.0.9', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5520, 10, 'org.powermock', 'powermock-api-mockito', '2.0.9', 'STABLE_ONLY');
+INSERT INTO `tb_dependency`
+VALUES (5521, 10, 'org.powermock', 'powermock-api-mockito2', '2.0.9', 'STABLE_ONLY');
+/*!40000 ALTER TABLE `tb_dependency` ENABLE KEYS */;
+UNLOCK
+TABLES;
+
+--
+-- Dumping data for table `tb_notify_record`
+--
+
+LOCK
+TABLES `tb_notify_record` WRITE;
+/*!40000 ALTER TABLE `tb_notify_record` DISABLE KEYS */;
+INSERT INTO `tb_notify_record`
+VALUES (1, 3, 'cn.hutool', 'hutool-all', '5.6.3', '5.6.4', 1, '2021-05-30 03:25:19');
+INSERT INTO `tb_notify_record`
+VALUES (2, 3, 'com.alibaba', 'transmittable-thread-local', '2.12.0', '2.13.0-Beta1', 1, '2021-05-30 03:14:53');
+INSERT INTO `tb_notify_record`
+VALUES (3, 3, 'com.baomidou', 'mybatis-plus-boot-starter', '3.4.0', '3.4.2', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (4, 3, 'com.baomidou', 'mybatis-plus-generator', '3.4.0', '3.4.1', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (5, 3, 'com.google.code.findbugs', 'annotations', '3.0.0', '3.0.1u2', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (6, 3, 'com.google.guava', 'guava', '29.0-jre', 'r09', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (7, 3, 'com.nimbusds', 'nimbus-jose-jwt', '8.21', '9.8.1', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (8, 3, 'commons-codec', 'commons-codec', '1.14', '20041127.091804', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (9, 3, 'commons-configuration', 'commons-configuration', '1.9', '20041012.002804', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (10, 3, 'commons-daemon', 'commons-daemon', '1.2.2', '1.2.4', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (11, 3, 'commons-io', 'commons-io', '2.7', '20030203.000550', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (12, 3, 'io.swagger', 'swagger-annotations', '1.6.2', '2.0.0-rc2', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (13, 3, 'io.swagger.core.v3', 'swagger-annotations', '2.1.2', '2.1.9', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (14, 3, 'javax.ws.rs', 'javax.ws.rs-api', '2.1.1', '2.1-m09', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (15, 3, 'net.java.dev.jna', 'jna', '5.5.0', '5.8.0', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (16, 3, 'org.apache.commons', 'commons-lang3', '3.11', '3.12.0', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (17, 3, 'org.apache.tika', 'tika-core', '1.24.1', '2.0.0-ALPHA', 1, '2021-05-30 02:23:19');
+INSERT INTO `tb_notify_record`
+VALUES (18, 3, 'org.bouncycastle', 'bcpkix-jdk15on', '1.66', '1.68', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (19, 3, 'org.bouncycastle', 'bcprov-jdk15on', '1.66', '1.68', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (20, 3, 'org.mockito', 'mockito-all', '1.10.19', '2.0.2-beta', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (21, 3, 'org.powermock', 'powermock-api-mockito2', '1.7.4', '2.0.9', 1, '2021-05-29 23:23:11');
+INSERT INTO `tb_notify_record`
+VALUES (22, 3, 'org.powermock', 'powermock-module-junit4', '1.7.4', '2.0.9', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (23, 3, 'org.springframework.cloud', 'spring-cloud-dependencies', '2020.0.2', 'Hoxton.SR9', 1,
+        '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (24, 3, 'org.springframework.security.oauth', 'spring-security-oauth2', '2.5.0.RELEASE', '2.5.1.RELEASE', 1,
+        '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (25, 3, 'cn.hutool', 'hutool-all', '5.6.3', '5.6.4', 1, '2021-05-30 03:28:14');
+INSERT INTO `tb_notify_record`
+VALUES (26, 3, 'com.alibaba', 'transmittable-thread-local', '2.12.0', '2.13.0-Beta1', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (27, 3, 'com.baomidou', 'mybatis-plus-boot-starter', '3.4.0', '3.4.2', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (28, 3, 'com.baomidou', 'mybatis-plus-generator', '3.4.0', '3.4.1', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (29, 3, 'com.google.code.findbugs', 'annotations', '3.0.0', '3.0.1u2', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (30, 3, 'com.google.guava', 'guava', '29.0-jre', 'r09', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (31, 3, 'com.nimbusds', 'nimbus-jose-jwt', '8.21', '9.8.1', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (32, 3, 'commons-codec', 'commons-codec', '1.14', '20041127.091804', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (33, 3, 'commons-configuration', 'commons-configuration', '1.9', '20041012.002804', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (34, 3, 'commons-daemon', 'commons-daemon', '1.2.2', '1.2.4', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (35, 3, 'commons-io', 'commons-io', '2.7', '20030203.000550', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (36, 3, 'io.swagger', 'swagger-annotations', '1.6.2', '2.0.0-rc2', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (37, 3, 'io.swagger.core.v3', 'swagger-annotations', '2.1.2', '2.1.9', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (38, 3, 'javax.ws.rs', 'javax.ws.rs-api', '2.1.1', '2.1-m09', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (39, 3, 'net.java.dev.jna', 'jna', '5.5.0', '5.8.0', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (40, 3, 'org.apache.commons', 'commons-lang3', '3.11', '3.12.0', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (41, 3, 'org.apache.tika', 'tika-core', '1.24.1', '2.0.0-ALPHA', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (42, 3, 'org.bouncycastle', 'bcpkix-jdk15on', '1.66', '1.68', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (43, 3, 'org.bouncycastle', 'bcprov-jdk15on', '1.66', '1.68', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (44, 3, 'org.mockito', 'mockito-all', '1.10.19', '2.0.2-beta', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (45, 3, 'org.powermock', 'powermock-api-mockito2', '1.7.4', '2.0.9', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (46, 3, 'org.powermock', 'powermock-module-junit4', '1.7.4', '2.0.9', 1, '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (47, 3, 'org.springframework.cloud', 'spring-cloud-dependencies', '2020.0.2', 'Hoxton.SR9', 1,
+        '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (48, 3, 'org.springframework.security.oauth', 'spring-security-oauth2', '2.5.0.RELEASE', '2.5.1.RELEASE', 1,
+        '2021-04-26 02:29:59');
+INSERT INTO `tb_notify_record`
+VALUES (49, 3, 'cn.hutool', 'hutool-all', '5.6.3', '5.6.4', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (50, 3, 'com.alibaba', 'transmittable-thread-local', '2.12.0', '2.13.0-Beta1', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (51, 3, 'com.baomidou', 'mybatis-plus-boot-starter', '3.4.0', '3.4.2', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (52, 3, 'com.baomidou', 'mybatis-plus-generator', '3.4.0', '3.4.1', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (53, 3, 'com.nimbusds', 'nimbus-jose-jwt', '8.21', '9.8.1', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (54, 3, 'commons-daemon', 'commons-daemon', '1.2.2', '1.2.4', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (55, 3, 'io.swagger', 'swagger-annotations', '1.6.2', '2.0.0-rc2', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (56, 3, 'io.swagger.core.v3', 'swagger-annotations', '2.1.2', '2.1.9', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (57, 3, 'net.java.dev.jna', 'jna', '5.5.0', '5.8.0', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (58, 3, 'org.apache.commons', 'commons-lang3', '3.11', '3.12.0', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (59, 3, 'org.apache.tika', 'tika-core', '1.24.1', '2.0.0-ALPHA', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (60, 3, 'org.bouncycastle', 'bcpkix-jdk15on', '1.66', '1.68', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (61, 3, 'org.bouncycastle', 'bcprov-jdk15on', '1.66', '1.68', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (62, 3, 'org.mockito', 'mockito-all', '1.10.19', '2.0.2-beta', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (63, 3, 'org.powermock', 'powermock-api-mockito2', '1.7.4', '2.0.9', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (64, 3, 'org.powermock', 'powermock-module-junit4', '1.7.4', '2.0.9', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (65, 3, 'org.springframework.security.oauth', 'spring-security-oauth2', '2.5.0.RELEASE', '2.5.1.RELEASE', 1,
+        '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (66, 3, 'cn.hutool', 'hutool-all', '5.6.3', '5.6.4', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (67, 3, 'com.alibaba', 'transmittable-thread-local', '2.12.0', '2.13.0-Beta1', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (68, 3, 'com.baomidou', 'mybatis-plus-boot-starter', '3.4.0', '3.4.2', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (69, 3, 'com.baomidou', 'mybatis-plus-generator', '3.4.0', '3.4.1', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (70, 3, 'com.google.code.findbugs', 'annotations', '3.0.0', '3.0.1', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (71, 3, 'com.google.guava', 'guava', '29.0-jre', '30.1.1-jre', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (72, 3, 'com.nimbusds', 'nimbus-jose-jwt', '8.21', '9.8.1', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (73, 3, 'commons-daemon', 'commons-daemon', '1.2.2', '1.2.4', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (74, 3, 'io.swagger', 'swagger-annotations', '1.6.2', '2.0.0-rc2', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (75, 3, 'io.swagger.core.v3', 'swagger-annotations', '2.1.2', '2.1.9', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (76, 3, 'net.java.dev.jna', 'jna', '5.5.0', '5.8.0', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (77, 3, 'org.apache.commons', 'commons-lang3', '3.11', '3.12.0', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (78, 3, 'org.apache.tika', 'tika-core', '1.24.1', '2.0.0-ALPHA', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (79, 3, 'org.bouncycastle', 'bcpkix-jdk15on', '1.66', '1.68', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (80, 3, 'org.bouncycastle', 'bcprov-jdk15on', '1.66', '1.68', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (81, 3, 'org.mockito', 'mockito-all', '1.10.19', '2.0.2-beta', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (82, 3, 'org.powermock', 'powermock-api-mockito2', '1.7.4', '2.0.9', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (83, 3, 'org.powermock', 'powermock-module-junit4', '1.7.4', '2.0.9', 1, '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (84, 3, 'org.springframework.security.oauth', 'spring-security-oauth2', '2.5.0.RELEASE', '2.5.1.RELEASE', 1,
+        '2021-04-26 02:44:43');
+INSERT INTO `tb_notify_record`
+VALUES (100, 3, 'cn.hutool', 'hutool-all', '5.6.3', '5.6.6', 1, '2021-05-29 23:03:44');
+INSERT INTO `tb_notify_record`
+VALUES (101, 3, 'cn.hutool', 'hutool-all', '5.6.3', '5.6.6', 1, '2021-05-29 23:03:44');
+INSERT INTO `tb_notify_record`
+VALUES (102, 3, 'cn.hutool', 'hutool-core', '5.6.3', '5.6.6', 1, '2021-05-29 23:03:44');
+INSERT INTO `tb_notify_record`
+VALUES (103, 3, 'cn.hutool', 'hutool-core', '5.6.3', '5.6.6', 1, '2021-05-29 23:03:44');
+INSERT INTO `tb_notify_record`
+VALUES (104, 3, 'cn.hutool', 'hutool-http', '5.6.3', '5.6.6', 1, '2021-05-29 23:03:44');
+INSERT INTO `tb_notify_record`
+VALUES (105, 3, 'cn.hutool', 'hutool-http', '5.6.3', '5.6.6', 1, '2021-05-29 23:03:44');
+INSERT INTO `tb_notify_record`
+VALUES (106, 3, 'org.springframework.cloud', 'spring-cloud-dependencies', '2020.0.2', '2020.0.3', 1,
+        '2021-05-29 23:03:44');
+INSERT INTO `tb_notify_record`
+VALUES (107, 3, 'org.springframework.cloud', 'spring-cloud-dependencies', '2020.0.2', '2020.0.3', 1,
+        '2021-05-29 23:03:44');
+INSERT INTO `tb_notify_record`
+VALUES (108, 3, 'org.springframework.security.oauth.boot', 'spring-security-oauth2-autoconfigure', '2.4.5', '2.5.0', 1,
+        '2021-05-29 23:03:44');
+INSERT INTO `tb_notify_record`
+VALUES (109, 3, 'org.springframework.security.oauth.boot', 'spring-security-oauth2-autoconfigure', '2.4.5', '2.5.0', 1,
+        '2021-05-29 23:03:44');
+INSERT INTO `tb_notify_record`
+VALUES (110, 10, 'io.swagger', 'swagger-annotations', '1.6.5', '1.6.2', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (111, 10, 'org.springframework.security.oauth.boot', 'spring-security-oauth2-autoconfigure', '2.4.5', '2.5.0', 1,
+        '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (112, 10, 'org.springframework.security.oauth', 'spring-security-oauth2', '2.5.0.RELEASE', '2.5.1.RELEASE', 1,
+        '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (113, 10, 'com.nimbusds', 'nimbus-jose-jwt', '8.21', '9.9.3', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (114, 10, 'org.springframework.security.experimental', 'spring-security-oauth2-authorization-server', '0.1.0',
+        '0.1.1', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (115, 10, 'commons-io', 'commons-io', '2.8.0', '2.9.0', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (116, 10, 'org.apache.commons', 'commons-lang3', '3.11', '3.12.0', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (117, 10, 'com.google.code.findbugs', 'annotations', '3.0.0', '3.0.1', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (118, 10, 'com.alibaba', 'transmittable-thread-local', '2.12.5', '2.12.1', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (119, 3, 'cn.hutool', 'hutool-all', '5.6.3', '5.8.15', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (120, 3, 'cn.hutool', 'hutool-all', '5.6.3', '5.8.15', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (121, 10, 'cn.hutool', 'hutool-all', '5.7.22', '5.8.15', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (122, 3, 'cn.hutool', 'hutool-core', '5.6.3', '5.8.15', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (123, 3, 'cn.hutool', 'hutool-core', '5.6.3', '5.8.15', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (124, 10, 'cn.hutool', 'hutool-core', '5.7.22', '5.8.15', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (125, 3, 'cn.hutool', 'hutool-http', '5.6.3', '5.8.15', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (126, 3, 'cn.hutool', 'hutool-http', '5.6.3', '5.8.15', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (127, 10, 'cn.hutool', 'hutool-http', '5.7.22', '5.8.15', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (130, 3, 'com.alibaba', 'transmittable-thread-local', '2.12.1', '2.14.2', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (131, 3, 'com.alibaba', 'transmittable-thread-local', '2.12.1', '2.14.2', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (132, 10, 'com.alibaba', 'transmittable-thread-local', '2.12.5', '2.14.2', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (133, 3, 'com.baomidou', 'mybatis-plus-boot-starter', '3.4.2', '3.5.3.1', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (134, 3, 'com.baomidou', 'mybatis-plus-boot-starter', '3.4.2', '3.5.3.1', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (135, 10, 'com.baomidou', 'mybatis-plus-boot-starter', '3.5.1', '3.5.3.1', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (136, 3, 'com.baomidou', 'mybatis-plus-generator', '3.4.2', '3.5.3.1', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (137, 3, 'com.baomidou', 'mybatis-plus-generator', '3.4.2', '3.5.3.1', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (138, 10, 'com.baomidou', 'mybatis-plus-generator', '3.5.1', '3.5.3.1', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (139, 3, 'com.github.chris2018998', 'beecp', '3.1.7', '3.4.0', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (140, 3, 'com.github.chris2018998', 'beecp', '3.1.7', '3.4.0', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (141, 10, 'com.github.chris2018998', 'beecp', '3.3.2', '3.4.0', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (142, 3, 'com.github.pagehelper', 'pagehelper', '5.2.0', '5.3.2', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (143, 3, 'com.github.pagehelper', 'pagehelper', '5.2.0', '5.3.2', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (144, 10, 'com.github.pagehelper', 'pagehelper', '5.3.0', '5.3.2', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (145, 3, 'com.github.pagehelper', 'pagehelper-spring-boot-starter', '1.3.0', '1.4.6', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (146, 3, 'com.github.pagehelper', 'pagehelper-spring-boot-starter', '1.3.0', '1.4.6', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (147, 10, 'com.github.pagehelper', 'pagehelper-spring-boot-starter', '1.4.1', '1.4.6', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (148, 3, 'com.github.xiaoymin', 'knife4j-spring-boot-starter', '3.0.2', '3.0.3', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (149, 3, 'com.github.xiaoymin', 'knife4j-spring-boot-starter', '3.0.2', '3.0.3', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (150, 10, 'com.github.xiaoymin', 'knife4j-spring-boot-starter', '3.0.2', '3.0.3', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (151, 3, 'com.github.xiaoymin', 'knife4j-spring-ui', '3.0.2', '3.0.3', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (152, 3, 'com.github.xiaoymin', 'knife4j-spring-ui', '3.0.2', '3.0.3', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (153, 10, 'com.github.xiaoymin', 'knife4j-spring-ui', '3.0.2', '3.0.3', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (154, 3, 'com.google.guava', 'guava', '30.1.1-jre', '31.1-jre', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (155, 3, 'com.google.guava', 'guava', '30.1.1-jre', '31.1-jre', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (156, 3, 'com.h2database', 'h2', '1.4.200', '2.1.214', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (157, 3, 'com.h2database', 'h2', '1.4.200', '2.1.214', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (158, 10, 'com.h2database', 'h2', '2.1.210', '2.1.214', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (159, 3, 'com.nimbusds', 'nimbus-jose-jwt', '8.21', '9.31', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (160, 3, 'com.nimbusds', 'nimbus-jose-jwt', '8.21', '9.31', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (161, 10, 'com.nimbusds', 'nimbus-jose-jwt', '8.21', '9.31', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (162, 3, 'com.thoughtworks.xstream', 'xstream', '1.4.17', '1.4.20', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (163, 3, 'com.thoughtworks.xstream', 'xstream', '1.4.17', '1.4.20', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (166, 10, 'com.thoughtworks.xstream', 'xstream', '1.4.19', '1.4.20', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (167, 3, 'commons-daemon', 'commons-daemon', '1.2.4', '1.3.3', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (168, 3, 'commons-daemon', 'commons-daemon', '1.2.4', '1.3.3', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (169, 10, 'commons-daemon', 'commons-daemon', '1.2.4', '1.3.3', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (170, 3, 'io.swagger.core.v3', 'swagger-annotations', '2.1.9', '2.2.8', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (171, 3, 'io.swagger.core.v3', 'swagger-annotations', '2.1.9', '2.2.8', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (172, 10, 'io.swagger.core.v3', 'swagger-annotations', '2.1.13', '2.2.8', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (173, 3, 'net.java.dev.jna', 'jna', '5.8.0', '5.13.0', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (174, 3, 'net.java.dev.jna', 'jna', '5.8.0', '5.13.0', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (175, 10, 'net.java.dev.jna', 'jna', '5.8.0', '5.13.0', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (176, 3, 'org.apache.tika', 'tika-core', '1.24.1', '2.7.0', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (177, 3, 'org.apache.tika', 'tika-core', '1.24.1', '2.7.0', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (178, 10, 'org.apache.tika', 'tika-core', '2.3.0', '2.7.0', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (179, 3, 'org.bouncycastle', 'bcpkix-jdk15on', '1.68', '1.70', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (180, 3, 'org.bouncycastle', 'bcpkix-jdk15on', '1.68', '1.70', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (181, 3, 'org.bouncycastle', 'bcprov-jdk15on', '1.68', '1.70', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (182, 3, 'org.bouncycastle', 'bcprov-jdk15on', '1.68', '1.70', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (183, 3, 'org.javassist', 'javassist', '3.27.0-GA', '3.29.2-GA', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (184, 3, 'org.javassist', 'javassist', '3.27.0-GA', '3.29.2-GA', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (185, 3, 'org.mapstruct', 'mapstruct', '1.4.2.Final', '1.5.3.Final', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (186, 3, 'org.mapstruct', 'mapstruct', '1.4.2.Final', '1.5.3.Final', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (187, 10, 'org.mapstruct', 'mapstruct', '1.4.2.Final', '1.5.3.Final', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (188, 3, 'org.mapstruct', 'mapstruct-processor', '1.4.2.Final', '1.5.3.Final', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (189, 3, 'org.mapstruct', 'mapstruct-processor', '1.4.2.Final', '1.5.3.Final', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (190, 10, 'org.mapstruct', 'mapstruct-processor', '1.4.2.Final', '1.5.3.Final', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (193, 10, 'org.projectlombok', 'lombok', '1.18.24', '1.18.26', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (194, 3, 'org.springframework.boot', 'spring-boot-starter-parent', '2.4.5', '3.0.4', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (195, 3, 'org.springframework.boot', 'spring-boot-starter-parent', '2.4.5', '3.0.4', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (196, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.6.4', '3.0.4', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (197, 3, 'org.springframework.cloud', 'spring-cloud-dependencies', '2020.0.2', '2022.0.1', 1,
+        '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (198, 3, 'org.springframework.cloud', 'spring-cloud-dependencies', '2020.0.2', '2022.0.1', 1,
+        '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (199, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.1', '2022.0.1', 1,
+        '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (200, 3, 'org.springframework.security.experimental', 'spring-security-oauth2-authorization-server', '0.1.0',
+        '0.1.2', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (201, 3, 'org.springframework.security.experimental', 'spring-security-oauth2-authorization-server', '0.1.0',
+        '0.1.2', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (202, 10, 'org.springframework.security.experimental', 'spring-security-oauth2-authorization-server', '0.1.0',
+        '0.1.2', 1, '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (203, 3, 'org.springframework.security.oauth', 'spring-security-oauth2', '2.5.0.RELEASE', '2.5.2.RELEASE', 1,
+        '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (204, 3, 'org.springframework.security.oauth', 'spring-security-oauth2', '2.5.0.RELEASE', '2.5.2.RELEASE', 1,
+        '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (205, 10, 'org.springframework.security.oauth', 'spring-security-oauth2', '2.5.0.RELEASE', '2.5.2.RELEASE', 1,
+        '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (206, 3, 'org.springframework.security.oauth.boot', 'spring-security-oauth2-autoconfigure', '2.4.5', '2.6.8', 1,
+        '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (207, 3, 'org.springframework.security.oauth.boot', 'spring-security-oauth2-autoconfigure', '2.4.5', '2.6.8', 1,
+        '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (208, 10, 'org.springframework.security.oauth.boot', 'spring-security-oauth2-autoconfigure', '2.4.5', '2.6.8', 1,
+        '2023-03-19 09:53:03');
+INSERT INTO `tb_notify_record`
+VALUES (209, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.9', '3.0.4', 1, '2023-03-19 10:21:58');
+INSERT INTO `tb_notify_record`
+VALUES (210, 10, 'org.apache.commons', 'commons-lang3', '3.12', '3.12.0', 1, '2023-03-19 10:21:58');
+INSERT INTO `tb_notify_record`
+VALUES (211, 3, 'cn.hutool', 'hutool-all', '5.6.3', '5.8.20', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (212, 3, 'cn.hutool', 'hutool-all', '5.6.3', '5.8.20', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (213, 10, 'cn.hutool', 'hutool-all', '5.8.15', '5.8.20', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (214, 3, 'cn.hutool', 'hutool-core', '5.6.3', '5.8.20', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (215, 3, 'cn.hutool', 'hutool-core', '5.6.3', '5.8.20', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (216, 10, 'cn.hutool', 'hutool-core', '5.8.15', '5.8.20', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (217, 3, 'cn.hutool', 'hutool-http', '5.6.3', '5.8.20', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (218, 3, 'cn.hutool', 'hutool-http', '5.6.3', '5.8.20', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (219, 10, 'cn.hutool', 'hutool-http', '5.8.15', '5.8.20', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (222, 3, 'com.alibaba', 'transmittable-thread-local', '2.12.1', '2.14.3', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (223, 3, 'com.alibaba', 'transmittable-thread-local', '2.12.1', '2.14.3', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (224, 10, 'com.alibaba', 'transmittable-thread-local', '2.14.2', '2.14.3', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (225, 3, 'com.github.chris2018998', 'beecp', '3.1.7', '3.4.1', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (226, 3, 'com.github.chris2018998', 'beecp', '3.1.7', '3.4.1', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (227, 10, 'com.github.chris2018998', 'beecp', '3.4.0', '3.4.1', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (228, 3, 'com.github.pagehelper', 'pagehelper', '5.2.0', '5.3.3', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (229, 3, 'com.github.pagehelper', 'pagehelper', '5.2.0', '5.3.3', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (230, 10, 'com.github.pagehelper', 'pagehelper', '5.3.2', '5.3.3', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (231, 3, 'com.github.pagehelper', 'pagehelper-spring-boot-starter', '1.3.0', '1.4.7', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (232, 3, 'com.github.pagehelper', 'pagehelper-spring-boot-starter', '1.3.0', '1.4.7', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (233, 10, 'com.github.pagehelper', 'pagehelper-spring-boot-starter', '1.4.6', '1.4.7', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (234, 3, 'com.google.guava', 'guava', '30.1.1-jre', '32.1.1-jre', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (235, 3, 'com.google.guava', 'guava', '30.1.1-jre', '32.1.1-jre', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (236, 10, 'com.google.guava', 'guava', '31.1-jre', '32.1.1-jre', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (237, 3, 'com.h2database', 'h2', '1.4.200', '2.2.220', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (238, 3, 'com.h2database', 'h2', '1.4.200', '2.2.220', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (239, 10, 'com.h2database', 'h2', '2.1.214', '2.2.220', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (240, 3, 'commons-daemon', 'commons-daemon', '1.2.4', '1.3.4', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (241, 3, 'commons-daemon', 'commons-daemon', '1.2.4', '1.3.4', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (242, 10, 'commons-daemon', 'commons-daemon', '1.3.3', '1.3.4', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (243, 3, 'io.swagger.core.v3', 'swagger-annotations', '2.1.9', '2.2.15', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (244, 3, 'io.swagger.core.v3', 'swagger-annotations', '2.1.9', '2.2.15', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (245, 10, 'io.swagger.core.v3', 'swagger-annotations', '2.2.8', '2.2.15', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (246, 3, 'org.apache.tika', 'tika-core', '1.24.1', '2.8.0', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (247, 3, 'org.apache.tika', 'tika-core', '1.24.1', '2.8.0', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (248, 10, 'org.apache.tika', 'tika-core', '2.7.0', '2.8.0', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (249, 3, 'org.mapstruct', 'mapstruct', '1.4.2.Final', '1.5.5.Final', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (250, 3, 'org.mapstruct', 'mapstruct', '1.4.2.Final', '1.5.5.Final', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (251, 10, 'org.mapstruct', 'mapstruct', '1.5.3.Final', '1.5.5.Final', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (252, 3, 'org.mapstruct', 'mapstruct-processor', '1.4.2.Final', '1.5.5.Final', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (253, 3, 'org.mapstruct', 'mapstruct-processor', '1.4.2.Final', '1.5.5.Final', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (254, 10, 'org.mapstruct', 'mapstruct-processor', '1.5.3.Final', '1.5.5.Final', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (257, 10, 'org.projectlombok', 'lombok', '1.18.26', '1.18.28', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (258, 3, 'org.springframework.boot', 'spring-boot-starter-parent', '2.4.5', '3.1.2', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (259, 3, 'org.springframework.boot', 'spring-boot-starter-parent', '2.4.5', '3.1.2', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (260, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.9', '3.1.2', 1, '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (261, 3, 'org.springframework.cloud', 'spring-cloud-dependencies', '2020.0.2', '2022.0.3', 1,
+        '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (262, 3, 'org.springframework.cloud', 'spring-cloud-dependencies', '2020.0.2', '2022.0.3', 1,
+        '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (263, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2022.0.1', '2022.0.3', 1,
+        '2023-07-22 09:39:39');
+INSERT INTO `tb_notify_record`
+VALUES (264, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.14', '3.1.2', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (265, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.3', 1,
+        '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (266, 10, 'org.redisson', 'redisson', '3.20.0', '3.23.2', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (267, 10, 'io.swagger', 'swagger-annotations', '1.6.9', '1.6.11', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (268, 10, 'commons-codec', 'commons-codec', '1.15', '1.16.0', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (269, 10, 'commons-io', 'commons-io', '2.11.0', '2.13.0', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (270, 10, 'com.h2database', 'h2', '2.1.220', '2.2.220', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (271, 3, 'cn.hutool', 'hutool-all', '5.6.3', '5.8.21', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (272, 3, 'cn.hutool', 'hutool-all', '5.6.3', '5.8.21', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (273, 10, 'cn.hutool', 'hutool-all', '5.8.20', '5.8.21', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (274, 3, 'cn.hutool', 'hutool-core', '5.6.3', '5.8.21', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (275, 3, 'cn.hutool', 'hutool-core', '5.6.3', '5.8.21', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (276, 10, 'cn.hutool', 'hutool-core', '5.8.20', '5.8.21', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (277, 3, 'cn.hutool', 'hutool-http', '5.6.3', '5.8.21', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (278, 3, 'cn.hutool', 'hutool-http', '5.6.3', '5.8.21', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (279, 10, 'cn.hutool', 'hutool-http', '5.8.20', '5.8.21', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (280, 3, 'com.baomidou', 'mybatis-plus-boot-starter', '3.4.2', '3.5.3.2', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (281, 3, 'com.baomidou', 'mybatis-plus-boot-starter', '3.4.2', '3.5.3.2', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (282, 10, 'com.baomidou', 'mybatis-plus-boot-starter', '3.5.3.1', '3.5.3.2', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (283, 3, 'com.baomidou', 'mybatis-plus-generator', '3.4.2', '3.5.3.2', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (284, 3, 'com.baomidou', 'mybatis-plus-generator', '3.4.2', '3.5.3.2', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (285, 10, 'com.baomidou', 'mybatis-plus-generator', '3.5.3.1', '3.5.3.2', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (286, 3, 'com.github.chris2018998', 'beecp', '3.1.7', '3.4.2', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (287, 3, 'com.github.chris2018998', 'beecp', '3.1.7', '3.4.2', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (288, 10, 'com.github.chris2018998', 'beecp', '3.4.1', '3.4.2', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (289, 3, 'com.google.guava', 'guava', '30.1.1-jre', '32.1.2-jre', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (290, 3, 'com.google.guava', 'guava', '30.1.1-jre', '32.1.2-jre', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (291, 10, 'com.google.guava', 'guava', '32.1.1-jre', '32.1.2-jre', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (292, 3, 'org.apache.commons', 'commons-lang3', '3.11', '3.13.0', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (293, 3, 'org.apache.commons', 'commons-lang3', '3.11', '3.13.0', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (294, 10, 'org.apache.commons', 'commons-lang3', '3.12.0', '3.13.0', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (295, 3, 'org.springframework.cloud', 'spring-cloud-dependencies', '2020.0.2', '2022.0.4', 1,
+        '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (296, 3, 'org.springframework.cloud', 'spring-cloud-dependencies', '2020.0.2', '2022.0.4', 1,
+        '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (297, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (298, 11, 'org.jsoup', 'jsoup', '1.15.4', '1.16.1', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (299, 11, 'com.aliyun.oss', 'aliyun-sdk-oss', '3.8.0', '3.17.1', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (300, 11, 'javax.xml.bind', 'jaxb-api', '2.3.1', '2.4.0-b180830.0359', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (301, 11, 'org.glassfish.jaxb', 'jaxb-runtime', '2.3.3', '4.0.3', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (302, 11, 'net.sourceforge.tess4j', 'tess4j', '5.6.0', '5.8.0', 1, '2023-08-13 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (303, 10, 'org.redisson', 'redisson', '3.20.0', '3.23.3', 1, '2023-08-20 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (304, 11, 'org.jsoup', 'jsoup', '1.15.4', '1.16.1', 1, '2023-08-21 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (305, 11, 'com.aliyun.oss', 'aliyun-sdk-oss', '3.8.0', '3.17.1', 1, '2023-08-21 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (306, 11, 'javax.xml.bind', 'jaxb-api', '2.3.1', '2.4.0-b180830.0359', 1, '2023-08-21 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (307, 11, 'org.glassfish.jaxb', 'jaxb-runtime', '2.3.3', '4.0.3', 1, '2023-08-21 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (308, 11, 'net.sourceforge.tess4j', 'tess4j', '5.6.0', '5.8.0', 1, '2023-08-21 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (309, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.14', '3.1.2', 1, '2023-08-21 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (310, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-08-21 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (311, 10, 'org.redisson', 'redisson', '3.20.0', '3.23.3', 1, '2023-08-21 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (312, 10, 'io.swagger', 'swagger-annotations', '1.6.9', '1.6.11', 1, '2023-08-21 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (313, 10, 'commons-codec', 'commons-codec', '1.15', '1.16.0', 1, '2023-08-21 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (314, 10, 'commons-io', 'commons-io', '2.11.0', '2.13.0', 1, '2023-08-21 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (315, 10, 'org.apache.commons', 'commons-lang3', '3.12.0', '3.13.0', 1, '2023-08-21 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (316, 10, 'cn.hutool', 'hutool-core', '5.8.20', '5.8.21', 1, '2023-08-21 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (317, 10, 'cn.hutool', 'hutool-all', '5.8.20', '5.8.21', 1, '2023-08-21 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (318, 10, 'cn.hutool', 'hutool-http', '5.8.20', '5.8.21', 1, '2023-08-21 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (319, 10, 'com.google.guava', 'guava', '32.1.1-jre', '32.1.2-jre', 1, '2023-08-21 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (320, 10, 'com.github.chris2018998', 'beecp', '3.4.1', '3.4.2', 1, '2023-08-21 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (321, 10, 'com.h2database', 'h2', '2.1.220', '2.2.220', 1, '2023-08-21 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (322, 10, 'com.baomidou', 'mybatis-plus-boot-starter', '3.5.3.1', '3.5.3.2', 1, '2023-08-21 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (323, 10, 'com.baomidou', 'mybatis-plus-generator', '3.5.3.1', '3.5.3.2', 1, '2023-08-21 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (324, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.14', '3.1.2', 1, '2023-08-20 11:06:00');
+INSERT INTO `tb_notify_record`
+VALUES (325, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-08-20 11:06:00');
+INSERT INTO `tb_notify_record`
+VALUES (326, 10, 'org.redisson', 'redisson', '3.20.0', '3.23.3', 1, '2023-08-20 11:06:00');
+INSERT INTO `tb_notify_record`
+VALUES (327, 10, 'io.swagger', 'swagger-annotations', '1.6.9', '1.6.11', 1, '2023-08-20 11:06:00');
+INSERT INTO `tb_notify_record`
+VALUES (328, 10, 'commons-codec', 'commons-codec', '1.15', '1.16.0', 1, '2023-08-20 11:06:00');
+INSERT INTO `tb_notify_record`
+VALUES (329, 10, 'commons-io', 'commons-io', '2.11.0', '2.13.0', 1, '2023-08-20 11:06:00');
+INSERT INTO `tb_notify_record`
+VALUES (330, 10, 'org.apache.commons', 'commons-lang3', '3.12.0', '3.13.0', 1, '2023-08-20 11:06:00');
+INSERT INTO `tb_notify_record`
+VALUES (331, 10, 'cn.hutool', 'hutool-core', '5.8.20', '5.8.21', 1, '2023-08-20 11:06:00');
+INSERT INTO `tb_notify_record`
+VALUES (332, 10, 'cn.hutool', 'hutool-all', '5.8.20', '5.8.21', 1, '2023-08-20 11:06:00');
+INSERT INTO `tb_notify_record`
+VALUES (333, 10, 'cn.hutool', 'hutool-http', '5.8.20', '5.8.21', 1, '2023-08-20 11:06:00');
+INSERT INTO `tb_notify_record`
+VALUES (334, 10, 'com.google.guava', 'guava', '32.1.1-jre', '32.1.2-jre', 1, '2023-08-20 11:06:00');
+INSERT INTO `tb_notify_record`
+VALUES (335, 10, 'com.github.chris2018998', 'beecp', '3.4.1', '3.4.2', 1, '2023-08-20 11:06:00');
+INSERT INTO `tb_notify_record`
+VALUES (336, 10, 'com.h2database', 'h2', '2.1.220', '2.2.220', 1, '2023-08-20 11:06:00');
+INSERT INTO `tb_notify_record`
+VALUES (337, 10, 'com.baomidou', 'mybatis-plus-boot-starter', '3.5.3.1', '3.5.3.2', 1, '2023-08-20 11:06:00');
+INSERT INTO `tb_notify_record`
+VALUES (338, 10, 'com.baomidou', 'mybatis-plus-generator', '3.5.3.1', '3.5.3.2', 1, '2023-08-20 11:06:00');
+INSERT INTO `tb_notify_record`
+VALUES (339, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.14', '3.1.2', 1, '2023-08-20 11:08:55');
+INSERT INTO `tb_notify_record`
+VALUES (340, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-08-20 11:08:55');
+INSERT INTO `tb_notify_record`
+VALUES (341, 10, 'org.redisson', 'redisson', '3.20.0', '3.23.3', 1, '2023-08-20 11:08:55');
+INSERT INTO `tb_notify_record`
+VALUES (342, 10, 'io.swagger', 'swagger-annotations', '1.6.9', '1.6.11', 1, '2023-08-20 11:08:55');
+INSERT INTO `tb_notify_record`
+VALUES (343, 10, 'commons-codec', 'commons-codec', '1.15', '1.16.0', 1, '2023-08-20 11:08:55');
+INSERT INTO `tb_notify_record`
+VALUES (344, 10, 'commons-io', 'commons-io', '2.11.0', '2.13.0', 1, '2023-08-20 11:08:55');
+INSERT INTO `tb_notify_record`
+VALUES (345, 10, 'org.apache.commons', 'commons-lang3', '3.12.0', '3.13.0', 1, '2023-08-20 11:08:55');
+INSERT INTO `tb_notify_record`
+VALUES (346, 10, 'cn.hutool', 'hutool-core', '5.8.20', '5.8.21', 1, '2023-08-20 11:08:55');
+INSERT INTO `tb_notify_record`
+VALUES (347, 10, 'cn.hutool', 'hutool-all', '5.8.20', '5.8.21', 1, '2023-08-20 11:08:55');
+INSERT INTO `tb_notify_record`
+VALUES (348, 10, 'cn.hutool', 'hutool-http', '5.8.20', '5.8.21', 1, '2023-08-20 11:08:55');
+INSERT INTO `tb_notify_record`
+VALUES (349, 10, 'com.google.guava', 'guava', '32.1.1-jre', '32.1.2-jre', 1, '2023-08-20 11:08:55');
+INSERT INTO `tb_notify_record`
+VALUES (350, 10, 'com.github.chris2018998', 'beecp', '3.4.1', '3.4.2', 1, '2023-08-20 11:08:55');
+INSERT INTO `tb_notify_record`
+VALUES (351, 10, 'com.h2database', 'h2', '2.1.220', '2.2.220', 1, '2023-08-20 11:08:55');
+INSERT INTO `tb_notify_record`
+VALUES (352, 10, 'com.baomidou', 'mybatis-plus-boot-starter', '3.5.3.1', '3.5.3.2', 1, '2023-08-20 11:08:55');
+INSERT INTO `tb_notify_record`
+VALUES (353, 10, 'com.baomidou', 'mybatis-plus-generator', '3.5.3.1', '3.5.3.2', 1, '2023-08-20 11:08:55');
+INSERT INTO `tb_notify_record`
+VALUES (354, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.14', '3.1.2', 1, '2023-08-20 12:49:16');
+INSERT INTO `tb_notify_record`
+VALUES (355, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-08-20 12:49:16');
+INSERT INTO `tb_notify_record`
+VALUES (356, 10, 'org.redisson', 'redisson', '3.20.0', '3.23.3', 1, '2023-08-20 12:49:16');
+INSERT INTO `tb_notify_record`
+VALUES (357, 10, 'io.swagger', 'swagger-annotations', '1.6.9', '1.6.11', 1, '2023-08-20 12:49:16');
+INSERT INTO `tb_notify_record`
+VALUES (358, 10, 'commons-codec', 'commons-codec', '1.15', '1.16.0', 1, '2023-08-20 12:49:16');
+INSERT INTO `tb_notify_record`
+VALUES (359, 10, 'commons-io', 'commons-io', '2.11.0', '2.13.0', 1, '2023-08-20 12:49:16');
+INSERT INTO `tb_notify_record`
+VALUES (360, 10, 'org.apache.commons', 'commons-lang3', '3.12.0', '3.13.0', 1, '2023-08-20 12:49:16');
+INSERT INTO `tb_notify_record`
+VALUES (361, 10, 'cn.hutool', 'hutool-core', '5.8.20', '5.8.21', 1, '2023-08-20 12:49:16');
+INSERT INTO `tb_notify_record`
+VALUES (362, 10, 'cn.hutool', 'hutool-all', '5.8.20', '5.8.21', 1, '2023-08-20 12:49:16');
+INSERT INTO `tb_notify_record`
+VALUES (363, 10, 'cn.hutool', 'hutool-http', '5.8.20', '5.8.21', 1, '2023-08-20 12:49:16');
+INSERT INTO `tb_notify_record`
+VALUES (364, 10, 'com.google.guava', 'guava', '32.1.1-jre', '32.1.2-jre', 1, '2023-08-20 12:49:16');
+INSERT INTO `tb_notify_record`
+VALUES (365, 10, 'com.github.chris2018998', 'beecp', '3.4.1', '3.4.2', 1, '2023-08-20 12:49:16');
+INSERT INTO `tb_notify_record`
+VALUES (366, 10, 'com.h2database', 'h2', '2.1.220', '2.2.220', 1, '2023-08-20 12:49:16');
+INSERT INTO `tb_notify_record`
+VALUES (367, 10, 'com.baomidou', 'mybatis-plus-boot-starter', '3.5.3.1', '3.5.3.2', 1, '2023-08-20 12:49:16');
+INSERT INTO `tb_notify_record`
+VALUES (368, 10, 'com.baomidou', 'mybatis-plus-generator', '3.5.3.1', '3.5.3.2', 1, '2023-08-20 12:49:16');
+INSERT INTO `tb_notify_record`
+VALUES (369, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.14', '3.1.2', 1, '2023-08-20 12:50:00');
+INSERT INTO `tb_notify_record`
+VALUES (370, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-08-20 12:50:00');
+INSERT INTO `tb_notify_record`
+VALUES (371, 10, 'org.redisson', 'redisson', '3.20.0', '3.23.3', 1, '2023-08-20 12:50:00');
+INSERT INTO `tb_notify_record`
+VALUES (372, 10, 'io.swagger', 'swagger-annotations', '1.6.9', '1.6.11', 1, '2023-08-20 12:50:00');
+INSERT INTO `tb_notify_record`
+VALUES (373, 10, 'commons-codec', 'commons-codec', '1.15', '1.16.0', 1, '2023-08-20 12:50:00');
+INSERT INTO `tb_notify_record`
+VALUES (374, 10, 'commons-io', 'commons-io', '2.11.0', '2.13.0', 1, '2023-08-20 12:50:00');
+INSERT INTO `tb_notify_record`
+VALUES (375, 10, 'org.apache.commons', 'commons-lang3', '3.12.0', '3.13.0', 1, '2023-08-20 12:50:00');
+INSERT INTO `tb_notify_record`
+VALUES (376, 10, 'cn.hutool', 'hutool-core', '5.8.20', '5.8.21', 1, '2023-08-20 12:50:00');
+INSERT INTO `tb_notify_record`
+VALUES (377, 10, 'cn.hutool', 'hutool-all', '5.8.20', '5.8.21', 1, '2023-08-20 12:50:00');
+INSERT INTO `tb_notify_record`
+VALUES (378, 10, 'cn.hutool', 'hutool-http', '5.8.20', '5.8.21', 1, '2023-08-20 12:50:00');
+INSERT INTO `tb_notify_record`
+VALUES (379, 10, 'com.google.guava', 'guava', '32.1.1-jre', '32.1.2-jre', 1, '2023-08-20 12:50:00');
+INSERT INTO `tb_notify_record`
+VALUES (380, 10, 'com.github.chris2018998', 'beecp', '3.4.1', '3.4.2', 1, '2023-08-20 12:50:00');
+INSERT INTO `tb_notify_record`
+VALUES (381, 10, 'com.h2database', 'h2', '2.1.220', '2.2.220', 1, '2023-08-20 12:50:00');
+INSERT INTO `tb_notify_record`
+VALUES (382, 10, 'com.baomidou', 'mybatis-plus-boot-starter', '3.5.3.1', '3.5.3.2', 1, '2023-08-20 12:50:00');
+INSERT INTO `tb_notify_record`
+VALUES (383, 10, 'com.baomidou', 'mybatis-plus-generator', '3.5.3.1', '3.5.3.2', 1, '2023-08-20 12:50:00');
+INSERT INTO `tb_notify_record`
+VALUES (384, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.14', '3.1.2', 1, '2023-08-20 12:57:49');
+INSERT INTO `tb_notify_record`
+VALUES (385, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-08-20 12:57:49');
+INSERT INTO `tb_notify_record`
+VALUES (386, 10, 'org.redisson', 'redisson', '3.20.0', '3.23.3', 1, '2023-08-20 12:57:49');
+INSERT INTO `tb_notify_record`
+VALUES (387, 10, 'io.swagger', 'swagger-annotations', '1.6.9', '1.6.11', 1, '2023-08-20 12:57:49');
+INSERT INTO `tb_notify_record`
+VALUES (388, 10, 'commons-codec', 'commons-codec', '1.15', '1.16.0', 1, '2023-08-20 12:57:49');
+INSERT INTO `tb_notify_record`
+VALUES (389, 10, 'commons-io', 'commons-io', '2.11.0', '2.13.0', 1, '2023-08-20 12:57:49');
+INSERT INTO `tb_notify_record`
+VALUES (390, 10, 'org.apache.commons', 'commons-lang3', '3.12.0', '3.13.0', 1, '2023-08-20 12:57:49');
+INSERT INTO `tb_notify_record`
+VALUES (391, 10, 'cn.hutool', 'hutool-core', '5.8.20', '5.8.21', 1, '2023-08-20 12:57:49');
+INSERT INTO `tb_notify_record`
+VALUES (392, 10, 'cn.hutool', 'hutool-all', '5.8.20', '5.8.21', 1, '2023-08-20 12:57:49');
+INSERT INTO `tb_notify_record`
+VALUES (393, 10, 'cn.hutool', 'hutool-http', '5.8.20', '5.8.21', 1, '2023-08-20 12:57:49');
+INSERT INTO `tb_notify_record`
+VALUES (394, 10, 'com.google.guava', 'guava', '32.1.1-jre', '32.1.2-jre', 1, '2023-08-20 12:57:49');
+INSERT INTO `tb_notify_record`
+VALUES (395, 10, 'com.github.chris2018998', 'beecp', '3.4.1', '3.4.2', 1, '2023-08-20 12:57:49');
+INSERT INTO `tb_notify_record`
+VALUES (396, 10, 'com.h2database', 'h2', '2.1.220', '2.2.220', 1, '2023-08-20 12:57:49');
+INSERT INTO `tb_notify_record`
+VALUES (397, 10, 'com.baomidou', 'mybatis-plus-boot-starter', '3.5.3.1', '3.5.3.2', 1, '2023-08-20 12:57:49');
+INSERT INTO `tb_notify_record`
+VALUES (398, 10, 'com.baomidou', 'mybatis-plus-generator', '3.5.3.1', '3.5.3.2', 1, '2023-08-20 12:57:49');
+INSERT INTO `tb_notify_record`
+VALUES (399, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.14', '3.1.2', 1, '2023-08-20 17:11:28');
+INSERT INTO `tb_notify_record`
+VALUES (400, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-08-20 17:11:28');
+INSERT INTO `tb_notify_record`
+VALUES (401, 10, 'org.redisson', 'redisson', '3.20.0', '3.23.3', 1, '2023-08-20 17:11:28');
+INSERT INTO `tb_notify_record`
+VALUES (402, 10, 'io.swagger', 'swagger-annotations', '1.6.9', '1.6.11', 1, '2023-08-20 17:11:28');
+INSERT INTO `tb_notify_record`
+VALUES (403, 10, 'commons-codec', 'commons-codec', '1.15', '1.16.0', 1, '2023-08-20 17:11:28');
+INSERT INTO `tb_notify_record`
+VALUES (404, 10, 'commons-io', 'commons-io', '2.11.0', '2.13.0', 1, '2023-08-20 17:11:28');
+INSERT INTO `tb_notify_record`
+VALUES (405, 10, 'org.apache.commons', 'commons-lang3', '3.12.0', '3.13.0', 1, '2023-08-20 17:11:28');
+INSERT INTO `tb_notify_record`
+VALUES (406, 10, 'cn.hutool', 'hutool-core', '5.8.20', '5.8.21', 1, '2023-08-20 17:11:28');
+INSERT INTO `tb_notify_record`
+VALUES (407, 10, 'cn.hutool', 'hutool-all', '5.8.20', '5.8.21', 1, '2023-08-20 17:11:28');
+INSERT INTO `tb_notify_record`
+VALUES (408, 10, 'cn.hutool', 'hutool-http', '5.8.20', '5.8.21', 1, '2023-08-20 17:11:28');
+INSERT INTO `tb_notify_record`
+VALUES (409, 10, 'com.google.guava', 'guava', '32.1.1-jre', '32.1.2-jre', 1, '2023-08-20 17:11:28');
+INSERT INTO `tb_notify_record`
+VALUES (410, 10, 'com.github.chris2018998', 'beecp', '3.4.1', '3.4.2', 1, '2023-08-20 17:11:28');
+INSERT INTO `tb_notify_record`
+VALUES (411, 10, 'com.h2database', 'h2', '2.1.220', '2.2.220', 1, '2023-08-20 17:11:28');
+INSERT INTO `tb_notify_record`
+VALUES (412, 10, 'com.baomidou', 'mybatis-plus-boot-starter', '3.5.3.1', '3.5.3.2', 1, '2023-08-20 17:11:28');
+INSERT INTO `tb_notify_record`
+VALUES (413, 10, 'com.baomidou', 'mybatis-plus-generator', '3.5.3.1', '3.5.3.2', 1, '2023-08-20 17:11:28');
+INSERT INTO `tb_notify_record`
+VALUES (414, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.14', '3.1.2', 1, '2023-08-21 21:52:45');
+INSERT INTO `tb_notify_record`
+VALUES (415, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-08-21 21:52:45');
+INSERT INTO `tb_notify_record`
+VALUES (416, 10, 'org.redisson', 'redisson', '3.20.0', '3.23.3', 1, '2023-08-21 21:52:45');
+INSERT INTO `tb_notify_record`
+VALUES (417, 10, 'io.swagger', 'swagger-annotations', '1.6.9', '1.6.11', 1, '2023-08-21 21:52:45');
+INSERT INTO `tb_notify_record`
+VALUES (418, 10, 'commons-codec', 'commons-codec', '1.15', '1.16.0', 1, '2023-08-21 21:52:45');
+INSERT INTO `tb_notify_record`
+VALUES (419, 10, 'commons-io', 'commons-io', '2.11.0', '2.13.0', 1, '2023-08-21 21:52:45');
+INSERT INTO `tb_notify_record`
+VALUES (420, 10, 'org.apache.commons', 'commons-lang3', '3.12.0', '3.13.0', 1, '2023-08-21 21:52:45');
+INSERT INTO `tb_notify_record`
+VALUES (421, 10, 'cn.hutool', 'hutool-core', '5.8.20', '5.8.21', 1, '2023-08-21 21:52:45');
+INSERT INTO `tb_notify_record`
+VALUES (422, 10, 'cn.hutool', 'hutool-all', '5.8.20', '5.8.21', 1, '2023-08-21 21:52:45');
+INSERT INTO `tb_notify_record`
+VALUES (423, 10, 'cn.hutool', 'hutool-http', '5.8.20', '5.8.21', 1, '2023-08-21 21:52:45');
+INSERT INTO `tb_notify_record`
+VALUES (424, 10, 'com.google.guava', 'guava', '32.1.1-jre', '32.1.2-jre', 1, '2023-08-21 21:52:45');
+INSERT INTO `tb_notify_record`
+VALUES (425, 10, 'com.github.chris2018998', 'beecp', '3.4.1', '3.4.2', 1, '2023-08-21 21:52:45');
+INSERT INTO `tb_notify_record`
+VALUES (426, 10, 'com.h2database', 'h2', '2.1.220', '2.2.220', 1, '2023-08-21 21:52:45');
+INSERT INTO `tb_notify_record`
+VALUES (427, 10, 'com.baomidou', 'mybatis-plus-boot-starter', '3.5.3.1', '3.5.3.2', 1, '2023-08-21 21:52:45');
+INSERT INTO `tb_notify_record`
+VALUES (428, 10, 'com.baomidou', 'mybatis-plus-generator', '3.5.3.1', '3.5.3.2', 1, '2023-08-21 21:52:45');
+INSERT INTO `tb_notify_record`
+VALUES (429, 3, 'org.springframework.boot', 'spring-boot-starter-parent', '2.4.5', '3.1.3', 1, '2023-08-25 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (430, 3, 'org.springframework.boot', 'spring-boot-starter-parent', '2.4.5', '3.1.3', 1, '2023-08-25 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (431, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.14', '3.1.3', 1, '2023-08-25 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (432, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.14', '3.1.3', 1, '2023-08-25 18:43:06');
+INSERT INTO `tb_notify_record`
+VALUES (433, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-08-25 18:43:06');
+INSERT INTO `tb_notify_record`
+VALUES (434, 10, 'org.redisson', 'redisson', '3.20.0', '3.23.3', 1, '2023-08-25 18:43:06');
+INSERT INTO `tb_notify_record`
+VALUES (435, 10, 'io.swagger', 'swagger-annotations', '1.6.9', '1.6.11', 1, '2023-08-25 18:43:06');
+INSERT INTO `tb_notify_record`
+VALUES (436, 10, 'commons-codec', 'commons-codec', '1.15', '1.16.0', 1, '2023-08-25 18:43:06');
+INSERT INTO `tb_notify_record`
+VALUES (437, 10, 'commons-io', 'commons-io', '2.11.0', '2.13.0', 1, '2023-08-25 18:43:06');
+INSERT INTO `tb_notify_record`
+VALUES (438, 10, 'org.apache.commons', 'commons-lang3', '3.12.0', '3.13.0', 1, '2023-08-25 18:43:06');
+INSERT INTO `tb_notify_record`
+VALUES (439, 10, 'cn.hutool', 'hutool-core', '5.8.20', '5.8.21', 1, '2023-08-25 18:43:06');
+INSERT INTO `tb_notify_record`
+VALUES (440, 10, 'cn.hutool', 'hutool-all', '5.8.20', '5.8.21', 1, '2023-08-25 18:43:06');
+INSERT INTO `tb_notify_record`
+VALUES (441, 10, 'cn.hutool', 'hutool-http', '5.8.20', '5.8.21', 1, '2023-08-25 18:43:06');
+INSERT INTO `tb_notify_record`
+VALUES (442, 10, 'com.google.guava', 'guava', '32.1.1-jre', '32.1.2-jre', 1, '2023-08-25 18:43:06');
+INSERT INTO `tb_notify_record`
+VALUES (443, 10, 'com.github.chris2018998', 'beecp', '3.4.1', '3.4.2', 1, '2023-08-25 18:43:06');
+INSERT INTO `tb_notify_record`
+VALUES (444, 10, 'com.h2database', 'h2', '2.1.220', '2.2.220', 1, '2023-08-25 18:43:06');
+INSERT INTO `tb_notify_record`
+VALUES (445, 10, 'com.baomidou', 'mybatis-plus-boot-starter', '3.5.3.1', '3.5.3.2', 1, '2023-08-25 18:43:06');
+INSERT INTO `tb_notify_record`
+VALUES (446, 10, 'com.baomidou', 'mybatis-plus-generator', '3.5.3.1', '3.5.3.2', 1, '2023-08-25 18:43:06');
+INSERT INTO `tb_notify_record`
+VALUES (447, 11, 'org.jsoup', 'jsoup', '1.15.4', '1.16.1', 1, '2023-08-26 09:00:01');
+INSERT INTO `tb_notify_record`
+VALUES (448, 11, 'com.aliyun.oss', 'aliyun-sdk-oss', '3.8.0', '3.17.1', 1, '2023-08-26 09:00:01');
+INSERT INTO `tb_notify_record`
+VALUES (449, 11, 'javax.xml.bind', 'jaxb-api', '2.3.1', '2.4.0-b180830.0359', 1, '2023-08-26 09:00:01');
+INSERT INTO `tb_notify_record`
+VALUES (450, 11, 'org.glassfish.jaxb', 'jaxb-runtime', '2.3.3', '4.0.3', 1, '2023-08-26 09:00:01');
+INSERT INTO `tb_notify_record`
+VALUES (451, 11, 'net.sourceforge.tess4j', 'tess4j', '5.6.0', '5.8.0', 1, '2023-08-26 09:00:01');
+INSERT INTO `tb_notify_record`
+VALUES (452, 11, 'org.jsoup', 'jsoup', '1.15.4', '1.16.1', 1, '2023-08-26 00:31:20');
+INSERT INTO `tb_notify_record`
+VALUES (453, 11, 'com.aliyun.oss', 'aliyun-sdk-oss', '3.8.0', '3.17.1', 1, '2023-08-26 00:31:20');
+INSERT INTO `tb_notify_record`
+VALUES (454, 11, 'javax.xml.bind', 'jaxb-api', '2.3.1', '2.4.0-b180830.0359', 1, '2023-08-26 00:31:20');
+INSERT INTO `tb_notify_record`
+VALUES (455, 11, 'org.glassfish.jaxb', 'jaxb-runtime', '2.3.3', '4.0.3', 1, '2023-08-26 00:31:20');
+INSERT INTO `tb_notify_record`
+VALUES (456, 11, 'net.sourceforge.tess4j', 'tess4j', '5.6.0', '5.8.0', 1, '2023-08-26 00:31:20');
+INSERT INTO `tb_notify_record`
+VALUES (457, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.14', '3.1.3', 1, '2023-08-26 00:42:06');
+INSERT INTO `tb_notify_record`
+VALUES (458, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-08-26 00:42:06');
+INSERT INTO `tb_notify_record`
+VALUES (459, 10, 'org.redisson', 'redisson', '3.20.0', '3.23.3', 1, '2023-08-26 00:42:06');
+INSERT INTO `tb_notify_record`
+VALUES (460, 10, 'io.swagger', 'swagger-annotations', '1.6.9', '1.6.11', 1, '2023-08-26 00:42:06');
+INSERT INTO `tb_notify_record`
+VALUES (461, 10, 'commons-codec', 'commons-codec', '1.15', '1.16.0', 1, '2023-08-26 00:42:06');
+INSERT INTO `tb_notify_record`
+VALUES (462, 10, 'commons-io', 'commons-io', '2.11.0', '2.13.0', 1, '2023-08-26 00:42:06');
+INSERT INTO `tb_notify_record`
+VALUES (463, 10, 'org.apache.commons', 'commons-lang3', '3.12.0', '3.13.0', 1, '2023-08-26 00:42:06');
+INSERT INTO `tb_notify_record`
+VALUES (464, 10, 'cn.hutool', 'hutool-core', '5.8.20', '5.8.21', 1, '2023-08-26 00:42:06');
+INSERT INTO `tb_notify_record`
+VALUES (465, 10, 'cn.hutool', 'hutool-all', '5.8.20', '5.8.21', 1, '2023-08-26 00:42:06');
+INSERT INTO `tb_notify_record`
+VALUES (466, 10, 'cn.hutool', 'hutool-http', '5.8.20', '5.8.21', 1, '2023-08-26 00:42:06');
+INSERT INTO `tb_notify_record`
+VALUES (467, 10, 'com.google.guava', 'guava', '32.1.1-jre', '32.1.2-jre', 1, '2023-08-26 00:42:06');
+INSERT INTO `tb_notify_record`
+VALUES (468, 10, 'com.github.chris2018998', 'beecp', '3.4.1', '3.4.2', 1, '2023-08-26 00:42:06');
+INSERT INTO `tb_notify_record`
+VALUES (469, 10, 'com.h2database', 'h2', '2.1.220', '2.2.220', 1, '2023-08-26 00:42:06');
+INSERT INTO `tb_notify_record`
+VALUES (470, 10, 'com.baomidou', 'mybatis-plus-boot-starter', '3.5.3.1', '3.5.3.2', 1, '2023-08-26 00:42:06');
+INSERT INTO `tb_notify_record`
+VALUES (471, 10, 'com.baomidou', 'mybatis-plus-generator', '3.5.3.1', '3.5.3.2', 1, '2023-08-26 00:42:06');
+INSERT INTO `tb_notify_record`
+VALUES (472, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.14', '3.1.3', 1, '2023-08-26 09:07:34');
+INSERT INTO `tb_notify_record`
+VALUES (473, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-08-26 09:07:34');
+INSERT INTO `tb_notify_record`
+VALUES (474, 10, 'org.redisson', 'redisson', '3.20.0', '3.23.3', 1, '2023-08-26 09:07:34');
+INSERT INTO `tb_notify_record`
+VALUES (475, 10, 'io.swagger', 'swagger-annotations', '1.6.9', '1.6.11', 1, '2023-08-26 09:07:34');
+INSERT INTO `tb_notify_record`
+VALUES (476, 10, 'commons-codec', 'commons-codec', '1.15', '1.16.0', 1, '2023-08-26 09:07:34');
+INSERT INTO `tb_notify_record`
+VALUES (477, 10, 'commons-io', 'commons-io', '2.11.0', '2.13.0', 1, '2023-08-26 09:07:34');
+INSERT INTO `tb_notify_record`
+VALUES (478, 10, 'org.apache.commons', 'commons-lang3', '3.12.0', '3.13.0', 1, '2023-08-26 09:07:34');
+INSERT INTO `tb_notify_record`
+VALUES (479, 10, 'cn.hutool', 'hutool-core', '5.8.20', '5.8.21', 1, '2023-08-26 09:07:34');
+INSERT INTO `tb_notify_record`
+VALUES (480, 10, 'cn.hutool', 'hutool-all', '5.8.20', '5.8.21', 1, '2023-08-26 09:07:34');
+INSERT INTO `tb_notify_record`
+VALUES (481, 10, 'cn.hutool', 'hutool-http', '5.8.20', '5.8.21', 1, '2023-08-26 09:07:34');
+INSERT INTO `tb_notify_record`
+VALUES (482, 10, 'com.google.guava', 'guava', '32.1.1-jre', '32.1.2-jre', 1, '2023-08-26 09:07:34');
+INSERT INTO `tb_notify_record`
+VALUES (483, 10, 'com.github.chris2018998', 'beecp', '3.4.1', '3.4.2', 1, '2023-08-26 09:07:34');
+INSERT INTO `tb_notify_record`
+VALUES (484, 10, 'com.h2database', 'h2', '2.1.220', '2.2.220', 1, '2023-08-26 09:07:34');
+INSERT INTO `tb_notify_record`
+VALUES (485, 10, 'com.baomidou', 'mybatis-plus-boot-starter', '3.5.3.1', '3.5.3.2', 1, '2023-08-26 09:07:34');
+INSERT INTO `tb_notify_record`
+VALUES (486, 10, 'com.baomidou', 'mybatis-plus-generator', '3.5.3.1', '3.5.3.2', 1, '2023-08-26 09:07:34');
+INSERT INTO `tb_notify_record`
+VALUES (487, 3, 'org.apache.tika', 'tika-core', '1.24.1', '2.9.0', 1, '2023-08-29 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (488, 3, 'org.apache.tika', 'tika-core', '1.24.1', '2.9.0', 1, '2023-08-29 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (489, 10, 'org.apache.tika', 'tika-core', '2.8.0', '2.9.0', 1, '2023-08-29 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (490, 10, 'org.redisson', 'redisson', '3.23.3', '3.23.4', 1, '2023-08-30 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (491, 3, 'com.h2database', 'h2', '1.4.200', '2.2.222', 1, '2023-09-02 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (492, 3, 'com.h2database', 'h2', '1.4.200', '2.2.222', 1, '2023-09-02 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (493, 10, 'com.h2database', 'h2', '2.2.220', '2.2.222', 1, '2023-09-02 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (494, 11, 'org.jsoup', 'jsoup', '1.15.4', '1.16.1', 1, '2023-09-03 18:38:06');
+INSERT INTO `tb_notify_record`
+VALUES (495, 11, 'com.aliyun.oss', 'aliyun-sdk-oss', '3.8.0', '3.17.1', 1, '2023-09-03 18:38:06');
+INSERT INTO `tb_notify_record`
+VALUES (496, 11, 'javax.xml.bind', 'jaxb-api', '2.3.1', '2.4.0-b180830.0359', 1, '2023-09-03 18:38:06');
+INSERT INTO `tb_notify_record`
+VALUES (497, 11, 'org.glassfish.jaxb', 'jaxb-runtime', '2.3.3', '4.0.3', 1, '2023-09-03 18:38:06');
+INSERT INTO `tb_notify_record`
+VALUES (498, 11, 'net.sourceforge.tess4j', 'tess4j', '5.6.0', '5.8.0', 1, '2023-09-03 18:38:06');
+INSERT INTO `tb_notify_record`
+VALUES (499, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.15', '3.1.3', 1, '2023-09-03 18:39:10');
+INSERT INTO `tb_notify_record`
+VALUES (500, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-03 18:39:10');
+INSERT INTO `tb_notify_record`
+VALUES (501, 10, 'org.redisson', 'redisson', '3.23.3', '3.23.4', 1, '2023-09-03 18:39:10');
+INSERT INTO `tb_notify_record`
+VALUES (502, 10, 'commons-codec', 'commons-codec', '1.15', '1.16.0', 1, '2023-09-03 18:39:10');
+INSERT INTO `tb_notify_record`
+VALUES (503, 10, 'org.apache.tika', 'tika-core', '2.8.0', '2.9.0', 1, '2023-09-03 18:39:10');
+INSERT INTO `tb_notify_record`
+VALUES (504, 10, 'com.h2database', 'h2', '2.2.220', '2.2.222', 1, '2023-09-03 18:39:10');
+INSERT INTO `tb_notify_record`
+VALUES (505, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.15', '3.1.3', 1, '2023-09-03 18:44:35');
+INSERT INTO `tb_notify_record`
+VALUES (506, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-03 18:44:35');
+INSERT INTO `tb_notify_record`
+VALUES (507, 10, 'org.redisson', 'redisson', '3.23.3', '3.23.4', 1, '2023-09-03 18:44:35');
+INSERT INTO `tb_notify_record`
+VALUES (508, 10, 'commons-codec', 'commons-codec', '1.15', '1.16.0', 1, '2023-09-03 18:44:35');
+INSERT INTO `tb_notify_record`
+VALUES (509, 10, 'org.apache.tika', 'tika-core', '2.8.0', '2.9.0', 1, '2023-09-03 18:44:35');
+INSERT INTO `tb_notify_record`
+VALUES (510, 10, 'com.h2database', 'h2', '2.2.220', '2.2.222', 1, '2023-09-03 18:44:35');
+INSERT INTO `tb_notify_record`
+VALUES (511, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.15', '3.1.3', 1, '2023-09-03 18:53:49');
+INSERT INTO `tb_notify_record`
+VALUES (512, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-03 18:53:49');
+INSERT INTO `tb_notify_record`
+VALUES (513, 10, 'org.redisson', 'redisson', '3.23.3', '3.23.4', 1, '2023-09-03 18:53:49');
+INSERT INTO `tb_notify_record`
+VALUES (514, 10, 'commons-codec', 'commons-codec', '1.15', '1.16.0', 1, '2023-09-03 18:53:49');
+INSERT INTO `tb_notify_record`
+VALUES (515, 10, 'org.apache.tika', 'tika-core', '2.8.0', '2.9.0', 1, '2023-09-03 18:53:49');
+INSERT INTO `tb_notify_record`
+VALUES (516, 10, 'com.h2database', 'h2', '2.2.220', '2.2.222', 1, '2023-09-03 18:53:49');
+INSERT INTO `tb_notify_record`
+VALUES (517, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.15', '3.1.3', 1, '2023-09-03 20:07:01');
+INSERT INTO `tb_notify_record`
+VALUES (518, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-03 20:07:01');
+INSERT INTO `tb_notify_record`
+VALUES (519, 10, 'org.redisson', 'redisson', '3.23.3', '3.23.4', 1, '2023-09-03 20:07:01');
+INSERT INTO `tb_notify_record`
+VALUES (520, 10, 'commons-codec', 'commons-codec', '1.15', '1.16.0', 1, '2023-09-03 20:07:01');
+INSERT INTO `tb_notify_record`
+VALUES (521, 10, 'org.apache.tika', 'tika-core', '2.8.0', '2.9.0', 1, '2023-09-03 20:07:01');
+INSERT INTO `tb_notify_record`
+VALUES (522, 10, 'com.h2database', 'h2', '2.2.220', '2.2.222', 1, '2023-09-03 20:07:01');
+INSERT INTO `tb_notify_record`
+VALUES (523, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.15', '3.1.3', 1, '2023-09-03 20:12:44');
+INSERT INTO `tb_notify_record`
+VALUES (524, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-03 20:12:44');
+INSERT INTO `tb_notify_record`
+VALUES (525, 10, 'org.redisson', 'redisson', '3.23.3', '3.23.4', 1, '2023-09-03 20:12:44');
+INSERT INTO `tb_notify_record`
+VALUES (526, 10, 'commons-codec', 'commons-codec', '1.15', '1.16.0', 1, '2023-09-03 20:12:44');
+INSERT INTO `tb_notify_record`
+VALUES (527, 10, 'org.apache.tika', 'tika-core', '2.8.0', '2.9.0', 1, '2023-09-03 20:12:44');
+INSERT INTO `tb_notify_record`
+VALUES (528, 10, 'com.h2database', 'h2', '2.2.220', '2.2.222', 1, '2023-09-03 20:12:44');
+INSERT INTO `tb_notify_record`
+VALUES (529, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.15', '3.1.3', 1, '2023-09-03 22:03:23');
+INSERT INTO `tb_notify_record`
+VALUES (530, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-03 22:03:23');
+INSERT INTO `tb_notify_record`
+VALUES (531, 10, 'org.redisson', 'redisson', '3.23.3', '3.23.4', 1, '2023-09-03 22:03:23');
+INSERT INTO `tb_notify_record`
+VALUES (532, 10, 'commons-codec', 'commons-codec', '1.15', '1.16.0', 1, '2023-09-03 22:03:23');
+INSERT INTO `tb_notify_record`
+VALUES (533, 10, 'org.apache.tika', 'tika-core', '2.8.0', '2.9.0', 1, '2023-09-03 22:03:23');
+INSERT INTO `tb_notify_record`
+VALUES (534, 10, 'com.h2database', 'h2', '2.2.220', '2.2.222', 1, '2023-09-03 22:03:23');
+INSERT INTO `tb_notify_record`
+VALUES (537, 3, 'cn.hutool', 'hutool-all', '5.6.3', '5.8.22', 1, '2023-09-14 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (538, 3, 'cn.hutool', 'hutool-all', '5.6.3', '5.8.22', 1, '2023-09-14 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (539, 10, 'cn.hutool', 'hutool-all', '5.8.21', '5.8.22', 1, '2023-09-14 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (540, 3, 'cn.hutool', 'hutool-core', '5.6.3', '5.8.22', 1, '2023-09-14 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (541, 3, 'cn.hutool', 'hutool-core', '5.6.3', '5.8.22', 1, '2023-09-14 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (542, 10, 'cn.hutool', 'hutool-core', '5.8.21', '5.8.22', 1, '2023-09-14 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (543, 3, 'cn.hutool', 'hutool-http', '5.6.3', '5.8.22', 1, '2023-09-14 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (544, 3, 'cn.hutool', 'hutool-http', '5.6.3', '5.8.22', 1, '2023-09-14 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (545, 10, 'cn.hutool', 'hutool-http', '5.8.21', '5.8.22', 1, '2023-09-14 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (546, 3, 'com.nimbusds', 'nimbus-jose-jwt', '8.21', '9.32', 1, '2023-09-14 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (547, 3, 'com.nimbusds', 'nimbus-jose-jwt', '8.21', '9.32', 1, '2023-09-14 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (548, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.31', '9.32', 1, '2023-09-14 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (549, 3, 'com.nimbusds', 'nimbus-jose-jwt', '8.21', '9.33', 1, '2023-09-15 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (550, 3, 'com.nimbusds', 'nimbus-jose-jwt', '8.21', '9.33', 1, '2023-09-15 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (551, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.31', '9.33', 1, '2023-09-15 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (552, 3, 'com.nimbusds', 'nimbus-jose-jwt', '8.21', '9.34', 1, '2023-09-15 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (553, 3, 'com.nimbusds', 'nimbus-jose-jwt', '8.21', '9.34', 1, '2023-09-15 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (554, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.31', '9.34', 1, '2023-09-15 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (555, 3, 'com.h2database', 'h2', '1.4.200', '2.2.224', 1, '2023-09-19 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (556, 3, 'com.h2database', 'h2', '1.4.200', '2.2.224', 1, '2023-09-19 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (557, 10, 'com.h2database', 'h2', '2.2.222', '2.2.224', 1, '2023-09-19 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (558, 3, 'io.swagger.core.v3', 'swagger-annotations', '2.1.9', '2.2.16', 1, '2023-09-19 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (559, 3, 'io.swagger.core.v3', 'swagger-annotations', '2.1.9', '2.2.16', 1, '2023-09-19 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (560, 10, 'io.swagger.core.v3', 'swagger-annotations', '2.2.15', '2.2.16', 1, '2023-09-19 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (561, 3, 'com.nimbusds', 'nimbus-jose-jwt', '8.21', '9.35', 1, '2023-09-19 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (562, 3, 'com.nimbusds', 'nimbus-jose-jwt', '8.21', '9.35', 1, '2023-09-19 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (563, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.31', '9.35', 1, '2023-09-19 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (564, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.15', '3.1.3', 1, '2023-09-19 15:19:22');
+INSERT INTO `tb_notify_record`
+VALUES (565, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-19 15:19:22');
+INSERT INTO `tb_notify_record`
+VALUES (566, 10, 'io.swagger.core.v3', 'swagger-annotations', '2.2.15', '2.2.16', 1, '2023-09-19 15:19:22');
+INSERT INTO `tb_notify_record`
+VALUES (567, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.31', '9.35', 1, '2023-09-19 15:19:22');
+INSERT INTO `tb_notify_record`
+VALUES (568, 10, 'cn.hutool', 'hutool-core', '5.8.21', '5.8.22', 1, '2023-09-19 15:19:22');
+INSERT INTO `tb_notify_record`
+VALUES (569, 10, 'cn.hutool', 'hutool-all', '5.8.21', '5.8.22', 1, '2023-09-19 15:19:22');
+INSERT INTO `tb_notify_record`
+VALUES (570, 10, 'cn.hutool', 'hutool-http', '5.8.21', '5.8.22', 1, '2023-09-19 15:19:22');
+INSERT INTO `tb_notify_record`
+VALUES (571, 10, 'com.h2database', 'h2', '2.2.222', '2.2.224', 1, '2023-09-19 15:19:22');
+INSERT INTO `tb_notify_record`
+VALUES (572, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.15', '3.1.3', 1, '2023-09-19 17:02:21');
+INSERT INTO `tb_notify_record`
+VALUES (573, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-19 17:02:21');
+INSERT INTO `tb_notify_record`
+VALUES (574, 10, 'io.swagger.core.v3', 'swagger-annotations', '2.2.15', '2.2.16', 1, '2023-09-19 17:02:21');
+INSERT INTO `tb_notify_record`
+VALUES (575, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.31', '9.35', 1, '2023-09-19 17:02:21');
+INSERT INTO `tb_notify_record`
+VALUES (576, 10, 'cn.hutool', 'hutool-core', '5.8.21', '5.8.22', 1, '2023-09-19 17:02:21');
+INSERT INTO `tb_notify_record`
+VALUES (577, 10, 'cn.hutool', 'hutool-all', '5.8.21', '5.8.22', 1, '2023-09-19 17:02:21');
+INSERT INTO `tb_notify_record`
+VALUES (578, 10, 'cn.hutool', 'hutool-http', '5.8.21', '5.8.22', 1, '2023-09-19 17:02:21');
+INSERT INTO `tb_notify_record`
+VALUES (579, 10, 'com.h2database', 'h2', '2.2.222', '2.2.224', 1, '2023-09-19 17:02:21');
+INSERT INTO `tb_notify_record`
+VALUES (580, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.15', '3.1.3', 1, '2023-09-19 18:21:18');
+INSERT INTO `tb_notify_record`
+VALUES (581, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-19 18:21:18');
+INSERT INTO `tb_notify_record`
+VALUES (582, 10, 'io.swagger.core.v3', 'swagger-annotations', '2.2.15', '2.2.16', 1, '2023-09-19 18:21:18');
+INSERT INTO `tb_notify_record`
+VALUES (583, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.31', '9.35', 1, '2023-09-19 18:21:18');
+INSERT INTO `tb_notify_record`
+VALUES (584, 10, 'cn.hutool', 'hutool-core', '5.8.21', '5.8.22', 1, '2023-09-19 18:21:18');
+INSERT INTO `tb_notify_record`
+VALUES (585, 10, 'cn.hutool', 'hutool-all', '5.8.21', '5.8.22', 1, '2023-09-19 18:21:18');
+INSERT INTO `tb_notify_record`
+VALUES (586, 10, 'cn.hutool', 'hutool-http', '5.8.21', '5.8.22', 1, '2023-09-19 18:21:18');
+INSERT INTO `tb_notify_record`
+VALUES (587, 10, 'com.h2database', 'h2', '2.2.222', '2.2.224', 1, '2023-09-19 18:21:18');
+INSERT INTO `tb_notify_record`
+VALUES (588, 10, 'org.redisson', 'redisson', '3.23.4', '3.23.5', 1, '2023-09-20 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (589, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.15', '3.1.3', 1, '2023-09-20 01:19:56');
+INSERT INTO `tb_notify_record`
+VALUES (590, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-20 01:19:56');
+INSERT INTO `tb_notify_record`
+VALUES (591, 10, 'org.redisson', 'redisson', '3.23.4', '3.23.5', 1, '2023-09-20 01:19:56');
+INSERT INTO `tb_notify_record`
+VALUES (592, 10, 'io.swagger.core.v3', 'swagger-annotations', '2.2.15', '2.2.16', 1, '2023-09-20 01:19:56');
+INSERT INTO `tb_notify_record`
+VALUES (593, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.31', '9.35', 1, '2023-09-20 01:19:56');
+INSERT INTO `tb_notify_record`
+VALUES (594, 10, 'cn.hutool', 'hutool-core', '5.8.21', '5.8.22', 1, '2023-09-20 01:19:56');
+INSERT INTO `tb_notify_record`
+VALUES (595, 10, 'cn.hutool', 'hutool-all', '5.8.21', '5.8.22', 1, '2023-09-20 01:19:56');
+INSERT INTO `tb_notify_record`
+VALUES (596, 10, 'cn.hutool', 'hutool-http', '5.8.21', '5.8.22', 1, '2023-09-20 01:19:56');
+INSERT INTO `tb_notify_record`
+VALUES (597, 10, 'com.h2database', 'h2', '2.2.222', '2.2.224', 1, '2023-09-20 01:19:56');
+INSERT INTO `tb_notify_record`
+VALUES (600, 10, 'org.projectlombok', 'lombok', '1.18.28', '1.18.30', 1, '2023-09-21 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (601, 3, 'org.springframework.boot', 'spring-boot-starter-parent', '2.4.5', '3.1.4', 1, '2023-09-22 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (602, 3, 'org.springframework.boot', 'spring-boot-starter-parent', '2.4.5', '3.1.4', 1, '2023-09-22 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (603, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.15', '3.1.4', 1, '2023-09-22 09:00:00');
+INSERT INTO `tb_notify_record`
+VALUES (604, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.15', '3.1.4', 1, '2023-09-21 22:00:45');
+INSERT INTO `tb_notify_record`
+VALUES (605, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-21 22:00:45');
+INSERT INTO `tb_notify_record`
+VALUES (606, 10, 'org.redisson', 'redisson', '3.23.4', '3.23.5', 1, '2023-09-21 22:00:45');
+INSERT INTO `tb_notify_record`
+VALUES (607, 10, 'io.swagger.core.v3', 'swagger-annotations', '2.2.15', '2.2.16', 1, '2023-09-21 22:00:45');
+INSERT INTO `tb_notify_record`
+VALUES (608, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.31', '9.35', 1, '2023-09-21 22:00:45');
+INSERT INTO `tb_notify_record`
+VALUES (609, 10, 'cn.hutool', 'hutool-core', '5.8.21', '5.8.22', 1, '2023-09-21 22:00:45');
+INSERT INTO `tb_notify_record`
+VALUES (610, 10, 'cn.hutool', 'hutool-all', '5.8.21', '5.8.22', 1, '2023-09-21 22:00:45');
+INSERT INTO `tb_notify_record`
+VALUES (611, 10, 'cn.hutool', 'hutool-http', '5.8.21', '5.8.22', 1, '2023-09-21 22:00:45');
+INSERT INTO `tb_notify_record`
+VALUES (612, 10, 'com.h2database', 'h2', '2.2.222', '2.2.224', 1, '2023-09-21 22:00:45');
+INSERT INTO `tb_notify_record`
+VALUES (613, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.15', '3.1.4', 1, '2023-09-21 22:02:18');
+INSERT INTO `tb_notify_record`
+VALUES (614, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-21 22:02:18');
+INSERT INTO `tb_notify_record`
+VALUES (615, 10, 'org.redisson', 'redisson', '3.23.4', '3.23.5', 1, '2023-09-21 22:02:18');
+INSERT INTO `tb_notify_record`
+VALUES (616, 10, 'io.swagger.core.v3', 'swagger-annotations', '2.2.15', '2.2.16', 1, '2023-09-21 22:02:18');
+INSERT INTO `tb_notify_record`
+VALUES (617, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.31', '9.35', 1, '2023-09-21 22:02:18');
+INSERT INTO `tb_notify_record`
+VALUES (618, 10, 'cn.hutool', 'hutool-core', '5.8.21', '5.8.22', 1, '2023-09-21 22:02:18');
+INSERT INTO `tb_notify_record`
+VALUES (619, 10, 'cn.hutool', 'hutool-all', '5.8.21', '5.8.22', 1, '2023-09-21 22:02:18');
+INSERT INTO `tb_notify_record`
+VALUES (620, 10, 'cn.hutool', 'hutool-http', '5.8.21', '5.8.22', 1, '2023-09-21 22:02:18');
+INSERT INTO `tb_notify_record`
+VALUES (621, 10, 'com.h2database', 'h2', '2.2.222', '2.2.224', 1, '2023-09-21 22:02:18');
+INSERT INTO `tb_notify_record`
+VALUES (622, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.15', '3.1.4', 1, '2023-09-26 00:37:16');
+INSERT INTO `tb_notify_record`
+VALUES (623, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-26 00:37:16');
+INSERT INTO `tb_notify_record`
+VALUES (624, 10, 'org.redisson', 'redisson', '3.23.4', '3.23.5', 1, '2023-09-26 00:37:16');
+INSERT INTO `tb_notify_record`
+VALUES (625, 10, 'io.swagger.core.v3', 'swagger-annotations', '2.2.15', '2.2.16', 1, '2023-09-26 00:37:16');
+INSERT INTO `tb_notify_record`
+VALUES (626, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.31', '9.35', 1, '2023-09-26 00:37:16');
+INSERT INTO `tb_notify_record`
+VALUES (627, 10, 'cn.hutool', 'hutool-core', '5.8.21', '5.8.22', 1, '2023-09-26 00:37:16');
+INSERT INTO `tb_notify_record`
+VALUES (628, 10, 'cn.hutool', 'hutool-all', '5.8.21', '5.8.22', 1, '2023-09-26 00:37:16');
+INSERT INTO `tb_notify_record`
+VALUES (629, 10, 'cn.hutool', 'hutool-http', '5.8.21', '5.8.22', 1, '2023-09-26 00:37:16');
+INSERT INTO `tb_notify_record`
+VALUES (630, 10, 'com.h2database', 'h2', '2.2.222', '2.2.224', 1, '2023-09-26 00:37:16');
+INSERT INTO `tb_notify_record`
+VALUES (631, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.15', '3.1.4', 1, '2023-09-26 19:43:48');
+INSERT INTO `tb_notify_record`
+VALUES (632, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-26 19:43:48');
+INSERT INTO `tb_notify_record`
+VALUES (633, 10, 'org.redisson', 'redisson', '3.23.4', '3.23.5', 1, '2023-09-26 19:43:48');
+INSERT INTO `tb_notify_record`
+VALUES (634, 10, 'io.swagger.core.v3', 'swagger-annotations', '2.2.15', '2.2.16', 1, '2023-09-26 19:43:48');
+INSERT INTO `tb_notify_record`
+VALUES (635, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.31', '9.35', 1, '2023-09-26 19:43:48');
+INSERT INTO `tb_notify_record`
+VALUES (636, 10, 'cn.hutool', 'hutool-core', '5.8.21', '5.8.22', 1, '2023-09-26 19:43:48');
+INSERT INTO `tb_notify_record`
+VALUES (637, 10, 'cn.hutool', 'hutool-all', '5.8.21', '5.8.22', 1, '2023-09-26 19:43:48');
+INSERT INTO `tb_notify_record`
+VALUES (638, 10, 'cn.hutool', 'hutool-http', '5.8.21', '5.8.22', 1, '2023-09-26 19:43:48');
+INSERT INTO `tb_notify_record`
+VALUES (639, 10, 'com.h2database', 'h2', '2.2.222', '2.2.224', 1, '2023-09-26 19:43:48');
+INSERT INTO `tb_notify_record`
+VALUES (640, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.15', '3.1.4', 1, '2023-09-26 23:37:55');
+INSERT INTO `tb_notify_record`
+VALUES (641, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-26 23:37:55');
+INSERT INTO `tb_notify_record`
+VALUES (642, 10, 'org.redisson', 'redisson', '3.23.4', '3.23.5', 1, '2023-09-26 23:37:55');
+INSERT INTO `tb_notify_record`
+VALUES (643, 10, 'io.swagger.core.v3', 'swagger-annotations', '2.2.15', '2.2.16', 1, '2023-09-26 23:37:55');
+INSERT INTO `tb_notify_record`
+VALUES (644, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.31', '9.35', 1, '2023-09-26 23:37:55');
+INSERT INTO `tb_notify_record`
+VALUES (645, 10, 'cn.hutool', 'hutool-core', '5.8.21', '5.8.22', 1, '2023-09-26 23:37:55');
+INSERT INTO `tb_notify_record`
+VALUES (646, 10, 'cn.hutool', 'hutool-all', '5.8.21', '5.8.22', 1, '2023-09-26 23:37:55');
+INSERT INTO `tb_notify_record`
+VALUES (647, 10, 'cn.hutool', 'hutool-http', '5.8.21', '5.8.22', 1, '2023-09-26 23:37:55');
+INSERT INTO `tb_notify_record`
+VALUES (648, 10, 'com.h2database', 'h2', '2.2.222', '2.2.224', 1, '2023-09-26 23:37:55');
+INSERT INTO `tb_notify_record`
+VALUES (649, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.15', '3.1.4', 1, '2023-09-26 23:53:23');
+INSERT INTO `tb_notify_record`
+VALUES (650, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-26 23:53:23');
+INSERT INTO `tb_notify_record`
+VALUES (651, 10, 'org.redisson', 'redisson', '3.23.4', '3.23.5', 1, '2023-09-26 23:53:23');
+INSERT INTO `tb_notify_record`
+VALUES (652, 10, 'io.swagger.core.v3', 'swagger-annotations', '2.2.15', '2.2.16', 1, '2023-09-26 23:53:23');
+INSERT INTO `tb_notify_record`
+VALUES (653, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.31', '9.35', 1, '2023-09-26 23:53:23');
+INSERT INTO `tb_notify_record`
+VALUES (654, 10, 'cn.hutool', 'hutool-core', '5.8.21', '5.8.22', 1, '2023-09-26 23:53:23');
+INSERT INTO `tb_notify_record`
+VALUES (655, 10, 'cn.hutool', 'hutool-all', '5.8.21', '5.8.22', 1, '2023-09-26 23:53:23');
+INSERT INTO `tb_notify_record`
+VALUES (656, 10, 'cn.hutool', 'hutool-http', '5.8.21', '5.8.22', 1, '2023-09-26 23:53:23');
+INSERT INTO `tb_notify_record`
+VALUES (657, 10, 'com.h2database', 'h2', '2.2.222', '2.2.224', 1, '2023-09-26 23:53:23');
+INSERT INTO `tb_notify_record`
+VALUES (658, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.15', '3.1.4', 1, '2023-09-28 15:39:03');
+INSERT INTO `tb_notify_record`
+VALUES (659, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-28 15:39:03');
+INSERT INTO `tb_notify_record`
+VALUES (660, 10, 'org.redisson', 'redisson', '3.23.4', '3.23.5', 1, '2023-09-28 15:39:03');
+INSERT INTO `tb_notify_record`
+VALUES (661, 10, 'io.swagger.core.v3', 'swagger-annotations', '2.2.15', '2.2.16', 1, '2023-09-28 15:39:03');
+INSERT INTO `tb_notify_record`
+VALUES (662, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.31', '9.35', 1, '2023-09-28 15:39:03');
+INSERT INTO `tb_notify_record`
+VALUES (663, 10, 'cn.hutool', 'hutool-core', '5.8.21', '5.8.22', 1, '2023-09-28 15:39:03');
+INSERT INTO `tb_notify_record`
+VALUES (664, 10, 'cn.hutool', 'hutool-all', '5.8.21', '5.8.22', 1, '2023-09-28 15:39:03');
+INSERT INTO `tb_notify_record`
+VALUES (665, 10, 'cn.hutool', 'hutool-http', '5.8.21', '5.8.22', 1, '2023-09-28 15:39:03');
+INSERT INTO `tb_notify_record`
+VALUES (666, 10, 'com.h2database', 'h2', '2.2.222', '2.2.224', 1, '2023-09-28 15:39:03');
+INSERT INTO `tb_notify_record`
+VALUES (667, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-09-28 23:03:53');
+INSERT INTO `tb_notify_record`
+VALUES (668, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-28 23:03:53');
+INSERT INTO `tb_notify_record`
+VALUES (669, 10, 'org.redisson', 'redisson', '3.23.4', '3.23.5', 1, '2023-09-28 23:03:53');
+INSERT INTO `tb_notify_record`
+VALUES (670, 10, 'io.swagger.core.v3', 'swagger-annotations', '2.2.15', '2.2.16', 1, '2023-09-28 23:03:53');
+INSERT INTO `tb_notify_record`
+VALUES (671, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.31', '9.35', 1, '2023-09-28 23:03:53');
+INSERT INTO `tb_notify_record`
+VALUES (672, 10, 'cn.hutool', 'hutool-core', '5.8.21', '5.8.22', 1, '2023-09-28 23:03:53');
+INSERT INTO `tb_notify_record`
+VALUES (673, 10, 'cn.hutool', 'hutool-all', '5.8.21', '5.8.22', 1, '2023-09-28 23:03:53');
+INSERT INTO `tb_notify_record`
+VALUES (674, 10, 'cn.hutool', 'hutool-http', '5.8.21', '5.8.22', 1, '2023-09-28 23:03:53');
+INSERT INTO `tb_notify_record`
+VALUES (675, 10, 'com.h2database', 'h2', '2.2.222', '2.2.224', 1, '2023-09-28 23:03:53');
+INSERT INTO `tb_notify_record`
+VALUES (676, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-09-29 10:22:01');
+INSERT INTO `tb_notify_record`
+VALUES (677, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-29 10:22:01');
+INSERT INTO `tb_notify_record`
+VALUES (678, 10, 'org.redisson', 'redisson', '3.23.4', '3.23.5', 1, '2023-09-29 10:22:01');
+INSERT INTO `tb_notify_record`
+VALUES (679, 10, 'io.swagger.core.v3', 'swagger-annotations', '2.2.15', '2.2.16', 1, '2023-09-29 10:22:01');
+INSERT INTO `tb_notify_record`
+VALUES (680, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.31', '9.35', 1, '2023-09-29 10:22:01');
+INSERT INTO `tb_notify_record`
+VALUES (681, 10, 'cn.hutool', 'hutool-core', '5.8.21', '5.8.22', 1, '2023-09-29 10:22:01');
+INSERT INTO `tb_notify_record`
+VALUES (682, 10, 'cn.hutool', 'hutool-all', '5.8.21', '5.8.22', 1, '2023-09-29 10:22:01');
+INSERT INTO `tb_notify_record`
+VALUES (683, 10, 'cn.hutool', 'hutool-http', '5.8.21', '5.8.22', 1, '2023-09-29 10:22:01');
+INSERT INTO `tb_notify_record`
+VALUES (684, 10, 'com.h2database', 'h2', '2.2.222', '2.2.224', 1, '2023-09-29 10:22:01');
+INSERT INTO `tb_notify_record`
+VALUES (685, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.15', '3.1.4', 1, '2023-09-29 14:04:19');
+INSERT INTO `tb_notify_record`
+VALUES (686, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-29 14:04:19');
+INSERT INTO `tb_notify_record`
+VALUES (687, 10, 'org.redisson', 'redisson', '3.23.4', '3.23.5', 1, '2023-09-29 14:04:19');
+INSERT INTO `tb_notify_record`
+VALUES (688, 10, 'io.swagger.core.v3', 'swagger-annotations', '2.2.15', '2.2.16', 1, '2023-09-29 14:04:19');
+INSERT INTO `tb_notify_record`
+VALUES (689, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.31', '9.35', 1, '2023-09-29 14:04:19');
+INSERT INTO `tb_notify_record`
+VALUES (690, 10, 'cn.hutool', 'hutool-core', '5.8.21', '5.8.22', 1, '2023-09-29 14:04:19');
+INSERT INTO `tb_notify_record`
+VALUES (691, 10, 'cn.hutool', 'hutool-all', '5.8.21', '5.8.22', 1, '2023-09-29 14:04:19');
+INSERT INTO `tb_notify_record`
+VALUES (692, 10, 'cn.hutool', 'hutool-http', '5.8.21', '5.8.22', 1, '2023-09-29 14:04:19');
+INSERT INTO `tb_notify_record`
+VALUES (693, 10, 'com.h2database', 'h2', '2.2.222', '2.2.224', 1, '2023-09-29 14:04:19');
+INSERT INTO `tb_notify_record`
+VALUES (694, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.15', '3.1.4', 1, '2023-09-29 16:06:43');
+INSERT INTO `tb_notify_record`
+VALUES (695, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-29 16:06:43');
+INSERT INTO `tb_notify_record`
+VALUES (696, 10, 'org.redisson', 'redisson', '3.23.4', '3.23.5', 1, '2023-09-29 16:06:43');
+INSERT INTO `tb_notify_record`
+VALUES (697, 10, 'io.swagger.core.v3', 'swagger-annotations', '2.2.15', '2.2.16', 1, '2023-09-29 16:06:43');
+INSERT INTO `tb_notify_record`
+VALUES (698, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.31', '9.35', 1, '2023-09-29 16:06:43');
+INSERT INTO `tb_notify_record`
+VALUES (699, 10, 'cn.hutool', 'hutool-core', '5.8.21', '5.8.22', 1, '2023-09-29 16:06:43');
+INSERT INTO `tb_notify_record`
+VALUES (700, 10, 'cn.hutool', 'hutool-all', '5.8.21', '5.8.22', 1, '2023-09-29 16:06:43');
+INSERT INTO `tb_notify_record`
+VALUES (701, 10, 'cn.hutool', 'hutool-http', '5.8.21', '5.8.22', 1, '2023-09-29 16:06:43');
+INSERT INTO `tb_notify_record`
+VALUES (702, 10, 'com.h2database', 'h2', '2.2.222', '2.2.224', 1, '2023-09-29 16:06:43');
+INSERT INTO `tb_notify_record`
+VALUES (703, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-09-30 00:35:20');
+INSERT INTO `tb_notify_record`
+VALUES (704, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-30 00:35:20');
+INSERT INTO `tb_notify_record`
+VALUES (705, 10, 'org.redisson', 'redisson', '3.23.4', '3.23.5', 1, '2023-09-30 00:35:20');
+INSERT INTO `tb_notify_record`
+VALUES (706, 10, 'io.swagger.core.v3', 'swagger-annotations', '2.2.15', '2.2.16', 1, '2023-09-30 00:35:20');
+INSERT INTO `tb_notify_record`
+VALUES (707, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.31', '9.35', 1, '2023-09-30 00:35:20');
+INSERT INTO `tb_notify_record`
+VALUES (708, 10, 'cn.hutool', 'hutool-core', '5.8.21', '5.8.22', 1, '2023-09-30 00:35:20');
+INSERT INTO `tb_notify_record`
+VALUES (709, 10, 'cn.hutool', 'hutool-all', '5.8.21', '5.8.22', 1, '2023-09-30 00:35:20');
+INSERT INTO `tb_notify_record`
+VALUES (710, 10, 'cn.hutool', 'hutool-http', '5.8.21', '5.8.22', 1, '2023-09-30 00:35:20');
+INSERT INTO `tb_notify_record`
+VALUES (711, 10, 'com.h2database', 'h2', '2.2.222', '2.2.224', 1, '2023-09-30 00:35:20');
+INSERT INTO `tb_notify_record`
+VALUES (712, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-09-30 00:54:27');
+INSERT INTO `tb_notify_record`
+VALUES (713, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-30 00:54:27');
+INSERT INTO `tb_notify_record`
+VALUES (714, 10, 'org.redisson', 'redisson', '3.23.4', '3.23.5', 1, '2023-09-30 00:54:27');
+INSERT INTO `tb_notify_record`
+VALUES (715, 10, 'io.swagger.core.v3', 'swagger-annotations', '2.2.15', '2.2.16', 1, '2023-09-30 00:54:27');
+INSERT INTO `tb_notify_record`
+VALUES (716, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.31', '9.35', 1, '2023-09-30 00:54:27');
+INSERT INTO `tb_notify_record`
+VALUES (717, 10, 'cn.hutool', 'hutool-core', '5.8.21', '5.8.22', 1, '2023-09-30 00:54:27');
+INSERT INTO `tb_notify_record`
+VALUES (718, 10, 'cn.hutool', 'hutool-all', '5.8.21', '5.8.22', 1, '2023-09-30 00:54:27');
+INSERT INTO `tb_notify_record`
+VALUES (719, 10, 'cn.hutool', 'hutool-http', '5.8.21', '5.8.22', 1, '2023-09-30 00:54:27');
+INSERT INTO `tb_notify_record`
+VALUES (720, 10, 'com.h2database', 'h2', '2.2.222', '2.2.224', 1, '2023-09-30 00:54:27');
+INSERT INTO `tb_notify_record`
+VALUES (721, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-09-30 00:59:31');
+INSERT INTO `tb_notify_record`
+VALUES (722, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-30 00:59:31');
+INSERT INTO `tb_notify_record`
+VALUES (723, 10, 'org.redisson', 'redisson', '3.23.4', '3.23.5', 1, '2023-09-30 00:59:31');
+INSERT INTO `tb_notify_record`
+VALUES (724, 10, 'io.swagger.core.v3', 'swagger-annotations', '2.2.15', '2.2.16', 1, '2023-09-30 00:59:31');
+INSERT INTO `tb_notify_record`
+VALUES (725, 10, 'com.nimbusds', 'nimbus-jose-jwt', '9.31', '9.35', 1, '2023-09-30 00:59:31');
+INSERT INTO `tb_notify_record`
+VALUES (726, 10, 'cn.hutool', 'hutool-core', '5.8.21', '5.8.22', 1, '2023-09-30 00:59:31');
+INSERT INTO `tb_notify_record`
+VALUES (727, 10, 'cn.hutool', 'hutool-all', '5.8.21', '5.8.22', 1, '2023-09-30 00:59:31');
+INSERT INTO `tb_notify_record`
+VALUES (728, 10, 'cn.hutool', 'hutool-http', '5.8.21', '5.8.22', 1, '2023-09-30 00:59:31');
+INSERT INTO `tb_notify_record`
+VALUES (729, 10, 'com.h2database', 'h2', '2.2.222', '2.2.224', 1, '2023-09-30 00:59:31');
+INSERT INTO `tb_notify_record`
+VALUES (730, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-09-30 01:15:35');
+INSERT INTO `tb_notify_record`
+VALUES (731, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-30 01:15:35');
+INSERT INTO `tb_notify_record`
+VALUES (732, 12, 'org.codehaus.mojo', 'license-maven-plugin', '2.0.0', '2.2.0', 1, '2023-09-30 01:25:14');
+INSERT INTO `tb_notify_record`
+VALUES (733, 12, 'org.apache.maven.plugins', 'maven-source-plugin', '3.2.1', '3.3.0', 1, '2023-09-30 01:25:14');
+INSERT INTO `tb_notify_record`
+VALUES (734, 12, 'org.apache.maven.plugins', 'maven-javadoc-plugin', '3.2.0', '3.6.0', 1, '2023-09-30 01:25:14');
+INSERT INTO `tb_notify_record`
+VALUES (735, 12, 'org.apache.maven.plugins', 'maven-surefire-plugin', '3.0.0', '3.1.2', 1, '2023-09-30 01:25:14');
+INSERT INTO `tb_notify_record`
+VALUES (736, 12, 'org.codehaus.mojo', 'sonar-maven-plugin', '3.7.0.1746', '3.10.0.2594', 1, '2023-09-30 01:25:14');
+INSERT INTO `tb_notify_record`
+VALUES (737, 12, 'org.codehaus.mojo', 'versions-maven-plugin', '2.7', '2.16.1', 1, '2023-09-30 01:25:14');
+INSERT INTO `tb_notify_record`
+VALUES (738, 12, 'pl.project13.maven', 'git-commit-id-plugin', '2.1.5', '4.9.10', 1, '2023-09-30 01:25:14');
+INSERT INTO `tb_notify_record`
+VALUES (739, 13, 'org.apache.maven.plugins', 'maven-gpg-plugin', '3.0.1', '3.1.0', 1, '2023-09-30 01:37:32');
+INSERT INTO `tb_notify_record`
+VALUES (740, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-09-30 01:56:02');
+INSERT INTO `tb_notify_record`
+VALUES (741, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-30 01:56:02');
+INSERT INTO `tb_notify_record`
+VALUES (742, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-09-30 02:21:15');
+INSERT INTO `tb_notify_record`
+VALUES (743, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-30 02:21:15');
+INSERT INTO `tb_notify_record`
+VALUES (744, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-09-30 11:57:24');
+INSERT INTO `tb_notify_record`
+VALUES (745, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-30 11:57:24');
+INSERT INTO `tb_notify_record`
+VALUES (746, 10, 'commons-io', 'commons-io', '2.13.0', '2.14.0', 1, '2023-09-30 11:57:24');
+INSERT INTO `tb_notify_record`
+VALUES (747, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-09-30 12:20:19');
+INSERT INTO `tb_notify_record`
+VALUES (748, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-30 12:20:19');
+INSERT INTO `tb_notify_record`
+VALUES (749, 10, 'commons-io', 'commons-io', '2.13.0', '2.14.0', 1, '2023-09-30 12:20:19');
+INSERT INTO `tb_notify_record`
+VALUES (750, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-09-30 21:37:10');
+INSERT INTO `tb_notify_record`
+VALUES (751, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-09-30 21:37:10');
+INSERT INTO `tb_notify_record`
+VALUES (752, 10, 'commons-io', 'commons-io', '2.13.0', '2.14.0', 1, '2023-09-30 21:37:10');
+INSERT INTO `tb_notify_record`
+VALUES (753, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-10-01 19:09:57');
+INSERT INTO `tb_notify_record`
+VALUES (754, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-10-01 19:09:57');
+INSERT INTO `tb_notify_record`
+VALUES (755, 10, 'commons-io', 'commons-io', '2.13.0', '2.14.0', 1, '2023-10-01 19:09:57');
+INSERT INTO `tb_notify_record`
+VALUES (756, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-10-01 20:52:29');
+INSERT INTO `tb_notify_record`
+VALUES (757, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-10-01 20:52:29');
+INSERT INTO `tb_notify_record`
+VALUES (758, 10, 'commons-io', 'commons-io', '2.13.0', '2.14.0', 1, '2023-10-01 20:52:29');
+INSERT INTO `tb_notify_record`
+VALUES (759, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-10-01 20:56:33');
+INSERT INTO `tb_notify_record`
+VALUES (760, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-10-01 20:56:33');
+INSERT INTO `tb_notify_record`
+VALUES (761, 10, 'commons-io', 'commons-io', '2.13.0', '2.14.0', 1, '2023-10-01 20:56:33');
+INSERT INTO `tb_notify_record`
+VALUES (762, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-10-01 21:00:07');
+INSERT INTO `tb_notify_record`
+VALUES (763, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-10-01 21:00:07');
+INSERT INTO `tb_notify_record`
+VALUES (764, 10, 'commons-io', 'commons-io', '2.13.0', '2.14.0', 1, '2023-10-01 21:00:07');
+INSERT INTO `tb_notify_record`
+VALUES (765, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-10-01 22:07:56');
+INSERT INTO `tb_notify_record`
+VALUES (766, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-10-01 22:07:56');
+INSERT INTO `tb_notify_record`
+VALUES (767, 10, 'commons-io', 'commons-io', '2.13.0', '2.14.0', 1, '2023-10-01 22:07:56');
+INSERT INTO `tb_notify_record`
+VALUES (768, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-10-02 00:23:42');
+INSERT INTO `tb_notify_record`
+VALUES (769, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-10-02 00:23:42');
+INSERT INTO `tb_notify_record`
+VALUES (770, 10, 'commons-io', 'commons-io', '2.13.0', '2.14.0', 1, '2023-10-02 00:23:42');
+INSERT INTO `tb_notify_record`
+VALUES (771, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-10-02 02:51:53');
+INSERT INTO `tb_notify_record`
+VALUES (772, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-10-02 02:51:53');
+INSERT INTO `tb_notify_record`
+VALUES (773, 10, 'commons-io', 'commons-io', '2.13.0', '2.14.0', 1, '2023-10-02 02:51:53');
+INSERT INTO `tb_notify_record`
+VALUES (774, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-10-02 16:27:09');
+INSERT INTO `tb_notify_record`
+VALUES (775, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-10-02 16:27:09');
+INSERT INTO `tb_notify_record`
+VALUES (776, 10, 'commons-io', 'commons-io', '2.13.0', '2.14.0', 1, '2023-10-02 16:27:09');
+INSERT INTO `tb_notify_record`
+VALUES (777, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-10-02 17:37:45');
+INSERT INTO `tb_notify_record`
+VALUES (778, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-10-02 17:37:45');
+INSERT INTO `tb_notify_record`
+VALUES (779, 10, 'commons-io', 'commons-io', '2.13.0', '2.14.0', 1, '2023-10-02 17:37:45');
+INSERT INTO `tb_notify_record`
+VALUES (780, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-10-02 18:12:42');
+INSERT INTO `tb_notify_record`
+VALUES (781, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-10-02 18:12:42');
+INSERT INTO `tb_notify_record`
+VALUES (782, 10, 'commons-io', 'commons-io', '2.13.0', '2.14.0', 1, '2023-10-02 18:12:42');
+INSERT INTO `tb_notify_record`
+VALUES (783, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-10-02 21:30:30');
+INSERT INTO `tb_notify_record`
+VALUES (784, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-10-02 21:30:30');
+INSERT INTO `tb_notify_record`
+VALUES (785, 10, 'commons-io', 'commons-io', '2.13.0', '2.14.0', 1, '2023-10-02 21:30:30');
+INSERT INTO `tb_notify_record`
+VALUES (786, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-10-02 22:16:30');
+INSERT INTO `tb_notify_record`
+VALUES (787, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-10-02 22:16:30');
+INSERT INTO `tb_notify_record`
+VALUES (788, 10, 'commons-io', 'commons-io', '2.13.0', '2.14.0', 1, '2023-10-02 22:16:30');
+INSERT INTO `tb_notify_record`
+VALUES (789, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-10-02 22:21:02');
+INSERT INTO `tb_notify_record`
+VALUES (790, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-10-02 22:21:02');
+INSERT INTO `tb_notify_record`
+VALUES (791, 10, 'commons-io', 'commons-io', '2.13.0', '2.14.0', 1, '2023-10-02 22:21:02');
+INSERT INTO `tb_notify_record`
+VALUES (792, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-10-03 00:07:22');
+INSERT INTO `tb_notify_record`
+VALUES (793, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-10-03 00:07:22');
+INSERT INTO `tb_notify_record`
+VALUES (794, 10, 'commons-io', 'commons-io', '2.13.0', '2.14.0', 1, '2023-10-03 00:07:22');
+INSERT INTO `tb_notify_record`
+VALUES (795, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-10-03 00:32:17');
+INSERT INTO `tb_notify_record`
+VALUES (796, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-10-03 00:32:17');
+INSERT INTO `tb_notify_record`
+VALUES (797, 10, 'commons-io', 'commons-io', '2.13.0', '2.14.0', 1, '2023-10-03 00:32:17');
+INSERT INTO `tb_notify_record`
+VALUES (798, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-10-03 10:25:54');
+INSERT INTO `tb_notify_record`
+VALUES (799, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-10-03 10:25:54');
+INSERT INTO `tb_notify_record`
+VALUES (800, 10, 'commons-io', 'commons-io', '2.13.0', '2.14.0', 1, '2023-10-03 10:25:54');
+INSERT INTO `tb_notify_record`
+VALUES (801, 10, 'org.springframework.boot', 'spring-boot-starter-parent', '2.7.16', '3.1.4', 1, '2023-10-03 10:39:16');
+INSERT INTO `tb_notify_record`
+VALUES (802, 10, 'org.springframework.cloud', 'spring-cloud-dependencies', '2021.0.8', '2022.0.4', 1,
+        '2023-10-03 10:39:16');
+INSERT INTO `tb_notify_record`
+VALUES (803, 10, 'commons-io', 'commons-io', '2.13.0', '2.14.0', 1, '2023-10-03 10:39:16');
+/*!40000 ALTER TABLE `tb_notify_record` ENABLE KEYS */;
+UNLOCK
+TABLES;
+
+--
+-- Dumping data for table `tb_project`
+--
+
+LOCK
+TABLES `tb_project` WRITE;
+/*!40000 ALTER TABLE `tb_project` DISABLE KEYS */;
+INSERT INTO `tb_project`
+VALUES (3, 'cn.itlym', 'shoulder-dependencies', NULL, 'shoulder-dependencies', NULL, '1', 'NORMAL',
+        '2020-08-01 01:06:18', '2021-05-27 00:27:48');
+INSERT INTO `tb_project`
+VALUES (10, 'cn.itlym', 'shoulder-dependencies', NULL, 'shoulder-dependencies', NULL, '1', 'NORMAL',
+        '2023-03-19 09:21:53', '2023-10-03 10:39:16');
+INSERT INTO `tb_project`
+VALUES (11, 'com.example', 'spider', '0.0.1-SNAPSHOT', 'spider', 'Demo project for Spring Boot', '1', 'NORMAL',
+        '2023-08-13 00:11:53', '2023-09-03 18:38:05');
+INSERT INTO `tb_project`
+VALUES (12, 'cn.itlym', 'shoulder-parent', NULL, 'shoulder-parent', NULL, '1', 'NORMAL', '2023-09-30 01:16:02',
+        '2023-09-30 01:25:09');
+INSERT INTO `tb_project`
+VALUES (13, 'cn.itlym', 'shoulder-framework', '0.7-SNAPSHOT', 'shoulder Build',
+        'Modules to centralize common resources and configuration for shoulder Maven builds.', '1', 'NORMAL',
+        '2023-09-30 01:37:30', NULL);
+INSERT INTO `tb_project`
+VALUES (23, 'cn.itlym', 'shoulder-archetype-simple', NULL, 'shoulder-archetype-simple',
+        'simple maven-archetype for Shoulder Framework', '1', 'NORMAL', '2023-09-30 02:16:02', NULL);
+/*!40000 ALTER TABLE `tb_project` ENABLE KEYS */;
+UNLOCK
+TABLES;
+
+--
+-- Dumping data for table `tb_third_project`
+--
+
+LOCK
+TABLES `tb_third_project` WRITE;
+/*!40000 ALTER TABLE `tb_third_project` DISABLE KEYS */;
+INSERT INTO `tb_third_project`
+VALUES ('cn.hutool', 'hutool-all', '5.8.22', '5.8.22', NULL, NULL, 'https://gitee.com/dromara/hutool',
+        'https://gitee.com/dromara/hutool/blob/v5-master/CHANGELOG.md', NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:00');
+INSERT INTO `tb_third_project`
+VALUES ('cn.hutool', 'hutool-core', '5.8.22', '5.8.22', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:01');
+INSERT INTO `tb_third_project`
+VALUES ('cn.hutool', 'hutool-http', '5.8.22', '5.8.22', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:02');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-api-doc', '0.6', '0.6', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:02');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-autoconfiguration', '0.7.1', '0.7.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:02');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-batch', '0.7.1', '0.7.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:02');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-cluster', '0.6', '0.6', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:02');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-core', '0.7.1', '0.7.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:02');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-crypto', '0.7.1', '0.7.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:02');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-crypto-negotiation', '0.7.1', '0.7.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:02');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-data-db', '0.7.1', '0.7.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:03');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-dependencies', '0.7.1', '0.7.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:03');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-ext-autoconfiguration', '0.6', '0.6', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:03');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-ext-common', '0.6', '0.6', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:03');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-ext-config', '0.6', '0.6', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:03');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-ext-dictionary', '0.6', '0.6', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:03');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-framework', '0.7.1', '0.7.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:03');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-http', '0.7.1', '0.7.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:03');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-monitor', '0.7.1', '0.7.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:03');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-operation-log', '0.7.1', '0.7.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:03');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-security', '0.7.1', '0.7.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:04');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-security-code', '0.6', '0.6', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:04');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-starter', '0.7.1', '0.7.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:04');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-starter-auth-server', '0.7.1', '0.7.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:04');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-starter-auth-session', '0.7.1', '0.7.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:04');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-starter-auth-token', '0.7.1', '0.7.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:04');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-starter-beanmap', '0.6', '0.6', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:04');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-starter-crypto', '0.6', '0.6', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:04');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-starter-monitor', '0.7.1', '0.7.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:05');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-starter-mysql', '0.7.1', '0.7.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:05');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-starter-operation-log', '0.6', '0.6', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:05');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-starter-security-code', '0.6', '0.6', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:05');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-starter-web', '0.7.1', '0.7.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:05');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-validation', '0.7.1', '0.7.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:05');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym', 'shoulder-web', '0.7.1', '0.7.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:05');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym.shoulder', 'lombok', '0.1', '0.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:05');
+INSERT INTO `tb_third_project`
+VALUES ('cn.itlym.shoulder', 'shoulder-maven-plugin', '1.1', '1.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:05');
+INSERT INTO `tb_third_project`
+VALUES ('com.alibaba', 'druid-spring-boot-starter', '1.2.19', '1.2.19', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:06');
+INSERT INTO `tb_third_project`
+VALUES ('com.alibaba', 'transmittable-thread-local', '2.14.3', '2.14.3', NULL, NULL,
+        'https://github.com/alibaba/transmittable-thread-local',
+        'https://github.com/alibaba/transmittable-thread-local/releases', NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:06');
+INSERT INTO `tb_third_project`
+VALUES ('com.aliyun.oss', 'aliyun-sdk-oss', '3.17.1', '3.17.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:06');
+INSERT INTO `tb_third_project`
+VALUES ('com.baomidou', 'mybatis-plus-boot-starter', '3.5.3.2', '3.5.3.2', NULL, NULL,
+        'https://github.com/baomidou/mybatis-plus', 'https://github.com/baomidou/mybatis-plus/blob/3.0/CHANGELOG.md',
+        NULL, '.*', 'x.y.z', 'NORMAL', '2023-10-03 16:00:06');
+INSERT INTO `tb_third_project`
+VALUES ('com.baomidou', 'mybatis-plus-generator', '3.5.3.2', '3.5.3.2', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:06');
+INSERT INTO `tb_third_project`
+VALUES ('com.belerweb', 'pinyin4j', '2.5.1', '2.5.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:07');
+INSERT INTO `tb_third_project`
+VALUES ('com.github.chris2018998', 'beecp', '3.4.2', '3.4.2', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:07');
+INSERT INTO `tb_third_project`
+VALUES ('com.github.pagehelper', 'pagehelper', '5.3.3', '5.3.3', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:07');
+INSERT INTO `tb_third_project`
+VALUES ('com.github.pagehelper', 'pagehelper-spring-boot-starter', '1.4.7', '1.4.7', NULL, NULL, NULL, NULL, NULL, '.*',
+        'x.y.z', 'NORMAL', '2023-10-03 16:00:07');
+INSERT INTO `tb_third_project`
+VALUES ('com.github.xiaoymin', 'knife4j-spring-boot-starter', '3.0.3', '3.0.3', NULL, NULL, NULL, NULL, NULL, '.*',
+        'x.y.z', 'NORMAL', '2023-10-03 16:00:07');
+INSERT INTO `tb_third_project`
+VALUES ('com.github.xiaoymin', 'knife4j-spring-ui', '3.0.3', '3.0.3', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:07');
+INSERT INTO `tb_third_project`
+VALUES ('com.google.code.findbugs', 'annotations', '3.0.1', '3.0.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:07');
+INSERT INTO `tb_third_project`
+VALUES ('com.google.guava', 'guava', '32.1.2-jre', '32.1.2-jre', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:07');
+INSERT INTO `tb_third_project`
+VALUES ('com.h2database', 'h2', '2.2.224', '2.2.224', NULL, NULL, 'https://github.com/h2database/h2database',
+        'https://github.com/h2database/h2database/releases', NULL, '.*', 'x.y.z', 'NORMAL', '2023-10-03 16:00:08');
+INSERT INTO `tb_third_project`
+VALUES ('com.nimbusds', 'nimbus-jose-jwt', '9.35', '9.35', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:08');
+INSERT INTO `tb_third_project`
+VALUES ('com.thoughtworks.xstream', 'xstream', '1.4.20', '1.4.20', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:09');
+INSERT INTO `tb_third_project`
+VALUES ('com.univocity', 'univocity-parsers', '2.9.1', '2.9.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:09');
+INSERT INTO `tb_third_project`
+VALUES ('commons-codec', 'commons-codec', '20041127.091804', '1.16.0', NULL, NULL,
+        'https://github.com/apache/commons-codec', 'https://github.com/apache/commons-codec/tags', NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:09');
+INSERT INTO `tb_third_project`
+VALUES ('commons-configuration', 'commons-configuration', '20041012.002804', '1.10', NULL, NULL, NULL, NULL, NULL, '.*',
+        'x.y.z', 'NORMAL', '2023-10-03 16:00:09');
+INSERT INTO `tb_third_project`
+VALUES ('commons-daemon', 'commons-daemon', '1.3.4', '1.3.4', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:09');
+INSERT INTO `tb_third_project`
+VALUES ('commons-io', 'commons-io', '20030203.000550', '2.14.0', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:10');
+INSERT INTO `tb_third_project`
+VALUES ('io.springfox', 'springfox-boot-starter', '3.0.0', '3.0.0', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:10');
+INSERT INTO `tb_third_project`
+VALUES ('io.springfox', 'springfox-core', '3.0.0', '3.0.0', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:10');
+INSERT INTO `tb_third_project`
+VALUES ('io.swagger', 'swagger-annotations', '2.0.0-rc2', '1.6.11', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:10');
+INSERT INTO `tb_third_project`
+VALUES ('io.swagger.core.v3', 'swagger-annotations', '2.2.16', '2.2.16', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:10');
+INSERT INTO `tb_third_project`
+VALUES ('javax.activation', 'activation', '1.1.1', '1.1.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:10');
+INSERT INTO `tb_third_project`
+VALUES ('javax.ws.rs', 'javax.ws.rs-api', '2.1.1', '2.1.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:10');
+INSERT INTO `tb_third_project`
+VALUES ('javax.xml.bind', 'jaxb-api', '2.4.0-b180830.0359', '2.4.0-b180830.0359', NULL, NULL, NULL, NULL, NULL, '.*',
+        'x.y.z', 'NORMAL', '2023-10-03 16:00:10');
+INSERT INTO `tb_third_project`
+VALUES ('net.java.dev.jna', 'jna', '5.13.0', '5.13.0', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:11');
+INSERT INTO `tb_third_project`
+VALUES ('net.sourceforge.tess4j', 'tess4j', '5.8.0', '5.8.0', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:11');
+INSERT INTO `tb_third_project`
+VALUES ('org.apache.commons', 'commons-collections4', '4.4', '4.4', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:11');
+INSERT INTO `tb_third_project`
+VALUES ('org.apache.commons', 'commons-lang3', '3.13.0', '3.13.0', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:11');
+INSERT INTO `tb_third_project`
+VALUES ('org.apache.maven.plugins', 'maven-archetype-plugin', '3.2.1', '3.2.1', NULL, NULL, NULL, NULL, NULL, '.*',
+        'x.y.z', 'NORMAL', '2023-10-03 16:00:11');
+INSERT INTO `tb_third_project`
+VALUES ('org.apache.maven.plugins', 'maven-compiler-plugin', '3.11.0', '3.11.0', NULL, NULL, NULL, NULL, NULL, '.*',
+        'x.y.z', 'NORMAL', '2023-10-03 16:00:11');
+INSERT INTO `tb_third_project`
+VALUES ('org.apache.maven.plugins', 'maven-gpg-plugin', '3.1.0', '3.1.0', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:11');
+INSERT INTO `tb_third_project`
+VALUES ('org.apache.maven.plugins', 'maven-jar-plugin', '3.3.0', '3.3.0', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:11');
+INSERT INTO `tb_third_project`
+VALUES ('org.apache.maven.plugins', 'maven-javadoc-plugin', '3.6.0', '3.6.0', NULL, NULL, NULL, NULL, NULL, '.*',
+        'x.y.z', 'NORMAL', '2023-10-03 16:00:12');
+INSERT INTO `tb_third_project`
+VALUES ('org.apache.maven.plugins', 'maven-resources-plugin', '3.3.1', '3.3.1', NULL, NULL, NULL, NULL, NULL, '.*',
+        'x.y.z', 'NORMAL', '2023-10-03 16:00:12');
+INSERT INTO `tb_third_project`
+VALUES ('org.apache.maven.plugins', 'maven-source-plugin', '3.3.0', '3.3.0', NULL, NULL, NULL, NULL, NULL, '.*',
+        'x.y.z', 'NORMAL', '2023-10-03 16:00:12');
+INSERT INTO `tb_third_project`
+VALUES ('org.apache.maven.plugins', 'maven-surefire-plugin', '3.1.2', '3.1.2', NULL, NULL, NULL, NULL, NULL, '.*',
+        'x.y.z', 'NORMAL', '2023-10-03 16:00:12');
+INSERT INTO `tb_third_project`
+VALUES ('org.apache.tika', 'tika-core', '2.9.0', '2.9.0', NULL, NULL, 'https://github.com/apache/tika',
+        'https://github.com/apache/tika/blob/main/CHANGES.txt', NULL, '.*', 'x.y.z', 'NORMAL', '2023-10-03 16:00:13');
+INSERT INTO `tb_third_project`
+VALUES ('org.bouncycastle', 'bcpkix-jdk15on', '1.70', '1.70', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:13');
+INSERT INTO `tb_third_project`
+VALUES ('org.bouncycastle', 'bcprov-jdk15on', '1.70', '1.70', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:13');
+INSERT INTO `tb_third_project`
+VALUES ('org.codehaus.mojo', 'cobertura-maven-plugin', '2.7', '2.7', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:13');
+INSERT INTO `tb_third_project`
+VALUES ('org.codehaus.mojo', 'findbugs-maven-plugin', '3.0.5', '3.0.5', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:13');
+INSERT INTO `tb_third_project`
+VALUES ('org.codehaus.mojo', 'license-maven-plugin', '2.2.0', '2.2.0', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:13');
+INSERT INTO `tb_third_project`
+VALUES ('org.codehaus.mojo', 'sonar-maven-plugin', '3.10.0.2594', '3.10.0.2594', NULL, NULL, NULL, NULL, NULL, '.*',
+        'x.y.z', 'NORMAL', '2023-10-03 16:00:13');
+INSERT INTO `tb_third_project`
+VALUES ('org.codehaus.mojo', 'versions-maven-plugin', '2.16.1', '2.16.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:13');
+INSERT INTO `tb_third_project`
+VALUES ('org.glassfish.jaxb', 'jaxb-runtime', '4.0.3', '4.0.3', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:14');
+INSERT INTO `tb_third_project`
+VALUES ('org.javassist', 'javassist', '3.29.2-GA', '3.29.2-GA', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:14');
+INSERT INTO `tb_third_project`
+VALUES ('org.jsoup', 'jsoup', '1.16.1', '1.16.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:14');
+INSERT INTO `tb_third_project`
+VALUES ('org.lz4', 'lz4-java', '1.8.0', '1.8.0', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:14');
+INSERT INTO `tb_third_project`
+VALUES ('org.mapstruct', 'mapstruct', '1.5.5.Final', '1.5.5.Final', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:15');
+INSERT INTO `tb_third_project`
+VALUES ('org.mapstruct', 'mapstruct-processor', '1.5.5.Final', '1.5.5.Final', NULL, NULL, NULL, NULL, NULL, '.*',
+        'x.y.z', 'NORMAL', '2023-10-03 16:00:15');
+INSERT INTO `tb_third_project`
+VALUES ('org.mockito', 'mockito-all', '2.0.2-beta', '1.10.19', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:15');
+INSERT INTO `tb_third_project`
+VALUES ('org.powermock', 'powermock-api-mockito', '1.7.4', '1.7.4', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:15');
+INSERT INTO `tb_third_project`
+VALUES ('org.powermock', 'powermock-api-mockito2', '2.0.9', '2.0.9', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:16');
+INSERT INTO `tb_third_project`
+VALUES ('org.powermock', 'powermock-module-junit4', '2.0.9', '2.0.9', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:16');
+INSERT INTO `tb_third_project`
+VALUES ('org.projectlombok', 'lombok', '1.18.30', '1.18.30', NULL, NULL, 'https://github.com/projectlombok/lombok',
+        'https://github.com/projectlombok/lombok/releases', NULL, '.*', 'x.y.z', 'NORMAL', '2023-10-03 16:00:16');
+INSERT INTO `tb_third_project`
+VALUES ('org.redisson', 'redisson', '3.23.5', '3.23.5', NULL, NULL, 'https://github.com/redisson/redisson',
+        'https://github.com/redisson/redisson/blob/master/CHANGELOG.md', NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:16');
+INSERT INTO `tb_third_project`
+VALUES ('org.sonatype.plugins', 'nexus-staging-maven-plugin', '1.6.13', '1.6.13', NULL, NULL, NULL, NULL, NULL, '.*',
+        'x.y.z', 'NORMAL', '2023-10-03 16:00:17');
+INSERT INTO `tb_third_project`
+VALUES ('org.springframework.boot', 'spring-boot-starter-parent', '3.1.4', '3.1.4', NULL, NULL,
+        'https://github.com/spring-projects/spring-boot', 'https://github.com/spring-projects/spring-boot/releases',
+        NULL, '.*', 'x.y.z', 'NORMAL', '2023-10-03 16:00:17');
+INSERT INTO `tb_third_project`
+VALUES ('org.springframework.cloud', 'spring-cloud-dependencies', '2022.0.4', '2022.0.4', NULL, NULL,
+        'https://spring.io/projects/spring-cloud#overview',
+        'https://docs.spring.io/spring-cloud/docs/current/reference/html', NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:17');
+INSERT INTO `tb_third_project`
+VALUES ('org.springframework.security.experimental', 'spring-security-oauth2-authorization-server', '0.1.2', '0.1.2',
+        NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL', '2023-10-03 16:00:17');
+INSERT INTO `tb_third_project`
+VALUES ('org.springframework.security.oauth', 'spring-security-oauth2', '2.5.2.RELEASE', '2.5.2.RELEASE', NULL, NULL,
+        NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL', '2023-10-03 16:00:17');
+INSERT INTO `tb_third_project`
+VALUES ('org.springframework.security.oauth.boot', 'spring-security-oauth2-autoconfigure', '2.6.8', '2.6.8', NULL, NULL,
+        NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL', '2023-10-03 16:00:18');
+INSERT INTO `tb_third_project`
+VALUES ('p6spy', 'p6spy', '3.9.1', '3.9.1', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z', 'NORMAL',
+        '2023-10-03 16:00:18');
+INSERT INTO `tb_third_project`
+VALUES ('pl.project13.maven', 'git-commit-id-plugin', '4.9.10', '4.9.10', NULL, NULL, NULL, NULL, NULL, '.*', 'x.y.z',
+        'NORMAL', '2023-10-03 16:00:18');
+/*!40000 ALTER TABLE `tb_third_project` ENABLE KEYS */;
+UNLOCK
+TABLES;

+ 137 - 0
pom-update-schema.sql

@@ -0,0 +1,137 @@
+-- MySQL dump 10.13  Distrib 8.0.17, for Win64 (x86_64)
+--
+-- Host: localhost    Database: db_pom_update
+-- ------------------------------------------------------
+-- Server version	8.0.27
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!50503 SET NAMES utf8mb4 */;
+/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
+/*!40103 SET TIME_ZONE='+00:00' */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+--
+-- Table structure for table `tb_user`
+--
+
+DROP TABLE IF EXISTS `tb_user`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!50503 SET character_set_client = utf8mb4 */;
+CREATE TABLE `tb_user`
+(
+    `id`                                  varchar(64) COLLATE utf8_unicode_ci NOT NULL,
+    `account`                             varchar(32) COLLATE utf8_unicode_ci  DEFAULT NULL,
+    `password`                            varchar(128) COLLATE utf8_unicode_ci DEFAULT NULL,
+    `name`                                varchar(32) COLLATE utf8_unicode_ci  DEFAULT NULL,
+    `email`                               varchar(64) COLLATE utf8_unicode_ci  DEFAULT NULL,
+    `phone`                               varchar(16) COLLATE utf8_unicode_ci  DEFAULT NULL,
+    `default_new_version_notify_strategy` varchar(16) COLLATE utf8_unicode_ci NOT NULL,
+    `create_time`                         datetime                             DEFAULT NULL,
+    PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `tb_project`
+--
+
+DROP TABLE IF EXISTS `tb_project`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!50503 SET character_set_client = utf8mb4 */;
+CREATE TABLE `tb_project`
+(
+    `id`          bigint                              NOT NULL AUTO_INCREMENT,
+    `group_id`    varchar(64) COLLATE utf8_unicode_ci NOT NULL,
+    `artifact_id` varchar(64) COLLATE utf8_unicode_ci NOT NULL,
+    `version`     varchar(64) COLLATE utf8_unicode_ci  DEFAULT NULL,
+    `name`        varchar(128) COLLATE utf8_unicode_ci DEFAULT NULL,
+    `description` varchar(512) COLLATE utf8_unicode_ci DEFAULT NULL,
+    `user_id`     varchar(64) COLLATE utf8_unicode_ci NOT NULL,
+    `status`      varchar(16) COLLATE utf8_unicode_ci  DEFAULT 'NOMARL',
+    `create_time` datetime                             DEFAULT NULL,
+    `update_time` datetime                             DEFAULT NULL,
+    PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8mb3 COLLATE=utf8_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `tb_dependency`
+--
+
+DROP TABLE IF EXISTS `tb_dependency`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!50503 SET character_set_client = utf8mb4 */;
+CREATE TABLE `tb_dependency`
+(
+    `id`                          bigint                              NOT NULL AUTO_INCREMENT,
+    `project_id`                  bigint                              NOT NULL,
+    `group_id`                    varchar(64) COLLATE utf8_unicode_ci NOT NULL,
+    `artifact_id`                 varchar(64) COLLATE utf8_unicode_ci NOT NULL,
+    `version`                     varchar(64) COLLATE utf8_unicode_ci NOT NULL,
+    `new_version_notify_strategy` varchar(32) COLLATE utf8_unicode_ci DEFAULT 'STABLE_ONLY',
+    PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=5522 DEFAULT CHARSET=utf8mb3 COLLATE=utf8_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `tb_third_project`
+--
+
+DROP TABLE IF EXISTS `tb_third_project`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!50503 SET character_set_client = utf8mb4 */;
+CREATE TABLE `tb_third_project`
+(
+    `group_id`               varchar(64) COLLATE utf8_unicode_ci NOT NULL,
+    `artifact_id`            varchar(64) COLLATE utf8_unicode_ci NOT NULL,
+    `version`                varchar(64) COLLATE utf8_unicode_ci  DEFAULT NULL,
+    `stable_version`         varchar(64) COLLATE utf8_unicode_ci  DEFAULT NULL,
+    `name`                   varchar(128) COLLATE utf8_unicode_ci DEFAULT NULL,
+    `description`            varchar(512) COLLATE utf8_unicode_ci DEFAULT NULL,
+    `home_url`               varchar(512) COLLATE utf8_unicode_ci DEFAULT NULL,
+    `change_log_url`         varchar(512) COLLATE utf8_unicode_ci DEFAULT NULL,
+    `open_source_protocol`   varchar(64) COLLATE utf8_unicode_ci  DEFAULT NULL,
+    `stable_version_pattern` varchar(64) COLLATE utf8_unicode_ci  DEFAULT NULL,
+    `version_rule`           varchar(32) COLLATE utf8_unicode_ci  DEFAULT NULL,
+    `status`                 varchar(32) COLLATE utf8_unicode_ci  DEFAULT NULL,
+    `update_time`            datetime                             DEFAULT NULL,
+    PRIMARY KEY (`group_id`, `artifact_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+--
+-- Table structure for table `tb_notify_record`
+--
+
+DROP TABLE IF EXISTS `tb_notify_record`;
+/*!40101 SET @saved_cs_client     = @@character_set_client */;
+/*!50503 SET character_set_client = utf8mb4 */;
+CREATE TABLE `tb_notify_record`
+(
+    `id`              bigint NOT NULL AUTO_INCREMENT,
+    `project_id`      bigint                              DEFAULT NULL,
+    `group_id`        varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
+    `artifact_id`     varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
+    `current_version` varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
+    `new_version`     varchar(64) COLLATE utf8_unicode_ci DEFAULT NULL,
+    `notified`        tinyint(1) DEFAULT NULL,
+    `notify_time`     datetime                            DEFAULT NULL,
+    PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=843 DEFAULT CHARSET=utf8mb3 COLLATE=utf8_unicode_ci;
+/*!40101 SET character_set_client = @saved_cs_client */;
+
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+-- Dump completed on 2023-10-03 17:37:55

+ 91 - 0
pom.xml

@@ -0,0 +1,91 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+
+    <parent>
+        <groupId>cn.itlym</groupId>
+        <artifactId>shoulder-parent</artifactId>
+        <version>0.7.1</version><!-- shoulder-version -->
+    </parent>
+
+    <groupId>com.lym.test</groupId>
+    <artifactId>pom-update</artifactId>
+    <version>1.0-SNAPSHOT</version>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-context-indexer</artifactId>
+            <optional>true</optional>
+        </dependency>
+
+        <dependency>
+            <groupId>cn.itlym</groupId>
+            <artifactId>shoulder-starter-web</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>cn.itlym</groupId>
+            <artifactId>shoulder-starter-mysql</artifactId>
+        </dependency>
+
+        <!-- JDBC: MySQL8 -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-data-jpa</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.alibaba</groupId>
+            <artifactId>druid-spring-boot-starter</artifactId>
+            <version>1.2.18</version>
+        </dependency>
+
+
+        <dependency>
+            <groupId>com.thoughtworks.xstream</groupId>
+            <artifactId>xstream</artifactId>
+<!--            <version>1.4.20</version>-->
+        </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-mail</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.projectlombok</groupId>
+            <artifactId>lombok</artifactId>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <finalName>executable</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-compiler-plugin</artifactId>
+                <configuration>
+                    <source>11</source>
+                    <target>11</target>
+                </configuration>
+            </plugin>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>2.7.1</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+
+        </plugins>
+    </build>
+
+</project>

+ 160 - 0
replaceAndStart.sh

@@ -0,0 +1,160 @@
+#!/bin/bash
+echo "开始运行Demo服务..."
+PARAM=$1;
+echo -e "Commit log: "$PARAM;
+#----------------------- 基本参数配置 start -----------------------
+# JAVA安装目录
+JAVA_PATH="/opt/jdk1.8.0_191/bin/java";
+# 运行环境配置
+JAVA_RUN_ENV="test";
+# drone部署的jar包所在路径
+DRONE_JAR_PATH="/home/drone/data/demoParant";
+# API工程
+APP_API_NAME="apiService-0.0.1-SNAPSHOT.jar"
+APP_API_PATH="/home/demoPatent/apiService"
+APP_API_PING_URL="http://127.0.0.1:18091/api/open/ping"
+APP_API_RUN=
+# 用户端工程
+APP_USER_NAME="userService-0.0.1-SNAPSHOT.jar"
+APP_USER_PATH="/home/demoPatent/userService"
+APP_USER_RUN=
+APP_USER_PING_URL="http://127.0.0.1:18071/user/open/ping"
+# 后台服务工程
+APP_BACK_NAME="backService-0.0.1-SNAPSHOT.jar"
+APP_BACK_PATH="/home/demoPatent/backService"
+APP_BACK_RUN=
+APP_BACK_PING_URL="http://127.0.0.1:18081/back/open/ping"
+
+# 记录是否有启动失败的服务
+APP_START_FAIL=
+APP_START_RESULT=
+#----------------------- 基本参数配置 end -----------------------
+
+echo "程序运行环境:$JAVA_RUN_ENV"
+#----------------------- 定义启动函数 start-----------------------
+startAPP() {
+    APP_NAME=$1;
+    APP_PATH=$2;
+    PING_URL=$3;
+    # echo "APP_NAME:$APP_NAME"
+    # echo "APP_PATH:$APP_PATH"
+    # echo "PING_URL:$APP_NAME"
+    # 部署新jar包到程序运行目录
+    if [ -f "$DRONE_JAR_PATH/$APP_NAME" ];then
+        echo "Move the new jar package to the deployment directory ..."
+        mv -f $DRONE_JAR_PATH/$APP_NAME $APP_PATH/$APP_NAME
+        else
+        echo "The drone original jar file not exist, skip move."
+    fi
+
+    # 获取程序PID
+    getPid() {
+        APP_PID=`ps -ef | grep -v grep | grep $APP_NAME | awk '{print $2}'`
+    }
+    getPid
+
+    # 启动前检查应用是否启动,如果已经启动则先停止再重新启动
+    while [ ${APP_PID} ]
+    do
+        echo -e "App ${APP_NAME} is still RUNNING! PID:$APP_PID";
+        echo "stop ${APP_NAME} ...";
+        kill -9 ${APP_PID};
+        sleep 2;
+        getPid
+    done
+
+    # 运行jar包
+    echo "start ${APP_NAME} ...."
+    cd ${APP_PATH}
+    nohup ${JAVA_PATH} -server -Xms256m -Xmx512m  -XX:MetaspaceSize=512m -XX:MaxMetaspaceSize=768m -Xss256k -jar ./${APP_NAME} --spring.profiles.active=$JAVA_RUN_ENV > /dev/null & 2>&1 &
+
+    # 请求测试接口,判断服务是否正常启动
+    getHttpCode () {
+        http_code=`curl -Is -m 10 -w %{http_code} -o /dev/null $PING_URL`;
+    }
+
+    # 检查服务启动状态
+    sleep 2s;
+    count=0;
+    # 获取接口状态码
+    getHttpCode
+    while [ $http_code -ne 200 ]
+    do
+        if (($count == 8));then
+            echo "${APP_NAME}: $(expr $count \* 5)秒内未启动,请检查!";
+            msg="start ${APP_NAME} failed!\n";
+            echo -e $msg;
+            APP_START_RESULT=$APP_START_RESULT$msg;
+            APP_START_FAIL="YES";
+            return;
+        fi
+        count=$(($count+1));
+        echo "${APP_NAME} waiting to start ...";
+        # sleep 1s;
+        sleep 5s;
+        # 获取接口状态码
+        getHttpCode
+        echo "http_code --> $http_code";
+    done
+
+    getPid
+    msg="start ${APP_NAME} success! PID=$APP_PID\n";
+    echo -e $msg;
+    APP_START_RESULT=$APP_START_RESULT$msg;
+}
+#----------------------- 函数定义结束 end -----------------------
+
+#----------------------- commit log 判断 start-----------------------
+# 根据commit日志参数判断启动哪个工程
+if [[ $PARAM == *'[CI API]'* ]]; then
+    echo -e "Commit参数指定启动API工程...\n";
+    APP_API_RUN="true"
+fi
+
+if [[ $PARAM == *'[CI USER]'* ]]; then
+    echo -e "Commit参数指定启动用户端工程...\n";
+    APP_USER_RUN="true"
+fi
+
+if [[ $PARAM == *'[CI BACK]'* ]]; then
+    echo -e "Commit参数指定启动BACK工程...\n";
+    APP_BACK_RUN="true"
+fi
+
+if [[ -z "$APP_API_RUN" ]] && [[ -z "$APP_USER_RUN" ]] && [[ -z "$APP_BACK_RUN" ]]; then
+    echo -e "Commit未指定参数,准备启动所有工程...\n";
+    APP_API_RUN="true"
+    APP_USER_RUN="true"
+    APP_BACK_RUN="true"
+fi
+#----------------------- commit log 判断结束 -----------------------
+
+# 启动运营端服务
+if [ $APP_API_RUN ]; then
+    echo "Run api service ..."
+    startAPP $APP_API_NAME $APP_API_PATH $APP_API_PING_URL
+fi
+# 启动用户端服务
+if [ $APP_USER_RUN ]; then
+    echo "Run user service"
+    startAPP $APP_USER_NAME $APP_USER_PATH $APP_USER_PING_URL
+fi
+# 启动商家端服务
+if [ $APP_BACK_RUN ]; then
+    echo "Run back service"
+    startAPP $APP_BACK_NAME $APP_BACK_PATH $APP_BACK_PING_URL
+fi
+
+
+# 删除drone构建缓存
+rm -rf $DRONE_JAR_PATH/*.jar
+
+# 打印运行结果
+echo "------------ service start status ------------"
+echo -e $APP_START_RESULT
+echo "----------------------------------------------"
+
+# 如果有启动失败的应用,则退出状态码为1,用于drone标记构建失败
+if [ $APP_START_FAIL ]; then
+    exit 1;
+fi

+ 23 - 0
run.sh

@@ -0,0 +1,23 @@
+java  \
+-Xms256M -Xmx256M  \
+-XX:ReservedCodeCacheSize=32m -XX:InitialCodeCacheSize=32m  \
+-XX:+UnlockExperimentalVMOptions -XX:+UseZGC  \
+-XX:ConcGCThreads=1 -XX:ParallelGCThreads=2  \
+-XX:ZCollectionInterval=120 -XX:ZAllocationSpikeTolerance=3  \
+-Xlog:safepoint,classhisto*=trace,age*,gc*=info:file=/opt/bin/java/logs/gc-%t.log:time,tid,tags:filecount=5,filesize=50m  \
+-verbose:gc \
+-XX:+PrintGCDetails \
+-XX:+PrintGCDateStamps \
+-Dsun.rmi.dgc.server.gcInterval=2592000000 \
+-Dsun.rmi.dgc.client.gcInterval=2592000000 \
+-server \
+-Dfile.encoding=UTF-8 \
+-XX:+HeapDumpOnOutOfMemoryError \
+-XX:HeapDumpPath=/opt/bin/java/logs \
+-XX:ErrorFile=/opt/bin/java/logs/hs_err_pid%p.log \
+-Xloggc:/opt/bin/java/logs/gc.log \
+-Xdebug \
+-Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n \
+-Dspring.config.additional-location=/opt/bin/java/config/application.properties \
+-jar \
+/opt/bin/java/executable.jar

+ 134 - 0
src/main/java/org/lym/pom/PojoMapConverter.java

@@ -0,0 +1,134 @@
+package org.lym.pom;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import com.thoughtworks.xstream.converters.Converter;
+import com.thoughtworks.xstream.converters.MarshallingContext;
+import com.thoughtworks.xstream.converters.UnmarshallingContext;
+import com.thoughtworks.xstream.io.HierarchicalStreamReader;
+import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
+
+/**
+ * 动态标签转换器 xml -> Map<String, String>
+ * @author lym
+ */
+public class PojoMapConverter implements Converter {
+
+    public PojoMapConverter() {
+        super();
+    }
+
+    @Override
+    public boolean canConvert(Class clazz) {
+        String classname = clazz.getName();
+        return classname.contains("Map") || classname.contains("List");
+    }
+
+    // ******************************** Map -> xml ***********************************
+
+    @Override
+    public void marshal(Object value, HierarchicalStreamWriter writer,
+                        MarshallingContext context) {
+
+        map2xml(value, writer, context);
+    }
+
+    protected void map2xml(Object value, HierarchicalStreamWriter writer,
+            MarshallingContext context) {
+        boolean bMap = true;
+        String classname = value.getClass().getName();
+
+        bMap = (!classname.contains("List"));
+        Map<String, Object> map;
+        List<Object> list;
+        String key;
+        Object subvalue;
+        if (bMap) {
+            map = (Map<String, Object>) value;
+            for (Iterator<Entry<String, Object>> iterator = map.entrySet()
+                    .iterator(); iterator.hasNext();) {
+                Entry<String, Object> entry = iterator
+                        .next();
+                key = (String) entry.getKey();
+                subvalue = entry.getValue();
+                writer.startNode(key);
+                if (subvalue.getClass().getName().indexOf("String") >= 0) {
+                    writer.setValue((String) subvalue);
+                } else {
+                    map2xml(subvalue, writer, context);
+                }
+                writer.endNode();
+            }
+
+        } else {
+            list = (List<Object>) value;
+            for (Object subval : list) {
+                subvalue = subval;
+                writer.startNode("child");
+                if (subvalue.getClass().getName().indexOf("String") >= 0) {
+                    writer.setValue((String) subvalue);
+                } else {
+                    map2xml(subvalue, writer, context);
+                }
+                writer.endNode();
+            }
+        }
+    }
+
+    // ******************************** xml -> Map ***********************************
+
+    @Override
+    public Map<String, Object> unmarshal(HierarchicalStreamReader reader,
+                                         UnmarshallingContext context) {
+        return (Map<String, Object>) populateMap(reader,
+                context);
+    }
+
+    protected Object populateMap(HierarchicalStreamReader reader,
+            UnmarshallingContext context) {
+        boolean bMap = true;
+        Map<String, Object> map = new HashMap<String, Object>();
+        List<Object> list = new ArrayList<Object>();
+        while (reader.hasMoreChildren()) {
+            reader.moveDown();
+            String key = reader.getNodeName();
+            Object value = null;
+            if (reader.hasMoreChildren()) {
+                value = populateMap(reader, context);
+            } else {
+                value = reader.getValue();
+            }
+            if (bMap) {
+                // 如果有多个重名标签,则转为 List
+                if (map.containsKey(key)) {
+                    // convert to list
+                    bMap = false;
+                    Iterator<Entry<String, Object>> iter = map.entrySet()
+                            .iterator();
+                    while (iter.hasNext())
+                        list.add(iter.next().getValue());
+                    // insert into list
+                    list.add(value);
+                } else {
+                    // insert into map
+                    map.put(key, value);
+                }
+            } else {
+                // insert into list
+                list.add(value);
+            }
+            reader.moveUp();
+        }
+        if (bMap) {
+            return map;
+        } else {
+            return list;
+        }
+    }
+
+}

+ 24 - 0
src/main/java/org/lym/pom/PomUpdateApplication.java

@@ -0,0 +1,24 @@
+package org.lym.pom;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.stereotype.Indexed;
+
+/**
+ *  pom update app
+ *
+ * @author lym
+ */
+@Indexed
+@EnableAsync
+@EnableScheduling
+@SpringBootApplication
+public class PomUpdateApplication {
+
+    public static void main(String[] args) {
+        SpringApplication.run(PomUpdateApplication.class, args);
+    }
+
+}

+ 16 - 0
src/main/java/org/lym/pom/annotation/ThirdProjectInfoSpider.java

@@ -0,0 +1,16 @@
+package org.lym.pom.annotation;
+
+import org.springframework.beans.factory.annotation.Qualifier;
+
+import java.lang.annotation.*;
+
+/**
+ * 标记专门用来爬取版本号的客户端
+ * @author lym
+ */
+@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Inherited
+@Qualifier
+public @interface ThirdProjectInfoSpider {}

+ 45 - 0
src/main/java/org/lym/pom/config/DependencyExtInfoProperties.java

@@ -0,0 +1,45 @@
+package org.lym.pom.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.ApplicationListener;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.context.event.ContextRefreshedEvent;
+
+import java.util.HashMap;
+import java.util.List;
+
+@Configuration
+@ConfigurationProperties(
+        prefix = "pomupdate"
+)
+@Data
+public class DependencyExtInfoProperties implements ApplicationListener<ContextRefreshedEvent> {
+
+    private static final HashMap<String, DependencyExtInfo> cache = new HashMap<>();
+
+    /**
+     * yaml 里 map 带特殊字符不好处理,用list更容易读和维护
+     */
+    private List<DependencyExtInfo> extInfoList;
+
+    @Override
+    public void onApplicationEvent(ContextRefreshedEvent event) {
+        synchronized (cache) {
+            extInfoList.forEach(extInfo -> cache.put(extInfo.getId(), extInfo));
+        }
+    }
+
+    public static DependencyExtInfo fetchExtInfoFromCache(String id) {
+        return cache.get(id);
+    }
+
+    @Data
+    public static class DependencyExtInfo {
+        private String id;
+
+        private String changeLogUrl;
+
+        private String opensourceUrl;
+    }
+}

+ 23 - 0
src/main/java/org/lym/pom/config/MailProperties.java

@@ -0,0 +1,23 @@
+package org.lym.pom.config;
+
+import lombok.Data;
+import org.springframework.boot.context.properties.ConfigurationProperties;
+
+import java.nio.charset.Charset;
+import java.util.Map;
+
+@ConfigurationProperties(
+    prefix = "shoulder.mail"
+)
+@Data
+public class MailProperties {
+    private String host;
+    private Integer port;
+    private String senderName;
+    private String username;
+    private String password;
+    private String protocol = "smtp";
+    private Charset defaultEncoding;
+    private Map<String, String> properties;
+    private String jndiName;
+}

+ 38 - 0
src/main/java/org/lym/pom/config/MailSenderConfig.java

@@ -0,0 +1,38 @@
+package org.lym.pom.config;
+
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.mail.javamail.JavaMailSenderImpl;
+
+import java.util.Map;
+import java.util.Properties;
+
+/**
+ * @author lym
+ */
+@Configuration
+@EnableConfigurationProperties({MailProperties.class})
+public class MailSenderConfig {
+
+
+    @Bean
+    public JavaMailSenderImpl javaMailSender(MailProperties properties) {
+        JavaMailSenderImpl sender = new JavaMailSenderImpl();
+        sender.setHost(properties.getHost());
+        sender.setPort(properties.getPort());
+        sender.setUsername(properties.getUsername());
+        sender.setPassword(properties.getPassword());
+        sender.setDefaultEncoding(properties.getDefaultEncoding().name());
+        if (!properties.getProperties().isEmpty()) {
+            sender.setJavaMailProperties(this.asProperties(properties.getProperties()));
+        }
+        return sender;
+    }
+
+    private Properties asProperties(Map<String, String> source) {
+        Properties properties = new Properties();
+        properties.putAll(source);
+        return properties;
+    }
+}

+ 13 - 0
src/main/java/org/lym/pom/config/ThirdExtInfoConfig.java

@@ -0,0 +1,13 @@
+package org.lym.pom.config;
+
+import org.springframework.boot.context.properties.EnableConfigurationProperties;
+import org.springframework.context.annotation.Configuration;
+
+/**
+ * @author lym
+ */
+@Configuration
+@EnableConfigurationProperties({DependencyExtInfoProperties.class})
+public class ThirdExtInfoConfig {
+
+}

+ 31 - 0
src/main/java/org/lym/pom/config/VersionClientConfig.java

@@ -0,0 +1,31 @@
+package org.lym.pom.config;
+
+import org.lym.pom.annotation.ThirdProjectInfoSpider;
+import org.lym.pom.util.HttpsClientRequestFactory;
+import org.lym.pom.util.UserAgentInterceptor;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.mail.javamail.JavaMailSenderImpl;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.Properties;
+
+/**
+ * @author lym
+ */
+@Configuration
+public class VersionClientConfig {
+
+    /**
+     * 专门用来获取版本号的客户端
+     * @return RestTemplate
+     */
+    @Bean
+    @ThirdProjectInfoSpider
+    public RestTemplate versionClient() {
+        RestTemplate rest = new RestTemplate(new HttpsClientRequestFactory());
+        rest.getInterceptors().add(new UserAgentInterceptor());
+        return rest;
+    }
+
+}

+ 13 - 0
src/main/java/org/lym/pom/constant/ContextKey.java

@@ -0,0 +1,13 @@
+package org.lym.pom.constant;
+
+/**
+ * 稳定版本号规则
+ *
+ * @author lym
+ */
+public interface ContextKey {
+
+    String NOTIFY_INSTANTLY_AFTER_CHECK = "notifyInstantlyAfterCheck";
+    String NOTIFY_REASON = "notifyReason";
+
+}

+ 30 - 0
src/main/java/org/lym/pom/constant/NewVersionNotifyStrategyEnum.java

@@ -0,0 +1,30 @@
+package org.lym.pom.constant;
+
+/**
+ * 新版本发布时,如何反应
+ * @author lym
+ */
+public enum NewVersionNotifyStrategyEnum {
+
+    /** 一有新版本就通知 */
+    ALWAYS,
+
+    /** 只有发布稳定版本时候才通知*/
+    STABLE_ONLY,
+
+    /** 忽略更新(不通知) */
+    IGNORE,
+    ;
+
+    private String value;
+
+    NewVersionNotifyStrategyEnum(){
+        value = name();
+    }
+
+    public String getValue() {
+        return this.value;
+    }
+
+
+}

+ 47 - 0
src/main/java/org/lym/pom/constant/NotifyTimeEnum.java

@@ -0,0 +1,47 @@
+package org.lym.pom.constant;
+
+import java.time.LocalTime;
+
+/**
+ * 发送通知的时间
+ */
+public enum NotifyTimeEnum {
+
+    /**
+     * 上午 6 点
+     */
+    AM_6,
+    AM_7,
+    AM_8,
+    AM_9,
+    AM_10,
+    AM_11,
+    AM_12,
+
+    /**
+     * 下午 1 - 11
+     */
+    PM_1,
+    PM_2,
+    PM_3,
+    PM_4,
+    PM_5,
+    PM_6,
+    PM_7,
+    PM_8,
+    PM_9,
+    PM_10,
+    PM_11,
+    ;
+
+    private final LocalTime time;
+
+    NotifyTimeEnum(){
+        int hourOffSet = this.name().startsWith("AM") ? 0 : 12;
+        int hour = Integer.parseInt(this.name().split("_")[1]);
+        time = LocalTime.of(hourOffSet + hour, 0);
+    }
+
+    public LocalTime getTime() {
+        return time;
+    }}

+ 32 - 0
src/main/java/org/lym/pom/constant/StableVersionPatterns.java

@@ -0,0 +1,32 @@
+package org.lym.pom.constant;
+
+/**
+ * 稳定版本号规则
+ *
+ * @author lym
+ */
+public interface StableVersionPatterns {
+
+    /**
+     * spring-boot
+     */
+    String X_Y_Z = "[\\d]+\\.[\\d]+\\.[\\d]+";
+
+    String X_Y_Z__RELEASE = "[\\d]+\\.[\\d]+\\.[\\d]+-RELEASE";
+
+    String X_Y_Z_RELEASE = "[\\d]+\\.[\\d]+\\.[\\d]+\\.RELEASE";
+
+    String X_Y_Z_release = "[\\d]+\\.[\\d]+\\.[\\d]+\\.release";
+
+    /**
+     * spring-cloud
+     */
+    String ABC_SR = "[A-Z][a-z]+ SR[\\d]*";
+
+
+    // -------------- 不包含 ----------
+
+    String NOT_SNAPSHOT = ".*\\.SNAPSHOT";
+
+
+}

+ 27 - 0
src/main/java/org/lym/pom/constant/StatusEnum.java

@@ -0,0 +1,27 @@
+package org.lym.pom.constant;
+
+/**
+ * @author lym
+ */
+
+public enum StatusEnum {
+
+    /** */
+    NORMAL,
+
+    /** */
+    DELETED,
+    ;
+
+    private String value;
+
+    StatusEnum(){
+        this.value = name();
+    }
+
+    public String getValue() {
+        return value;
+    }
+
+
+}

+ 44 - 0
src/main/java/org/lym/pom/constant/ThirdProjectInfoSource.java

@@ -0,0 +1,44 @@
+package org.lym.pom.constant;
+
+/**
+ * 用于获取第三方依赖信息的途径
+ * @author lym
+ */
+public interface ThirdProjectInfoSource {
+
+    /**
+     * 获取默认 url 模板
+     * @param groupId       groupId
+     * @param artifactId    artifactId
+     * @return              默认 url 模板
+     */
+    String getUrl(String groupId, String artifactId);
+
+
+    /**
+     * 项目版本号列表
+     * @return 匹配符
+     */
+    String getVersionsPattern();
+
+    /** 项目名称 */
+    String getNamePattern();
+
+    /** 项目描述 */
+    String getDescriptionPattern();
+
+    /** 项目主页 */
+    String getHomeUrlPattern();
+
+    /** 更新日志地址 */
+    String getChangeLogUrlPattern();
+
+    /** 开源协议 */
+    String getOpenSourceProtocolPattern();
+
+
+    interface Placeholder{
+        String GROUP_ID = "{groupId}";
+        String ARTIFACT_ID = "{artifactId}";
+    }
+}

+ 107 - 0
src/main/java/org/lym/pom/constant/ThirdProjectInfoSourceEnum.java

@@ -0,0 +1,107 @@
+package org.lym.pom.constant;
+
+import static org.lym.pom.constant.ThirdProjectInfoSource.Placeholder.*;
+
+/**
+ * @author lym
+ */
+
+public enum ThirdProjectInfoSourceEnum implements ThirdProjectInfoSource {
+
+    /** mvn jar
+     * https://www.mvnjar.com/mysql/mysql-connector-java/jar.html
+     */
+    MVN_JAR("https://www.mvnjar.com/{groupId}/{artifactId}/jar.html",
+            "<th class=\"thread\"><a href=\".*?/detail.html\">(.*?)</a></th>",
+            "<td><span>(.*?)</span>",
+            "<i class=\"fa fa-info-circle\" aria-hidden=\"true\"></i>(.*?)</p>",
+            "<td><span>(http.*?)</span></td>",
+            "",
+            "<td colspan=\"2\">\\s*?<span>\\s*?<a rel=\"nofollow\" href=\".*?\" target=\"_blank\">(.*?)</a>\\s*?</span>\\s*?</td>"
+    ),
+
+    /** 阿里云 */
+    ALI_CLOUD("https://maven.aliyun.com/artifact/aliyunMaven/searchArtifactByGav?_input_charset=utf-8&groupId={groupId}&repoId=central&artifactId={artifactId}&version=",
+            "\"repositoryId\":\"central\",\"version\":\"(.*?)\"}"),
+
+    /**
+     * 中央仓库
+     */
+    CENTRAL("https://mvnrepository.com/artifact/{groupId}/{artifactId}",
+            " class=\"vbtn release\">(.*?)</a>"),
+
+    /**
+     * github
+     */
+    GITHUB("https://github.com/{groupId}/{artifactId}/releases",
+            "<span class=\"css-truncate-target\" style=\"max-width: [\\d]+px\">(.*?)</span>");
+    ;
+
+    private String urlTemplate;
+
+    private String versionPattern;
+
+    private String namePattern;
+
+    private String descriptionPattern;
+
+    private String homeUrlPattern;
+
+    private String changeLogUrlPattern;
+
+    private String openSourceProtocolPattern;
+
+    ThirdProjectInfoSourceEnum(String urlTemplate, String versionPattern, String namePattern,
+                               String descriptionPattern, String homeUrlPattern, String changeLogUrlPattern,
+                               String openSourceProtocolPattern){
+        this.urlTemplate = urlTemplate;
+        this.versionPattern = versionPattern;
+        this.namePattern = namePattern;
+        this.descriptionPattern = descriptionPattern;
+        this.homeUrlPattern = homeUrlPattern;
+        this.changeLogUrlPattern = changeLogUrlPattern;
+        this.openSourceProtocolPattern = openSourceProtocolPattern;
+
+    }
+
+    ThirdProjectInfoSourceEnum(String urlTemplate, String versionPattern){
+        this.urlTemplate = urlTemplate;
+        this.versionPattern = versionPattern;
+    }
+
+    @Override
+    public String getUrl(String groupId, String artifactId){
+        return urlTemplate.replace(GROUP_ID, groupId).replace(ARTIFACT_ID, artifactId);
+    }
+
+    @Override
+    public String getVersionsPattern() {
+        return versionPattern;
+    }
+
+    @Override
+    public String getNamePattern() {
+        return namePattern;
+    }
+
+    @Override
+    public String getDescriptionPattern() {
+        return descriptionPattern;
+    }
+
+    @Override
+    public String getHomeUrlPattern() {
+        return homeUrlPattern;
+    }
+
+    @Override
+    public String getChangeLogUrlPattern() {
+        return changeLogUrlPattern;
+    }
+
+    @Override
+    public String getOpenSourceProtocolPattern() {
+        return openSourceProtocolPattern;
+    }
+
+}

+ 39 - 0
src/main/java/org/lym/pom/constant/ThirdProjectVersionStatusEnum.java

@@ -0,0 +1,39 @@
+package org.lym.pom.constant;
+
+/**
+ * @author lym
+ */
+public enum ThirdProjectVersionStatusEnum {
+
+    /**
+     * 第一次引入,还未进行爬取
+     */
+    BORN,
+
+    /**
+     * 正常
+     */
+    NORMAL,
+
+    /**
+     * 需要检查爬取记录,人工干涉
+     */
+    EXCEPTION,
+
+    /**
+     * 项目停止更新、维护,不再推荐依赖
+     * 暂不使用
+     */
+    STOP,
+
+    ;
+    ThirdProjectVersionStatusEnum(){
+        this.status = name();
+    }
+
+    private String status;
+
+    public String getStatus() {
+        return status;
+    }
+}

+ 85 - 0
src/main/java/org/lym/pom/controller/DependencyController.java

@@ -0,0 +1,85 @@
+package org.lym.pom.controller;
+
+import org.lym.pom.constant.NewVersionNotifyStrategyEnum;
+import org.lym.pom.entity.DependencyEntity;
+import org.lym.pom.entity.ProjectEntity;
+import org.lym.pom.service.IDependencyService;
+import org.lym.pom.service.IProjectService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.constraints.Email;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+/**
+ * 依赖相关
+ *
+ * @author lym
+ */
+@Validated
+@RestController
+@RequestMapping("dependencies")
+public class DependencyController {
+
+    @Autowired
+    private IProjectService projectService;
+
+    @Autowired
+    private IDependencyService dependencyService;
+
+    /**
+     * 查询 特定工程 的依赖列表
+     * http://localhost:12345/dependencies/3
+     *
+     * @return 所有依赖
+     */
+    @GetMapping("{projectId}")
+    public List<DependencyEntity> query(@PathVariable("projectId") Long projectId){
+        return dependencyService.findAllByProjectId(projectId);
+    }
+
+    /**
+     * http://localhost:12345/dependencies/updateNotifyStrategy?projectId=10&notifyStrategy=ALWAYS&email=cn_lym@foxmail.com
+     * @param projectId
+     * @param notifyStrategy
+     * @param email
+     * @return
+     */
+    @GetMapping("updateNotifyStrategy")
+    public String updateAllNotifyStrategyByProjectId(@NotNull Long projectId, @NotNull String notifyStrategy, @NotEmpty @Email String email){
+        NewVersionNotifyStrategyEnum newNotifyStrategy = NewVersionNotifyStrategyEnum.valueOf(notifyStrategy);
+        // 校验 email
+        ProjectEntity projectEntity = projectService.findById(projectId);
+        if(projectEntity == null){
+            throw new IllegalStateException("project not exist, projectId=" + projectId);
+        }
+        if(!projectEntity.getUserId().equals(email)){
+            throw new IllegalStateException("permission deny can't change strategy, projectId=" + projectId + ", email=" + email);
+        }
+        dependencyService.updateAllNotifyStrategyByProjectId(projectId, newNotifyStrategy);
+        return "changed project(groupId=" + projectEntity.getArtifactId() + ",artifactId=" + projectEntity.getArtifactId()
+                + ") notifyStrategy to '" + notifyStrategy + "'";
+    }
+
+    /**
+     * 更新依赖
+     */
+    //@PostMapping
+    public String update(DependencyEntity dependency){
+        dependencyService.update(dependency);
+        return "success";
+    }
+
+    /**
+     * 更新依赖列表
+     */
+    //@PostMapping("_search")
+    public String updateBatch(List<DependencyEntity> dependencies){
+        dependencyService.update(dependencies);
+        return "success";
+    }
+
+}

+ 92 - 0
src/main/java/org/lym/pom/controller/ProjectController.java

@@ -0,0 +1,92 @@
+package org.lym.pom.controller;
+
+import org.lym.pom.constant.ContextKey;
+import org.lym.pom.dto.xml.ProjectDTO;
+import org.lym.pom.entity.ProjectEntity;
+import org.lym.pom.entity.UserEntity;
+import org.lym.pom.service.IPomAnalyzerService;
+import org.lym.pom.service.IProjectService;
+import org.lym.pom.service.IUserService;
+import org.shoulder.core.context.AppContext;
+import org.shoulder.core.exception.CommonErrorCodeEnum;
+import org.shoulder.core.util.AssertUtils;
+import org.shoulder.validate.annotation.FileType;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.context.properties.bind.DefaultValue;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestMethod;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.validation.constraints.Email;
+import javax.validation.constraints.NotEmpty;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * project
+ *
+ * @author lym
+ */
+@Validated
+@RestController
+@RequestMapping("projects")
+public class ProjectController {
+
+    @Autowired
+    private IPomAnalyzerService pomAnalyzerService;
+
+    @Autowired
+    private IProjectService projectService;
+
+    @Autowired
+    private IUserService userService;
+
+    //@RequestMapping(value = "uploadPomXml", method = {RequestMethod.POST, RequestMethod.PUT})
+    public void uploadPomXml(@FileType(allowSuffix = "xml", maxSize = "200kb", nameAllowPattern = "pom\\.xml")
+                                     MultipartFile pomXml) {
+        ProjectDTO projectDTO = pomAnalyzerService.analysisPom(pomXml);
+        projectService.save(projectDTO);
+    }
+
+    @RequestMapping(value = "create", method = {RequestMethod.POST, RequestMethod.PUT})
+    public String create(@FileType(allowSuffix = "xml", maxSize = "200kb", nameAllowPattern = "pom\\.xml")
+                                     MultipartFile pomXml, @NotEmpty @Email String email,
+                         @DefaultValue("false") Boolean notifyInstantlyAfterCheck, String notifyReason) {
+        if(notifyInstantlyAfterCheck) {
+            // 防止 xss
+            AssertUtils.notBlank(notifyReason, CommonErrorCodeEnum.ILLEGAL_PARAM, "notifyReason");
+        }
+        UserEntity userEntity = userService.findById(email);
+        if (userEntity == null) {
+            userEntity = new UserEntity();
+            userEntity.setId(email);
+            userEntity.setName(email);
+            userEntity.setEmail(email);
+            userEntity.setCreateTime(LocalDateTime.now());
+            userService.save(userEntity);
+        }
+        ProjectDTO projectDTO = pomAnalyzerService.analysisPom(pomXml);
+        AppContext.set(ContextKey.NOTIFY_INSTANTLY_AFTER_CHECK, notifyInstantlyAfterCheck);
+        AppContext.set(ContextKey.NOTIFY_REASON, "API_INVOKED::" + notifyReason);
+        projectService.save(projectDTO, email);
+        AppContext.remove(ContextKey.NOTIFY_INSTANTLY_AFTER_CHECK);
+        AppContext.remove(ContextKey.NOTIFY_REASON);
+        return "添加成功!";
+    }
+
+
+    /**
+     * 查询 工程 列表
+     * http://localhost:12345/projects/list?email=xxx
+     *
+     * @return 查询我的所有工程
+     */
+    @GetMapping("list")
+    public List<ProjectEntity> showMyProjectList(@NotEmpty @Email String email) {
+        return projectService.findByUserId(email);
+    }
+
+}

+ 16 - 0
src/main/java/org/lym/pom/controller/ThirdDependencyController.java

@@ -0,0 +1,16 @@
+package org.lym.pom.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * 仅管理员可以修改
+ *
+ * @author lym
+ */
+@RestController
+@RequestMapping("thirdDependencies")
+public class ThirdDependencyController {
+
+
+}

+ 20 - 0
src/main/java/org/lym/pom/dto/business/NotifyEmailBO.java

@@ -0,0 +1,20 @@
+package org.lym.pom.dto.business;
+
+import lombok.Data;
+
+/**
+ * @author lym
+ */
+@Data
+public class NotifyEmailBO {
+
+    /** 接收者邮件 */
+    private String email;
+
+    /** 邮件主题 */
+    private String subject;
+
+    /** 邮件内容 */
+    private String content;
+
+}

+ 63 - 0
src/main/java/org/lym/pom/dto/business/NotifyProjectBO.java

@@ -0,0 +1,63 @@
+package org.lym.pom.dto.business;
+
+
+import lombok.Data;
+import lombok.experimental.Accessors;
+import org.lym.pom.entity.NotifyRecordEntity;
+import org.lym.pom.entity.ProjectEntity;
+import org.lym.pom.entity.ThirdProjectEntity;
+import org.lym.pom.entity.UserEntity;
+
+import java.util.LinkedList;
+import java.util.List;
+
+
+/**
+ * project
+ * @author lym
+ */
+@Data
+@Accessors(chain = true)
+public class NotifyProjectBO {
+
+    private Long projectId;
+
+    private String groupId;
+
+    private String artifactId;
+
+    private String version;
+
+    private String name;
+
+    private String description;
+
+    private String notifyReason;
+
+    private UserEntity user;
+
+    private List<NotifyRecordBO> notifyRecordBOList;
+
+    public NotifyProjectBO(ProjectEntity projectEntity, UserEntity user){
+        this.projectId = projectEntity.getId();
+        this.groupId = projectEntity.getGroupId();
+        this.artifactId = projectEntity.getArtifactId();
+        this.version = projectEntity.getVersion();
+        this.name = projectEntity.getName();
+        this.description = projectEntity.getDescription();
+        this.user = user;
+    }
+
+    private NotifyProjectBO addNotifyRecordBO(NotifyRecordBO notifyRecordBO){
+        if(this.notifyRecordBOList == null){
+            this.notifyRecordBOList = new LinkedList<>();
+        }
+        this.notifyRecordBOList.add(notifyRecordBO);
+        return this;
+    }
+
+    public NotifyProjectBO addNotifyRecordBO(NotifyRecordEntity notifyRecordEntity, ThirdProjectEntity thirdProjectEntity){
+        return addNotifyRecordBO(new NotifyRecordBO(notifyRecordEntity, thirdProjectEntity));
+    }
+
+}

+ 43 - 0
src/main/java/org/lym/pom/dto/business/NotifyRecordBO.java

@@ -0,0 +1,43 @@
+package org.lym.pom.dto.business;
+
+import lombok.Data;
+import org.lym.pom.entity.DependencyIndex;
+import org.lym.pom.entity.NotifyRecordEntity;
+import org.lym.pom.entity.ThirdProjectEntity;
+
+import javax.persistence.*;
+import java.util.Date;
+
+/**
+ * 通知记录,对应着 project 中的一个依赖
+ * @author lym
+ */
+@Data
+public class NotifyRecordBO {
+
+    /** 依赖 id*/
+    private String groupId;
+
+    /** 依赖 id */
+    private String artifactId;
+
+    /** 当前该依赖对应的版本(project.dependency.version) */
+    private String currentVersion;
+
+    private ThirdProjectEntity thirdProject;
+
+    NotifyRecordBO(NotifyRecordEntity notifyRecordEntity, ThirdProjectEntity thirdProjectEntity){
+        this.groupId = notifyRecordEntity.getGroupId();
+        this.artifactId = notifyRecordEntity.getArtifactId();
+        this.currentVersion = notifyRecordEntity.getCurrentVersion();
+        this.thirdProject = thirdProjectEntity;
+    }
+
+    /**
+     * 获取 第三方依赖的 id
+     */
+    public DependencyIndex getDependencyIndex(){
+        return new DependencyIndex(groupId, artifactId);
+    }
+
+}

+ 41 - 0
src/main/java/org/lym/pom/dto/business/ThirdDependencyUpdateBO.java

@@ -0,0 +1,41 @@
+package org.lym.pom.dto.business;
+
+import lombok.Data;
+import org.lym.pom.entity.DependencyEntity;
+import org.lym.pom.entity.DependencyIndex;
+import org.lym.pom.entity.ThirdProjectEntity;
+
+/**
+ * 第三方依赖,发送了版本更新 Event
+ *
+ * @author lym
+ */
+@Data
+public class ThirdDependencyUpdateBO {
+
+    /**
+     * 第三方依赖标识
+     */
+    private DependencyIndex dependencyIndex;
+
+    /**
+     * 更新后的版本
+     */
+    private String latestVersion;
+
+    /**
+     * 更新后的版本
+     */
+    private String latestStableVersion;
+
+
+    /**
+     * 暂时不支持更多的构造方法,主要是为了可以拿到更多的信息,如
+     */
+    public ThirdDependencyUpdateBO(DependencyIndex dependencyIndex, String latestVersion, String latestStableVersion) {
+        this.dependencyIndex = dependencyIndex;
+        this.latestVersion = latestVersion;
+        this.latestStableVersion = latestStableVersion;
+    }
+
+}

+ 18 - 0
src/main/java/org/lym/pom/dto/xml/BuildDTO.java

@@ -0,0 +1,18 @@
+package org.lym.pom.dto.xml;
+
+import lombok.Data;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author lym
+ */
+@Data
+public class BuildDTO {
+
+    private PluginManagementDTO pluginManagement;
+
+    private List<PluginDTO> plugins = new LinkedList<>();
+
+}

+ 20 - 0
src/main/java/org/lym/pom/dto/xml/DependencyBaseDTO.java

@@ -0,0 +1,20 @@
+package org.lym.pom.dto.xml;
+
+import lombok.Data;
+
+/**
+ * @author lym
+ */
+@Data
+public class DependencyBaseDTO {
+
+
+    private String groupId;
+
+
+    private String artifactId;
+
+
+    private String version;
+
+}

+ 11 - 0
src/main/java/org/lym/pom/dto/xml/DependencyDTO.java

@@ -0,0 +1,11 @@
+package org.lym.pom.dto.xml;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
+/**
+ * @author lym
+ */
+@XStreamAlias("dependency")
+public class DependencyDTO extends DependencyBaseDTO {
+
+}

+ 17 - 0
src/main/java/org/lym/pom/dto/xml/DependencyManagementDTO.java

@@ -0,0 +1,17 @@
+package org.lym.pom.dto.xml;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import lombok.Data;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author lym
+ */
+@Data
+@XStreamAlias("dependencyManagement")
+public class DependencyManagementDTO {
+
+    private List<DependencyDTO> dependencies = new LinkedList<>();
+}

+ 11 - 0
src/main/java/org/lym/pom/dto/xml/PluginDTO.java

@@ -0,0 +1,11 @@
+package org.lym.pom.dto.xml;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+
+/**
+ * @author lym
+ */
+@XStreamAlias("plugin")
+public class PluginDTO extends DependencyBaseDTO {
+
+}

+ 17 - 0
src/main/java/org/lym/pom/dto/xml/PluginManagementDTO.java

@@ -0,0 +1,17 @@
+package org.lym.pom.dto.xml;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import lombok.Data;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * @author lym
+ */
+@Data
+@XStreamAlias("pluginManagement")
+public class PluginManagementDTO {
+
+    private List<PluginDTO> plugins = new LinkedList<>();
+}

+ 41 - 0
src/main/java/org/lym/pom/dto/xml/ProjectDTO.java

@@ -0,0 +1,41 @@
+package org.lym.pom.dto.xml;
+
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import com.thoughtworks.xstream.annotations.XStreamConverter;
+import lombok.Data;
+import org.lym.pom.PojoMapConverter;
+
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author lym
+ */
+@Data
+@XStreamAlias("project")
+public class ProjectDTO {
+
+    private DependencyDTO parent;
+
+    private String name;
+
+    private String description;
+
+    private String groupId;
+
+    private String artifactId;
+
+    private String version;
+
+    @XStreamConverter(PojoMapConverter.class)
+    private Map<String, String> properties = new HashMap<>();
+
+    private DependencyManagementDTO dependencyManagement;
+
+    private List<DependencyDTO> dependencies = new LinkedList<>();
+
+    private BuildDTO build;
+
+}

+ 39 - 0
src/main/java/org/lym/pom/entity/DependencyEntity.java

@@ -0,0 +1,39 @@
+package org.lym.pom.entity;
+
+import lombok.Data;
+import org.lym.pom.constant.NewVersionNotifyStrategyEnum;
+
+import javax.persistence.*;
+
+/**
+ * 特定 project 的依赖项
+ *
+ * @author lym
+ */
+@Data
+@Entity
+@Table(name="tb_dependency")
+public class DependencyEntity {
+    @Id
+    @GeneratedValue(strategy= GenerationType.IDENTITY)
+    private Long id;
+
+    /** 项目 id */
+    private Long projectId;
+
+    /** 依赖 id*/
+    private String groupId;
+
+    /** 依赖 id */
+    private String artifactId;
+
+    /** 当前该依赖对应的版本 */
+    private String version;
+
+    /**
+     * 该依赖发布新版时,响应方式 ON,STABLE_ONLY,OFF
+     * todo 【功能】允许使用者修改,保存时根据用户获取
+     */
+    private String newVersionNotifyStrategy = NewVersionNotifyStrategyEnum.STABLE_ONLY.getValue();
+
+}

+ 42 - 0
src/main/java/org/lym/pom/entity/DependencyIndex.java

@@ -0,0 +1,42 @@
+package org.lym.pom.entity;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.Embeddable;
+import java.io.Serializable;
+import java.util.Objects;
+
+/**
+ * 依赖的主键
+ * @author lym
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@Embeddable
+public class DependencyIndex implements Serializable {
+
+    private String groupId;
+
+    private String artifactId;
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        DependencyIndex that = (DependencyIndex) o;
+        return Objects.equals(groupId, that.groupId) &&
+                Objects.equals(artifactId, that.artifactId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(groupId, artifactId);
+    }
+}

+ 33 - 0
src/main/java/org/lym/pom/entity/ListJpaConverter.java

@@ -0,0 +1,33 @@
+package org.lym.pom.entity;
+
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import javax.persistence.AttributeConverter;
+import java.util.*;
+
+/**
+ * @author lym
+ */
+public class ListJpaConverter implements AttributeConverter<List<String>, String> {
+	
+	@Override
+	public String convertToDatabaseColumn(List<String> strings) {
+		if(CollectionUtils.isEmpty(strings)){
+			return "";
+		}
+		StringJoiner sj = new StringJoiner(",");
+		strings.forEach(sj::add);
+		return sj.toString();
+	}
+
+	@Override
+	public List<String> convertToEntityAttribute(String s) {
+		if(StringUtils.isEmpty(s)){
+			return new LinkedList<>();
+		}
+		String[] strings = s.split(",");
+		return new ArrayList<>(Arrays.asList(strings));
+	}
+}
+

+ 81 - 0
src/main/java/org/lym/pom/entity/NotifyRecordEntity.java

@@ -0,0 +1,81 @@
+package org.lym.pom.entity;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import javax.persistence.*;
+import java.util.Date;
+import java.util.Objects;
+
+/**
+ * 通知记录
+ * @author lym
+ */
+@Data
+@Entity
+@Table(name="tb_notify_record")
+@NoArgsConstructor
+public class NotifyRecordEntity {
+
+    @Id
+    @GeneratedValue(strategy= GenerationType.IDENTITY)
+    private Long id;
+
+    private Long projectId;
+
+    /** 依赖 id*/
+    private String groupId;
+
+    /** 依赖 id */
+    private String artifactId;
+
+    /** 当前该依赖对应的版本(project.dependency.version) */
+    private String currentVersion;
+
+    /** 新的版本号,用于判断是否为同一条记录 */
+    private String newVersion;
+
+    /** 通知状态,待通知,已经通知,取消 */
+    private Boolean notified;
+
+    /** 发送通知时间 */
+    private Date notifyTime;
+
+    public NotifyRecordEntity(Long projectId, String groupId, String artifactId, String currentVersion, String newVersion){
+        this.projectId = projectId;
+        this.groupId = groupId;
+        this.artifactId = artifactId;
+        this.currentVersion = currentVersion;
+        this.newVersion = newVersion;
+        this.notified = false;
+    }
+
+    /**
+     * 获取 第三方依赖的 id
+     */
+    public DependencyIndex getDependencyIndex(){
+        return new DependencyIndex(groupId, artifactId);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || getClass() != o.getClass()) {
+            return false;
+        }
+        NotifyRecordEntity that = (NotifyRecordEntity) o;
+        return id.equals(that.id) &&
+                projectId.equals(that.projectId) &&
+                groupId.equals(that.groupId) &&
+                artifactId.equals(that.artifactId) &&
+                currentVersion.equals(that.currentVersion) &&
+                newVersion.equals(that.newVersion);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(id, projectId, groupId, artifactId, currentVersion, newVersion);
+    }
+}

+ 50 - 0
src/main/java/org/lym/pom/entity/ProjectEntity.java

@@ -0,0 +1,50 @@
+package org.lym.pom.entity;
+
+
+import lombok.Data;
+import org.lym.pom.constant.StatusEnum;
+
+
+import javax.persistence.*;
+import java.util.Date;
+
+
+/**
+ * 待扫描的 pom.xml
+ *
+ * @author lym
+ */
+@Data
+@Entity
+@Table(name="tb_project")
+public class ProjectEntity {
+
+    @Id
+    @GeneratedValue(strategy= GenerationType.IDENTITY)
+    private Long id;
+
+
+    private String groupId;
+
+
+    private String artifactId;
+
+
+    private String version;
+
+
+    private String name;
+
+
+    private String description;
+
+
+    private String userId;
+
+    private String status = StatusEnum.NORMAL.getValue();
+
+    private Date createTime;
+
+    private Date updateTime;
+
+}

+ 32 - 0
src/main/java/org/lym/pom/entity/SetJpaConverter.java

@@ -0,0 +1,32 @@
+package org.lym.pom.entity;
+
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import javax.persistence.AttributeConverter;
+import java.util.*;
+
+/**
+ * @author lym
+ */
+public class SetJpaConverter implements AttributeConverter<Set<String>, String> {
+	
+	@Override
+	public String convertToDatabaseColumn(Set<String> strings) {
+		if(CollectionUtils.isEmpty(strings)){
+			return "";
+		}
+		StringJoiner sj = new StringJoiner(",");
+		strings.forEach(sj::add);
+		return sj.toString();
+	}
+
+	@Override
+	public Set<String> convertToEntityAttribute(String s) {
+		if(StringUtils.isEmpty(s)){
+			return new HashSet<>();
+		}
+		String[] strings = s.split(",");
+		return new HashSet<>(Arrays.asList(strings));
+	}
+}

+ 95 - 0
src/main/java/org/lym/pom/entity/ThirdProjectEntity.java

@@ -0,0 +1,95 @@
+package org.lym.pom.entity;
+
+
+import lombok.Data;
+import org.lym.pom.constant.ThirdProjectVersionStatusEnum;
+
+import javax.persistence.*;
+import java.util.Date;
+
+
+/**
+ * 第三方 jar
+ * 被 project 依赖,每日爬取版本更新
+ *
+ * @author lym
+ */
+@Data
+@Entity
+@Table(name="tb_third_project")
+public class ThirdProjectEntity {
+
+    @EmbeddedId
+    private DependencyIndex id;
+
+    /** 已知最新版本 */
+    private String version;
+
+    /** 已知最新稳定版本 */
+    private String stableVersion;
+
+    /** 名称(可选) */
+    private String name;
+
+    /** 描述(可选) */
+    private String description;
+
+    /** 项目主页(可选) */
+    private String homeUrl;
+
+    /** 更新日志地址(可选) */
+    private String changeLogUrl;
+
+    /** 开源协议(可选) */
+    private String openSourceProtocol;
+
+
+    //********************* 统一获取版本号 **********************
+
+    /** 项目版本获取地址 */
+    //private String versionUrl;
+
+    /**
+     * regex, xpath
+     */
+    //private String analysisType;
+
+    /** 匹配表达式 */
+    //private String pattern;
+
+    //***********************************
+
+    /**
+     * 如何判断为稳定版,正则
+     */
+    private String stableVersionPattern = ".*";
+
+    /** 版本规则 */
+    private String versionRule = "x.y.z";
+
+    /**
+     * 状态
+     * @see ThirdProjectVersionStatusEnum
+     */
+    private String status;
+    // = ThirdProjectVersionStatusEnum.NORMAL.getStatus();
+
+    /** 最后一次更新时间 */
+    private Date updateTime;
+
+    // 判断相等时,若 id 相同则认为相同
+
+    @Override
+    public boolean equals(Object object){
+        if(object instanceof ThirdProjectEntity){
+            return getId().equals(((ThirdProjectEntity) object).getId());
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode(){
+        return this.getId().hashCode();
+    }
+
+}

+ 30 - 0
src/main/java/org/lym/pom/entity/UserEntity.java

@@ -0,0 +1,30 @@
+package org.lym.pom.entity;
+
+import lombok.Data;
+import org.lym.pom.constant.NewVersionNotifyStrategyEnum;
+
+import javax.persistence.*;
+import java.time.LocalDateTime;
+
+/**
+ * @author lym
+ */
+@Data
+@Entity
+@Table(name="tb_user")
+public class UserEntity {
+
+    @Id
+    private String id;
+
+    private String name;
+
+    private String email;
+
+    private String phone;
+
+    private LocalDateTime createTime;
+
+    private String defaultNewVersionNotifyStrategy = NewVersionNotifyStrategyEnum.STABLE_ONLY.getValue();
+
+}

+ 27 - 0
src/main/java/org/lym/pom/notify/event/CheckProjectAllDependenciesEvent.java

@@ -0,0 +1,27 @@
+package org.lym.pom.notify.event;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import org.lym.pom.entity.ThirdProjectEntity;
+
+import java.util.List;
+
+/**
+ * 检查一个 project 所有依赖是否有新版本【本地检查,不向中央仓库同步】,如果有,则创建待通知记录
+ * 该事件可以异步处理
+ *
+ * @author lym
+ */
+@Data
+@AllArgsConstructor
+public class CheckProjectAllDependenciesEvent {
+
+    private Long projectId;
+
+    private List<ThirdProjectEntity> thirdProjectEntities;
+
+    private boolean sendNotifyInstantly;
+
+    private String notifyReason;
+
+}

+ 27 - 0
src/main/java/org/lym/pom/notify/event/DependencyInsertEvent.java

@@ -0,0 +1,27 @@
+package org.lym.pom.notify.event;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import org.lym.pom.entity.DependencyIndex;
+
+import java.util.Set;
+
+/**
+ * 依赖插入事件
+ * 如新增 project,解析完它的依赖,保存到数据库
+ * 查询更新第三方依赖中是否对这些依赖做了追踪,若未追踪则添加追踪,并立即尝试获取版本号
+ * @author lym
+ */
+@Data
+@AllArgsConstructor
+public class DependencyInsertEvent {
+
+    private Long projectId;
+
+    private Set<DependencyIndex> dependencyIndices;
+
+    private boolean sendNotifyInstantlyAfterVersionCheck;
+
+    private String notifyReason;
+
+}

+ 19 - 0
src/main/java/org/lym/pom/notify/event/ProjectReLoadEvent.java

@@ -0,0 +1,19 @@
+package org.lym.pom.notify.event;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * 用户的项目重新加载事件,一般发生于用户上传已经上传过的 pom.xml
+ * 删除通知记录中 projectId 且待通知的记录
+ * 该事件不建议异步,若该事件处理过慢,会导致新生成的通知也会被删掉
+ *
+ * @author lym
+ */
+@Data
+@AllArgsConstructor
+public class ProjectReLoadEvent {
+
+    private Long projectId;
+
+}

+ 22 - 0
src/main/java/org/lym/pom/notify/event/SendNotifyEvent.java

@@ -0,0 +1,22 @@
+package org.lym.pom.notify.event;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import org.lym.pom.entity.NotifyRecordEntity;
+
+import java.util.List;
+
+/**
+ * 检查一个 project 所有依赖是否有新版本【本地检查,不向中央仓库同步】,如果有,则创建待通知记录
+ *
+ * @author lym
+ */
+@Data
+@AllArgsConstructor
+public class SendNotifyEvent {
+
+    private List<NotifyRecordEntity> toNotifiedRecordList;
+
+    private String notifyReason;
+
+}

+ 27 - 0
src/main/java/org/lym/pom/notify/publisher/EventPublisher.java

@@ -0,0 +1,27 @@
+package org.lym.pom.notify.publisher;
+
+import org.springframework.beans.BeansException;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Service;
+
+/**
+ * 事件发布者
+ * @author lym
+ */
+@Service
+public class EventPublisher implements ApplicationContextAware {
+
+
+    private ApplicationContext context;
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        context = applicationContext;
+    }
+
+    public void publish(Object event){
+        context.publishEvent(event);
+    }
+
+}

+ 38 - 0
src/main/java/org/lym/pom/repository/IDependencyRepository.java

@@ -0,0 +1,38 @@
+package org.lym.pom.repository;
+
+import org.lym.pom.entity.DependencyEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+/**
+* Description: DAO. 
+*   Deal directly with the database, 
+*   if you customize the query, take the index first
+* 
+* 		Please follow the prefix convention below
+*
+*   getOne ------------ getXXX
+*   getMultiple ------- listXXX
+*   count ------------- countXXX
+*   getOne ------------ getXXX
+*   insert ------------ saveXXX
+*   delete ------------ deleteXXX
+*   modify ------------ updateXXX
+*
+ * @author lym
+ */
+public interface IDependencyRepository extends JpaRepository<DependencyEntity, Long> {
+
+    /**
+     * 根据 groupId artifactId
+     * @return DependencyEntity
+     */
+    List<DependencyEntity> findByGroupIdAndArtifactId(String groupId, String artifactId);
+
+    @Transactional
+    void deleteByProjectId(Long projectId);
+
+    List<DependencyEntity> findByProjectId(Long projectId);
+}

+ 33 - 0
src/main/java/org/lym/pom/repository/INotifyRecordRepository.java

@@ -0,0 +1,33 @@
+package org.lym.pom.repository;
+
+import org.lym.pom.entity.NotifyRecordEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.List;
+
+/**
+* Description: DAO. 
+*   Deal directly with the database, 
+*   if you customize the query, take the index first
+* 
+* 		Please follow the prefix convention below
+*
+*   getOne ------------ getXXX
+*   getMultiple ------- listXXX
+*   count ------------- countXXX
+*   getOne ------------ getXXX
+*   insert ------------ saveXXX
+*   delete ------------ deleteXXX
+*   modify ------------ updateXXX
+*
+ * @author lym
+ */
+public interface INotifyRecordRepository extends JpaRepository<NotifyRecordEntity, Long> {
+
+    List<NotifyRecordEntity> findAllByNotified(Boolean notified);
+
+    @Transactional
+    void deleteByIdAndNotified(Long projectId, boolean notified);
+
+}

+ 28 - 0
src/main/java/org/lym/pom/repository/IProjectRepository.java

@@ -0,0 +1,28 @@
+package org.lym.pom.repository;
+
+import org.lym.pom.entity.ProjectEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+import java.util.List;
+
+/**
+* Description: DAO. 
+*   Deal directly with the database, 
+*   if you customize the query, take the index first
+* 
+* 		Please follow the prefix convention below
+*
+*   getOne ------------ getXXX
+*   getMultiple ------- listXXX
+*   count ------------- countXXX
+*   getOne ------------ getXXX
+*   insert ------------ saveXXX
+*   delete ------------ deleteXXX
+*   modify ------------ updateXXX
+*
+ * @author lym
+ */
+public interface IProjectRepository extends JpaRepository<ProjectEntity, Long> {
+
+    List<ProjectEntity> findByUserId(String userId);
+}

+ 29 - 0
src/main/java/org/lym/pom/repository/IThirdProjectRepository.java

@@ -0,0 +1,29 @@
+package org.lym.pom.repository;
+
+import org.lym.pom.entity.DependencyIndex;
+import org.lym.pom.entity.ThirdProjectEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+import org.springframework.data.jpa.repository.Query;
+
+import java.util.List;
+
+/**
+* Description: DAO. 
+*   Deal directly with the database, 
+*   if you customize the query, take the index first
+* 
+* 		Please follow the prefix convention below
+*
+*   getOne ------------ getXXX
+*   getMultiple ------- listXXX
+*   count ------------- countXXX
+*   getOne ------------ getXXX
+*   insert ------------ saveXXX
+*   delete ------------ deleteXXX
+*   modify ------------ updateXXX
+*
+ * @author lym
+ */
+public interface IThirdProjectRepository extends JpaRepository<ThirdProjectEntity, DependencyIndex> {
+
+}

+ 25 - 0
src/main/java/org/lym/pom/repository/IUserRepository.java

@@ -0,0 +1,25 @@
+package org.lym.pom.repository;
+
+import org.lym.pom.entity.UserEntity;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+/**
+* Description: DAO. 
+*   Deal directly with the database, 
+*   if you customize the query, take the index first
+* 
+* 		Please follow the prefix convention below
+*
+*   getOne ------------ getXXX
+*   getMultiple ------- listXXX
+*   count ------------- countXXX
+*   getOne ------------ getXXX
+*   insert ------------ saveXXX
+*   delete ------------ deleteXXX
+*   modify ------------ updateXXX
+*
+ * @author lym
+ */
+public interface IUserRepository extends JpaRepository<UserEntity, String> {
+
+}

+ 261 - 0
src/main/java/org/lym/pom/scheduled/SendNotifyTask.java

@@ -0,0 +1,261 @@
+package org.lym.pom.scheduled;
+
+import lombok.extern.slf4j.Slf4j;
+import org.lym.pom.constant.NewVersionNotifyStrategyEnum;
+import org.lym.pom.dto.business.NotifyEmailBO;
+import org.lym.pom.dto.business.NotifyProjectBO;
+import org.lym.pom.dto.business.NotifyRecordBO;
+import org.lym.pom.entity.*;
+import org.lym.pom.notify.event.SendNotifyEvent;
+import org.lym.pom.service.*;
+import org.shoulder.core.exception.CommonErrorCodeEnum;
+import org.shoulder.core.util.AssertUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.event.EventListener;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import org.springframework.util.StringUtils;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 发送提醒任务
+ * 每天早上 9 点执行
+ *
+ * @author lym
+ */
+@Slf4j
+@Service
+public class SendNotifyTask {
+
+    @Autowired
+    private INotifyRecordService notifyRecordService;
+
+    @Autowired
+    private IProjectService projectService;
+
+    @Autowired
+    private IUserService userService;
+
+    @Autowired
+    private IThirdProjectService thirdProjectService;
+
+    @Autowired
+    private INotifySendService notifySender;
+
+    /**
+     * 找出所有待发送提醒的记录
+     * 按照每个项目一次通知发送
+     * 09:00
+     */
+    @Scheduled(cron = "0 0 9 * * ?")
+    public void sendNotify() {
+        log.info("ready to send notify...");
+
+        // 获取所有待通知记录
+        List<NotifyRecordEntity> toNotifiedRecordList = notifyRecordService.findAllByNotified(false);
+        sendNotify(toNotifiedRecordList, "Scheduled");
+    }
+
+    /**
+     * 发送的通知
+     *
+     * @param event 工程更新事件
+     */
+    @Async
+    @EventListener(SendNotifyEvent.class)
+    public void onSendNotifyEvent(SendNotifyEvent sendNotifyEvent) {
+        AssertUtils.notBlank(sendNotifyEvent.getNotifyReason(), CommonErrorCodeEnum.ILLEGAL_PARAM);
+        sendNotify(sendNotifyEvent.getToNotifiedRecordList(), sendNotifyEvent.getNotifyReason());
+    }
+
+    /**
+     * 需要注意 notifyReason 是拼接的,注意避免注入脚本
+     */
+    public void sendNotify(List<NotifyRecordEntity> toNotifiedRecordList, String notifyReason) {
+        if (CollectionUtils.isEmpty(toNotifiedRecordList)) {
+            log.info("not need send notify. toNotifiedRecordList is empty.");
+            return;
+        } else {
+            log.info("toNotifiedRecordList.size=" + toNotifiedRecordList.size());
+        }
+        Set<Long> projectIds = new HashSet<>();
+        Set<DependencyIndex> thirdProjectIds = new HashSet<>();
+        toNotifiedRecordList.forEach(record -> {
+            projectIds.add(record.getProjectId());
+            thirdProjectIds.add(record.getDependencyIndex());
+        });
+
+        // 查询需要的 projectInfo、thirdProjectInfo、userInfo
+        List<String> userIds = new LinkedList<>();
+        List<ProjectEntity> projects = projectService.findByIds(projectIds);
+        Map<Long, ProjectEntity> projectMap = new HashMap<>(projects.size());
+        projects.forEach(p -> {
+            projectMap.put(p.getId(), p);
+            userIds.add(p.getUserId());
+        });
+
+        Map<DependencyIndex, ThirdProjectEntity> thirdProjectMap = thirdProjectService.findMapByIds(thirdProjectIds);
+        Map<String, UserEntity> userMap = new HashMap<>(userIds.size());
+        List<UserEntity> users = userService.findByIds(userIds);
+        users.forEach(u -> userMap.put(u.getId(), u));
+
+        Map<Long, NotifyProjectBO> projectIdToBoMap = new HashMap<>(projectIds.size());
+
+        List<Long> notifiedRecordIds = new LinkedList<>();
+        toNotifiedRecordList.forEach(
+                record -> {
+                    notifiedRecordIds.add(record.getId());
+                    ProjectEntity project = projectMap.get(record.getProjectId());
+                    UserEntity user = userMap.get(project.getUserId());
+                    NotifyProjectBO notifyProjectBO = projectIdToBoMap.computeIfAbsent(project.getId(), id -> new NotifyProjectBO(project, user));
+                    notifyProjectBO.addNotifyRecordBO(record, thirdProjectMap.get(record.getDependencyIndex()));
+                    notifyProjectBO.setNotifyReason(notifyReason);
+                }
+        );
+
+        // 转化为邮件 BO
+        List<NotifyEmailBO> notifyEmailBOList = projectIdToBoMap.values().stream()
+                .map(this::generateNotifyEmailBO).collect(Collectors.toList());
+
+        // 发送
+        notifySender.sendEmailNotify(notifyEmailBOList);
+
+        // 更新发送状态为已经发送
+        notifyRecordService.setNotified(notifiedRecordIds);
+
+        log.info("finished sending notify TASK!");
+    }
+
+
+    private NotifyEmailBO generateNotifyEmailBO(NotifyProjectBO notifyProjectBO) {
+        NotifyEmailBO emailBO = new NotifyEmailBO();
+        emailBO.setEmail(notifyProjectBO.getUser().getEmail());
+        emailBO.setSubject("Dependency Update Notification.");
+        emailBO.setContent(getEmailContent(notifyProjectBO));
+        return emailBO;
+    }
+
+    private static boolean from_style = true;
+
+    /**
+     * 邮件模板:
+     * hi, {userName}!
+     * Your project {projectName}({groupId}, {artifactId}) may need update.
+     * The dependency({dependency.name}) has published a <a href="{dependency.changeLogUrl}">new version ({newVersion})
+     * xx dependency has published a <a href="xxx">new version (xxx)</a>.
+     * xx dependency has published a <a href="xxx">new version (xxx)</a>.
+     * —
+     * You are receiving this because you are subscribed to this project.
+     * View it on <a href="">PomUpdate</a> or <a href="xxx">unsubscribe</a>.
+     */
+    private String getEmailContent(NotifyProjectBO notifyProjectBO) {
+        String USER_NAME = notifyProjectBO.getUser().getName();
+        String PROJECT_NAME = notifyProjectBO.getName();
+        String NOTIFY_REASON = notifyProjectBO.getNotifyReason();
+        String projectDetail = "(" + notifyProjectBO.getGroupId() + ":" + notifyProjectBO.getArtifactId() + ")";
+        if (!StringUtils.hasText(PROJECT_NAME)) {
+            PROJECT_NAME = projectDetail;
+        } else {
+            PROJECT_NAME += projectDetail;
+        }
+
+        // -------------------------------------------------------------
+        String splitLine = "</br><hr></br>";
+
+        String headTemplate = "Deer {USER_NAME}</br>" +
+                " Your project <b>{PROJECT_NAME}</b> may need update.";
+        String header = headTemplate
+                .replace("{PROJECT_NAME}", PROJECT_NAME)
+                .replace("{USER_NAME}", USER_NAME);
+
+        StringBuilder result = new StringBuilder(header);
+        // -------------------------------------------------------------
+//        result.append(splitLine);
+        String eachDependencyTemplate = "* The dependency({DEPENDENCY_ID}) has published a new stable version " +
+                "({NEW_VERSION})  Your version is {YOUR_VERSION}.</br>";
+        if (from_style) {
+            String tableHeader = "<style type=\"text/css\">" +
+                    "            table.tftable {font-size:12px;color:#333333;width:100%;border-width: 1px;border-color: #729ea5;border-collapse: collapse;}" +
+                    "    table.tftable th {font-size:12px;background-color:#acc8cc;border-width: 1px;padding: 8px;border-style: solid;border-color: #729ea5;text-align:left;}" +
+                    "    table.tftable tr {background-color:#ffffff;}" +
+                    "    table.tftable td {font-size:12px;border-width: 1px;padding: 8px;border-style: solid;border-color: #729ea5;}" +
+                    "</style>" +
+                    "<table id=\"tfhover\" class=\"tftable\" border=\"1\">" +
+                    "<tr><th>Dependency</th><th>Your<br>Version</th><th>New<br>Version</th>";
+            result.append(tableHeader);
+            eachDependencyTemplate = "<tr><td>{DEPENDENCY_ID}</td><td>{YOUR_VERSION}</td><td>{NEW_VERSION}</td>";
+        }
+
+        for (NotifyRecordBO notifyRecordBO : notifyProjectBO.getNotifyRecordBOList()) {
+            result.append(getDependencyContent(notifyRecordBO, eachDependencyTemplate));
+        }
+        if (from_style) {
+            String tableTail = "</table>";
+            result.append(tableTail);
+        }
+        // -------------------------------------------------------
+        result.append(splitLine);
+
+        String unsubscribeUrl = "http://autoPom.itlym.cn/dependencies/updateNotifyStrategy?projectId={PROJECT_ID}&email&={USER_EMAIL}&notifyStrategy=" + NewVersionNotifyStrategyEnum.IGNORE.getValue()
+                .replace("{PROJECT_ID}", String.valueOf(notifyProjectBO.getProjectId()))
+                .replace("{USER_EMAIL}", notifyProjectBO.getUser().getEmail());
+        String LINK_POM_UPDATE_PROJECT = convertHtmlLink("View on PomUpdate", "http://autoPom.itlym.cn/projects?email=" + notifyProjectBO.getUser().getEmail());
+        String LINK_POM_UPDATE_UNSUBSCRIBE = convertHtmlLink("Unsubscribe", unsubscribeUrl, "gray", false);
+
+        String tailTemplate = " Notify Reason: {NOTIFY_REASON}.<br>" +
+                "{LINK_POM_UPDATE_PROJECT}<br>" +
+                "<br> {LINK_POM_UPDATE_UNSUBSCRIBE}";
+        String tail = tailTemplate
+                .replace("{LINK_POM_UPDATE_PROJECT}", LINK_POM_UPDATE_PROJECT)
+                .replace("{LINK_POM_UPDATE_UNSUBSCRIBE}", LINK_POM_UPDATE_UNSUBSCRIBE)
+                .replace("{NOTIFY_REASON}", NOTIFY_REASON);
+
+        result.append(tail);
+
+        return result.toString();
+    }
+
+    private String getDependencyContent(NotifyRecordBO notifyRecordBO, String template) {
+        ThirdProjectEntity thirdProject = notifyRecordBO.getThirdProject();
+
+        String thirdProjectUrl = thirdProject.getHomeUrl();
+        String dependencyName = thirdProject.getName();
+        String dependencyDetail =
+                thirdProject.getId().getGroupId() + ":<br>" + thirdProject.getId().getArtifactId();
+        if (!StringUtils.hasText(dependencyName)) {
+            dependencyName = dependencyDetail;
+        } else {
+            dependencyName += dependencyDetail;
+        }
+        String newStableVersion = thirdProject.getStableVersion();
+        String changeLogUrl = thirdProject.getChangeLogUrl();
+
+        String DEPENDENCY_ID = convertHtmlLink(dependencyName, thirdProjectUrl);
+        String NEW_VERSION = convertHtmlLink(newStableVersion, changeLogUrl);
+        String YOUR_VERSION = notifyRecordBO.getCurrentVersion();
+
+        return template.replace("{DEPENDENCY_ID}", DEPENDENCY_ID)
+                .replace("{NEW_VERSION}", NEW_VERSION)
+                .replace("{YOUR_VERSION}", YOUR_VERSION);
+    }
+
+    private static String convertHtmlLink(String text, String url) {
+        return convertHtmlLink(text, url, "blue", true);
+    }
+    private static String convertHtmlLink(String text, String url, String color, boolean blod) {
+        if (StringUtils.hasText(url)) {
+            String style = " style=\"color:" + color + ";";
+            if(blod) {
+                style += "font-weight:bold;";
+            }
+            style += "\" ";
+            return "<a " + style + " href=\"" + url + "\">" + text + "</a>";
+        }
+        return text;
+    }
+
+}

+ 82 - 0
src/main/java/org/lym/pom/scheduled/VersionWatcherTask.java

@@ -0,0 +1,82 @@
+package org.lym.pom.scheduled;
+
+import lombok.extern.slf4j.Slf4j;
+import org.lym.pom.dto.business.ThirdDependencyUpdateBO;
+import org.lym.pom.entity.DependencyEntity;
+import org.lym.pom.entity.NotifyRecordEntity;
+import org.lym.pom.service.IDependencyService;
+import org.lym.pom.service.INotifyRecordService;
+import org.lym.pom.service.IThirdProjectService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+import java.util.stream.Collectors;
+
+/**
+ * 版本号监视器任务
+ * 每 4 小时执行一次
+ *
+ * @author lym
+ */
+@Slf4j
+@Service
+public class VersionWatcherTask {
+
+    @Autowired
+    private IThirdProjectService thirdProjectService;
+
+    @Autowired
+    private IDependencyService dependencyService;
+
+    @Autowired
+    private INotifyRecordService notifyRecordService;
+
+    /**
+     * 检查所有第三方依赖是否有新版本
+     */
+    @Scheduled(cron = "0 0 0/4 * * ?")
+    public void checkDependenciesHasUpdate() {
+
+        log.info("ready to check Dependencies has update...");
+
+        // 获取有新版本的第三方依赖
+        List<ThirdDependencyUpdateBO> updateInfoList = thirdProjectService.checkAndUpdateAll();
+
+        if (CollectionUtils.isEmpty(updateInfoList)) {
+            log.info("not thirdDependency has updated.");
+        } else {
+            log.info("updatedThirdDependencyInfoList.size=" + updateInfoList.size());
+        }
+
+        // 待通知记录 todo 【性能】分成另一个任务,查找最近通知时间大于3天的
+        List<NotifyRecordEntity> toNotifyRecords = genNotifyRecordEntities(updateInfoList);
+        // 保存待通知记录
+        notifyRecordService.save(toNotifyRecords, false, null);
+
+        log.info("Finished checking dependenciesHasUpdate TASK!");
+    }
+
+    /**
+     * 根据变更信息待通知记录
+     */
+    private List<NotifyRecordEntity> genNotifyRecordEntities(List<ThirdDependencyUpdateBO> updateInfoList) {
+        List<NotifyRecordEntity> toNotifyRecords = new LinkedList<>();
+
+        for (ThirdDependencyUpdateBO updateBO : updateInfoList) {
+            List<DependencyEntity> dependencyEntities = dependencyService.findByIndex(updateBO.getDependencyIndex().getGroupId(), updateBO.getDependencyIndex().getArtifactId());
+
+            if (CollectionUtils.isEmpty(dependencyEntities)) {
+                continue;
+            }
+            // 获取需要发送提醒的工程的id
+            toNotifyRecords.addAll(dependencyEntities.stream().map(d -> notifyRecordService.tryCreateNotifyRecordEntity(d, updateBO)).filter(Objects::nonNull).collect(Collectors.toList()));
+        }
+        return toNotifyRecords;
+    }
+
+}

+ 31 - 0
src/main/java/org/lym/pom/service/IDependencyService.java

@@ -0,0 +1,31 @@
+package org.lym.pom.service;
+
+import org.lym.pom.constant.NewVersionNotifyStrategyEnum;
+import org.lym.pom.dto.xml.DependencyBaseDTO;
+import org.lym.pom.entity.DependencyEntity;
+
+import java.util.List;
+
+/**
+ * 订阅推送服务
+ * @author lym
+ */
+public interface IDependencyService {
+    /**
+     * 获取所有某第三方依赖记录
+     * @return DependencyEntities
+     */
+    List<DependencyEntity> findByIndex(String groupId, String artifactId);
+
+    List<DependencyEntity> findAllByProjectId(Long projectId);
+
+    void saveDependencies(List<? extends DependencyBaseDTO> dependencyDTOList, Long projectId);
+
+    void update(DependencyEntity dependency);
+
+    void update(List<DependencyEntity> dependencies);
+
+    void deleteByProjectId(Long projectId);
+
+    void updateAllNotifyStrategyByProjectId(Long projectId, NewVersionNotifyStrategyEnum newVersionNotifyStrategy);
+}

+ 50 - 0
src/main/java/org/lym/pom/service/INotifyRecordService.java

@@ -0,0 +1,50 @@
+package org.lym.pom.service;
+
+import org.lym.pom.dto.business.ThirdDependencyUpdateBO;
+import org.lym.pom.entity.DependencyEntity;
+import org.lym.pom.entity.NotifyRecordEntity;
+import org.lym.pom.notify.event.CheckProjectAllDependenciesEvent;
+import org.lym.pom.notify.event.ProjectReLoadEvent;
+import org.springframework.lang.Nullable;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 发送提醒任务
+ * 每天早上 9 点执行
+ *
+ * @author lym
+ */
+public interface INotifyRecordService {
+
+
+    /**
+     * 保存待通知记录
+     *
+     * @param entities            要保存的
+     * @param sendNotifyInstantly
+     * @param notifyReason
+     */
+    void save(Collection<NotifyRecordEntity> entities, boolean sendNotifyInstantly, String notifyReason);
+
+    /**
+     * 查找所有记录
+     * @param notified 已经通知过
+     * @return List<NotifyRecordEntity>
+     */
+    List<NotifyRecordEntity> findAllByNotified(boolean notified);
+
+    /**
+     * 设置发送通知状态为已经发送,记录通知发送时间
+     * @param notifiedRecordIds 需要更新的id
+     */
+    void setNotified(Collection<Long> notifiedRecordIds);
+
+    void onCheckProjectAllDependenciesEvent(CheckProjectAllDependenciesEvent event);
+
+    void onProjectReLoadEvent(ProjectReLoadEvent event);
+
+    @Nullable
+    NotifyRecordEntity tryCreateNotifyRecordEntity(DependencyEntity dependency, ThirdDependencyUpdateBO updateBO);
+}

+ 18 - 0
src/main/java/org/lym/pom/service/INotifySendService.java

@@ -0,0 +1,18 @@
+package org.lym.pom.service;
+
+import org.lym.pom.dto.business.NotifyEmailBO;
+
+import java.util.Collection;
+
+/**
+ * @author lym
+ */
+public interface INotifySendService {
+
+    /**
+     * 逐一发送邮件
+     * @param notifyEmailBOList 待发送邮件
+     */
+    void sendEmailNotify(Collection<NotifyEmailBO> notifyEmailBOList);
+
+}

+ 19 - 0
src/main/java/org/lym/pom/service/IPomAnalyzerService.java

@@ -0,0 +1,19 @@
+package org.lym.pom.service;
+
+import org.lym.pom.dto.xml.ProjectDTO;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * pom.xml 分析、转换
+ * @author lym
+ */
+public interface IPomAnalyzerService {
+
+    /**
+     * 将 pom.xml 转化为 dto
+     * @param file pom.xml
+     * @return 分析完毕的 dto
+     */
+    ProjectDTO analysisPom(MultipartFile file);
+
+}

+ 33 - 0
src/main/java/org/lym/pom/service/IProjectService.java

@@ -0,0 +1,33 @@
+package org.lym.pom.service;
+
+import org.lym.pom.dto.xml.ProjectDTO;
+import org.lym.pom.entity.ProjectEntity;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author lym
+ */
+public interface IProjectService {
+
+    /**
+     * 单纯保存 project 和 dependencies 到数据库
+     */
+    default void save(ProjectDTO projectDTO){
+        save(projectDTO, "1");
+    }
+
+    void save(ProjectDTO projectDTO, String userId);
+
+    ProjectEntity findById(Long projectId);
+
+    List<ProjectEntity> findByIds(Iterable<Long> projectIds);
+
+    Map<Long, ProjectEntity> findMapByIds(Iterable<Long> projectIds);
+
+    List<ProjectEntity> findByUserId(String userId);
+}

+ 15 - 0
src/main/java/org/lym/pom/service/IThirdProjectInfoRefreshService.java

@@ -0,0 +1,15 @@
+package org.lym.pom.service;
+
+import org.lym.pom.entity.ThirdProjectEntity;
+
+/**
+ * @author lym
+ */
+public interface IThirdProjectInfoRefreshService {
+
+    /**
+     * 根据远程仓库同步最新信息
+     */
+    void refreshInfo(ThirdProjectEntity thirdProject) throws Exception;
+
+}

+ 37 - 0
src/main/java/org/lym/pom/service/IThirdProjectService.java

@@ -0,0 +1,37 @@
+package org.lym.pom.service;
+
+import org.lym.pom.dto.business.ThirdDependencyUpdateBO;
+import org.lym.pom.entity.DependencyEntity;
+import org.lym.pom.entity.DependencyIndex;
+import org.lym.pom.entity.ThirdProjectEntity;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author lym
+ */
+public interface IThirdProjectService {
+
+    void save(List<ThirdProjectEntity> entities);
+
+    ThirdProjectEntity save(ThirdProjectEntity entity);
+
+    ThirdProjectEntity findById(DependencyIndex dependencyIndex);
+
+    List<ThirdProjectEntity> findByIds(Iterable<DependencyIndex> dependencyIndex);
+
+    Map<DependencyIndex, ThirdProjectEntity> findMapByIds(Iterable<DependencyIndex> dependencyIndex);
+
+    void compareAndSave(List<DependencyEntity> dependencies);
+
+
+    /**
+     * 获取有新版本的第三方依赖
+     *
+     * @return 有更新的依赖
+     */
+    List<ThirdDependencyUpdateBO> checkAndUpdateAll();
+
+
+}

+ 17 - 0
src/main/java/org/lym/pom/service/IUserService.java

@@ -0,0 +1,17 @@
+package org.lym.pom.service;
+
+import org.lym.pom.entity.UserEntity;
+
+import java.util.List;
+
+/**
+ * @author lym
+ */
+public interface IUserService {
+
+    void save(UserEntity userEntity);
+
+    UserEntity findById(String userId);
+
+    List<UserEntity> findByIds(Iterable<String> ids);
+}

+ 128 - 0
src/main/java/org/lym/pom/service/impl/DependencyServiceImpl.java

@@ -0,0 +1,128 @@
+package org.lym.pom.service.impl;
+
+import org.lym.pom.constant.ContextKey;
+import org.lym.pom.constant.NewVersionNotifyStrategyEnum;
+import org.lym.pom.dto.xml.DependencyBaseDTO;
+import org.lym.pom.entity.DependencyEntity;
+import org.lym.pom.entity.DependencyIndex;
+import org.lym.pom.notify.event.DependencyInsertEvent;
+import org.lym.pom.notify.publisher.EventPublisher;
+import org.lym.pom.repository.IDependencyRepository;
+import org.lym.pom.service.IDependencyService;
+import org.shoulder.core.context.AppContext;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
+import org.springframework.jdbc.core.namedparam.SqlParameterSource;
+import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * 订阅推送服务
+ *
+ * @author lym
+ */
+@Service
+public class DependencyServiceImpl implements IDependencyService {
+
+    @Autowired
+    private IDependencyRepository dependencyRepository;
+
+    @Autowired
+    private EventPublisher eventPublisher;
+
+
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+
+    /**
+     * 从项目依赖表获取所有(groupId, artifactId) 且lastVersion与 newVersion 不相同的 DependencyEntity
+     */
+    @Override
+    public List<DependencyEntity> findByIndex(String groupId, String artifactId) {
+        return dependencyRepository.findByGroupIdAndArtifactId(groupId, artifactId);
+    }
+
+    private List<DependencyEntity> createDependencies(List<? extends DependencyBaseDTO> dependencyDTOList, Long projectId) {
+        List<DependencyEntity> dependencies = new ArrayList<>(dependencyDTOList.size());
+        for (DependencyBaseDTO dependencyDTO : dependencyDTOList) {
+            DependencyEntity dependencyEntity = new DependencyEntity();
+            dependencyEntity.setGroupId(dependencyDTO.getGroupId());
+            dependencyEntity.setArtifactId(dependencyDTO.getArtifactId());
+            dependencyEntity.setProjectId(projectId);
+            dependencyEntity.setVersion(dependencyDTO.getVersion());
+            dependencies.add(dependencyEntity);
+        }
+        return dependencies;
+    }
+
+
+    @Override
+    public void saveDependencies(List<? extends DependencyBaseDTO> dependencyDTOList, Long projectId) {
+        List<DependencyEntity> dependencyEntities = createDependencies(dependencyDTOList, projectId);
+
+        // 删除已有的
+        deleteByProjectId(projectId);
+        // 保存
+        save(dependencyEntities);
+
+        // 发布插入事件
+        Set<DependencyIndex> dependencyIndices = dependencyEntities.stream().map(
+                dependencyEntity -> new DependencyIndex(dependencyEntity.getGroupId(), dependencyEntity.getArtifactId())
+        ).collect(Collectors.toSet());
+        DependencyInsertEvent event = new DependencyInsertEvent(projectId, dependencyIndices,
+                AppContext.getOrDefault(ContextKey.NOTIFY_INSTANTLY_AFTER_CHECK, false),
+                AppContext.getOrDefault(ContextKey.NOTIFY_REASON, null)
+        );
+        eventPublisher.publish(event);
+
+    }
+
+    @Override
+    public void deleteByProjectId(Long projectId) {
+        String sql = "delete from tb_dependency where project_id = ?";
+        jdbcTemplate.update(sql, projectId);
+    }
+
+    @Override
+    public void updateAllNotifyStrategyByProjectId(Long projectId, NewVersionNotifyStrategyEnum newVersionNotifyStrategy) {
+        String sql = "update tb_dependency set new_version_notify_strategy = ? where project_id = ?";
+        jdbcTemplate.update(sql, newVersionNotifyStrategy.getValue(), projectId);
+    }
+
+    @Override
+    public List<DependencyEntity> findAllByProjectId(Long projectId) {
+        return dependencyRepository.findByProjectId(projectId);
+    }
+
+    @Override
+    public void update(DependencyEntity dependency) {
+        dependencyRepository.save(dependency);
+    }
+
+    @Override
+    public void update(List<DependencyEntity> dependencies) {
+        dependencyRepository.saveAll(dependencies);
+    }
+
+
+    private void save(List<DependencyEntity> dependencyEntities) {
+
+        NamedParameterJdbcTemplate namedParameterJdbcTemplate =
+                new NamedParameterJdbcTemplate(jdbcTemplate.getDataSource());
+        //批量转数组
+        SqlParameterSource[] beanSources = SqlParameterSourceUtils.createBatch(dependencyEntities.toArray());
+        String sql = "INSERT INTO tb_dependency(project_id, group_id, artifact_id, version, new_version_notify_strategy)" +
+                " VALUES (:projectId, :groupId, :artifactId, :version, :newVersionNotifyStrategy)";
+
+        namedParameterJdbcTemplate.batchUpdate(sql, beanSources);
+
+        //dependencyRepository.saveAll(dependencyEntities);
+    }
+
+}

+ 174 - 0
src/main/java/org/lym/pom/service/impl/NotifyRecordServiceImpl.java

@@ -0,0 +1,174 @@
+package org.lym.pom.service.impl;
+
+import cn.hutool.core.util.StrUtil;
+import org.lym.pom.constant.NewVersionNotifyStrategyEnum;
+import org.lym.pom.dto.business.ThirdDependencyUpdateBO;
+import org.lym.pom.entity.DependencyEntity;
+import org.lym.pom.entity.DependencyIndex;
+import org.lym.pom.entity.NotifyRecordEntity;
+import org.lym.pom.notify.event.CheckProjectAllDependenciesEvent;
+import org.lym.pom.notify.event.ProjectReLoadEvent;
+import org.lym.pom.notify.event.SendNotifyEvent;
+import org.lym.pom.notify.publisher.EventPublisher;
+import org.lym.pom.repository.INotifyRecordRepository;
+import org.lym.pom.service.IDependencyService;
+import org.lym.pom.service.INotifyRecordService;
+import org.lym.pom.service.impl.select.VersionSelectorManager;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.event.EventListener;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
+import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
+import org.springframework.lang.Nullable;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * @author lym
+ */
+@Service
+public class NotifyRecordServiceImpl implements INotifyRecordService {
+
+    @Autowired
+    private INotifyRecordRepository notifyRecordRepository;
+
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+
+    @Autowired
+    private IDependencyService dependencyService;
+
+    @Autowired
+    private EventPublisher eventPublisher;
+
+    @Override
+    @Transactional
+    public void save(Collection<NotifyRecordEntity> entities, boolean sendNotifyInstantly, String notifyReason) {
+        /// 先查出待发送通知的,如果新 version 相同,则不保存
+        // 优化 db lock
+        Set<NotifyRecordEntity> dbRecords = new HashSet<>(findAllByNotified(false));
+        List<NotifyRecordEntity> toSaveRecords = entities.stream()
+                .filter(r -> !dbRecords.contains(r)).collect(Collectors.toList());
+        notifyRecordRepository.saveAll(toSaveRecords);
+        // unlock
+        if (sendNotifyInstantly) {
+            eventPublisher.publish(new SendNotifyEvent(toSaveRecords, notifyReason));
+        }
+    }
+
+    /**
+     * todo 【性能】 可以考虑走索引
+     */
+    @Override
+    public List<NotifyRecordEntity> findAllByNotified(boolean notified) {
+        return notifyRecordRepository.findAllByNotified(notified);
+    }
+
+    @Override
+    public void setNotified(Collection<Long> ids) {
+        if (CollectionUtils.isEmpty(ids)) {
+            return;
+        }
+
+        String sql = "UPDATE tb_notify_record set notified=true, notify_time=(:updateTime) where id in (:ids)";
+        NamedParameterJdbcTemplate template =
+                new NamedParameterJdbcTemplate(Objects.requireNonNull(jdbcTemplate.getDataSource()));
+        MapSqlParameterSource parameters = new MapSqlParameterSource();
+        parameters.addValue("ids", ids);
+        parameters.addValue("updateTime", new Date());
+        template.update(sql, parameters);
+    }
+
+
+    /**
+     * 添加了工程,检查它的依赖
+     *
+     * @param event 工程添加,检查它的所有更新,生成待通知记录
+     */
+    @Async
+    @EventListener(CheckProjectAllDependenciesEvent.class)
+    @Override
+    public void onCheckProjectAllDependenciesEvent(CheckProjectAllDependenciesEvent event) {
+        Long projectId = event.getProjectId();
+        // 避免重复通知,保险起见,先删除;一般还没有新建,相当于什么都没删
+        notifyRecordRepository.deleteByIdAndNotified(projectId, false);
+
+        // 找出所有依赖项
+        List<DependencyEntity> dependencyEntities = dependencyService.findAllByProjectId(projectId);
+        Map<DependencyIndex, ThirdDependencyUpdateBO> map = event.getThirdProjectEntities().stream()
+                .map(d -> new ThirdDependencyUpdateBO(d.getId(), d.getVersion(), d.getStableVersion()))
+                .collect(Collectors.toMap(ThirdDependencyUpdateBO::getDependencyIndex, d -> d, (d1, d2) -> d2));
+
+        // 筛选出需要通知的
+        List<NotifyRecordEntity> toNotifyRecords = dependencyEntities.stream()
+                .map(d ->
+                        tryCreateNotifyRecordEntity(d, map.get(new DependencyIndex(d.getGroupId(), d.getArtifactId())))
+                )
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+
+        // 保存通知记录
+        save(toNotifyRecords, event.isSendNotifyInstantly(), event.getNotifyReason());
+    }
+
+    /**
+     * 删除未发送的通知
+     *
+     * @param event 工程更新事件
+     */
+    @Async
+    @EventListener(ProjectReLoadEvent.class)
+    @Override
+    public void onProjectReLoadEvent(ProjectReLoadEvent event) {
+        Long projectId = event.getProjectId();
+        notifyRecordRepository.deleteByIdAndNotified(projectId, false);
+        // 这里未重新检测该工程,因此若该工程的依赖有更新版必须等待下次检测后才能收到通知
+    }
+
+
+    @Override
+    @Nullable
+    public NotifyRecordEntity tryCreateNotifyRecordEntity(DependencyEntity dependency, ThirdDependencyUpdateBO updateBO) {
+        // todo 【功能增强】从 user 表中查询推送策略
+        boolean ignore = NewVersionNotifyStrategyEnum.IGNORE.getValue().equals(dependency.getNewVersionNotifyStrategy());
+        if (ignore) {
+            return null;
+        }
+        boolean alwaysNotify = NewVersionNotifyStrategyEnum.ALWAYS.getValue().equals(dependency.getNewVersionNotifyStrategy());
+        boolean notifyWhenStableAndStableUpdate = NewVersionNotifyStrategyEnum.STABLE_ONLY.getValue().equals(dependency.getNewVersionNotifyStrategy())
+                && !StrUtil.equals(dependency.getVersion(), updateBO.getLatestStableVersion());
+        if (alwaysNotify || notifyWhenStableAndStableUpdate) {
+            if (VersionSelectorManager.getVersionSelector("")
+                    .getComparator()
+                    .compare(updateBO.getLatestVersion(), dependency.getVersion()) <= 0) {
+                // 特殊的 dependency 的 version 太高了,比检测到最新的还高,认为没更新
+                return null;
+            }
+
+            Long projectId = dependency.getProjectId();
+            return new NotifyRecordEntity(
+                    projectId,
+                    dependency.getGroupId(),
+                    dependency.getArtifactId(),
+                    dependency.getVersion(),
+                    // 目标版本 = 最新版
+                    alwaysNotify ? updateBO.getLatestVersion() :
+                            // 目标版本 = 最新稳定版
+                            updateBO.getLatestStableVersion()
+            );
+        }
+        return null;
+    }
+
+}

+ 80 - 0
src/main/java/org/lym/pom/service/impl/NotifySendServiceImpl.java

@@ -0,0 +1,80 @@
+package org.lym.pom.service.impl;
+
+import lombok.extern.slf4j.Slf4j;
+import org.lym.pom.config.MailProperties;
+import org.lym.pom.dto.business.NotifyEmailBO;
+import org.lym.pom.service.INotifySendService;
+import org.shoulder.core.exception.BaseRuntimeException;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.mail.javamail.JavaMailSenderImpl;
+import org.springframework.mail.javamail.MimeMessageHelper;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.stereotype.Service;
+
+import javax.mail.MessagingException;
+import javax.mail.internet.MimeMessage;
+import java.util.Collection;
+import java.util.concurrent.LinkedBlockingDeque;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author lym
+ */
+@Slf4j
+@Service
+public class NotifySendServiceImpl implements INotifySendService {
+
+    private final ThreadPoolExecutor executor = new ThreadPoolExecutor(5, 5, 30, TimeUnit.SECONDS, new LinkedBlockingDeque<>(300));
+
+    @Autowired
+    private JavaMailSenderImpl sender;
+
+    @Autowired
+    private MailProperties mailProperties;
+
+    @Async
+    @Override
+    public void sendEmailNotify(Collection<NotifyEmailBO> notifyEmailBOList){
+        log.info("emailToSend.size=" + notifyEmailBOList.size());
+        notifyEmailBOList.forEach(this::sendEmail);
+        log.info("emailToSend finished.");
+    }
+
+
+    private void sendEmail(NotifyEmailBO notifyEmailBO){
+        executor.execute(() -> {
+            MimeMessage message = sender.createMimeMessage();
+            try {
+                MimeMessageHelper helper = new MimeMessageHelper(message, true);
+                //发送人
+                helper.setFrom(mailProperties.getSenderName());
+                //接收人
+                helper.setTo(notifyEmailBO.getEmail());
+                //抄送人
+                //helper.setBcc();
+                //邮件标题
+                helper.setSubject(notifyEmailBO.getSubject());
+                //true代表支持html,邮件内容
+                String tail = "</br></br> Power by <a href=\"autoPom.itlym.cn\">autoPom.itlym.cn</a>.";
+                helper.setText(notifyEmailBO.getContent() + tail, true);
+                sender.send(message);
+            } catch (MessagingException e) {
+                throw new BaseRuntimeException(e);
+            }
+        });
+
+    }
+
+    private void sendFakerEmail(NotifyEmailBO notifyEmailBO){
+        executor.execute(() -> {
+            System.out.println("SEND EMAIL TO " + notifyEmailBO.getEmail() + "...........");
+            System.out.println("SUBJECT");
+            System.out.println(notifyEmailBO.getSubject());
+            System.out.println("CONTENT:");
+            System.out.println(notifyEmailBO.getContent());
+        });
+
+    }
+
+}

+ 24 - 0
src/main/java/org/lym/pom/service/impl/PomAnalyzerServiceImpl.java

@@ -0,0 +1,24 @@
+package org.lym.pom.service.impl;
+
+import org.lym.pom.dto.xml.ProjectDTO;
+import org.lym.pom.service.IPomAnalyzerService;
+import org.lym.pom.util.XmlUtil;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * @author lym
+ */
+@Service
+public class PomAnalyzerServiceImpl implements IPomAnalyzerService {
+
+    @Override
+    public ProjectDTO analysisPom(MultipartFile file){
+        try {
+            return XmlUtil.xmlToObject(file.getInputStream());
+        } catch (Exception e) {
+            throw new RuntimeException("invalid pom.xml file!", e);
+        }
+    }
+
+}

+ 209 - 0
src/main/java/org/lym/pom/service/impl/ProjectServiceImpl.java

@@ -0,0 +1,209 @@
+package org.lym.pom.service.impl;
+
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.util.StrUtil;
+import org.lym.pom.dto.xml.*;
+import org.lym.pom.entity.ProjectEntity;
+import org.lym.pom.notify.event.ProjectReLoadEvent;
+import org.lym.pom.notify.publisher.EventPublisher;
+import org.lym.pom.repository.IProjectRepository;
+import org.lym.pom.service.IProjectService;
+import org.shoulder.core.util.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.domain.Example;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * project Business
+ * @author lym
+ */
+@Service
+public class ProjectServiceImpl implements IProjectService {
+
+    @Autowired
+    private IProjectRepository projectRepository;
+
+    @Autowired
+    private DependencyServiceImpl dependencyService;
+
+    @Autowired
+    private EventPublisher eventPublisher;
+
+    @Override
+    @Transactional
+    public void save(ProjectDTO projectDTO, String userId) {
+        ProjectEntity projectEntity = createProject(projectDTO, userId);
+        projectEntity = save(projectEntity);
+        List<? extends DependencyBaseDTO> dependencyDTOList = getAllDependenciesWithVersion(projectDTO);
+        dependencyService.saveDependencies(dependencyDTOList, projectEntity.getId());
+    }
+
+    /**
+     * 获取所有需要管理版本的依赖,包含 dependencyManager.dependencies 和 dependencies 的依赖
+     * @param projectDTO pom.xml DTO
+     * @return 需要管理版本的依赖
+     */
+    public List<? extends DependencyBaseDTO> getAllDependenciesWithVersion(ProjectDTO projectDTO) {
+        // 【1】收集需要管理的依赖
+
+        List<DependencyDTO> directoryDependencies = projectDTO.getDependencies();
+        // todo 【优化校验】确保每个 dependency 是惟一的
+        // 1. build.dependencies
+        List<DependencyBaseDTO> dependencies = new ArrayList<>(directoryDependencies);
+        // 2. parent
+        if(projectDTO.getParent() != null) {
+            dependencies.add(projectDTO.getParent());
+        }
+        // 3. build.dependencyManagement.dependencies
+        Optional.ofNullable(projectDTO.getDependencyManagement())
+                .map(DependencyManagementDTO::getDependencies)
+                .filter(CollectionUtil::isNotEmpty)
+                .ifPresent(dependencies::addAll);
+        // todo 【优化校验】 plugin 的默认 groupId = org.apache.maven.plugins
+        // 4. build.plugins
+        Optional.ofNullable(projectDTO.getBuild())
+                .map(BuildDTO::getPlugins)
+                .filter(CollectionUtil::isNotEmpty)
+                .ifPresent(dependencies::addAll);
+        // 5. build.pluginManagement.plugins
+        Optional.ofNullable(projectDTO.getBuild())
+                .map(BuildDTO::getPluginManagement)
+                .map(PluginManagementDTO::getPlugins)
+                .filter(CollectionUtil::isNotEmpty)
+                .ifPresent(dependencies::addAll);
+
+        // 【2】 填充版本
+        final Map<String, String> properties = trimProperties(projectDTO.getProperties());
+        fillVersionFromProperties(dependencies, properties);
+
+        // 【3】去掉没有版本的依赖项,这些由 parent / dependencyManager.pom 已经接管了,只需要关心parent/dependencyManager.pom版本即可
+        List<DependencyBaseDTO> dependenciesWithVersion =
+                dependencies.stream()
+                        .filter(dependency -> dependency.getVersion() != null)
+                        .collect(Collectors.toList());
+
+        return dependenciesWithVersion;
+    }
+
+    /**
+     * properties 去掉多余的空格
+     */
+    private Map<String, String> trimProperties(Map<String, String> properties) {
+        Map<String, String> trimmedProperties = new HashMap<>(properties.size());
+        for (Map.Entry<String, String> entry : properties.entrySet()) {
+            trimmedProperties.put(entry.getKey().trim(), entry.getValue().trim());
+        }
+        return trimmedProperties;
+    }
+
+    /**
+     * 将 ${xxx} 格式的 version 从 properties 中填充
+     */
+    private void fillVersionFromProperties(List<? extends DependencyBaseDTO> dependencies, Map<String, String> versionMap) {
+        for (DependencyBaseDTO dependencyDTO : dependencies) {
+            String version = dependencyDTO.getVersion();
+            if (version == null) {
+                // 这种情况发生在 pom 形式引入了其他工程或者 parent 不为空,总之已经被其他依赖完成版本管理,无需关心
+                continue;
+            }
+            version = version.trim();
+            if (version.startsWith("${")) {
+                // 去掉 ${}
+                String versionKey = version.substring(2, version.length() - 1).trim();
+                String newVersion = versionMap.get(versionKey);
+                if (newVersion == null) {
+                    // 版本号缺失,认为是不合格的 pom 文件(dependency version中引用了 ${xx.version} 却未在 properties 中定义)
+                    throw new IllegalStateException(String.format("Missing version. [groupId=%s, artifactId=%s, " +
+                                                                  "version=%s]",
+                            dependencyDTO.getGroupId(), dependencyDTO.getArtifactId(), version));
+                }
+                dependencyDTO.setVersion(newVersion);
+            }
+            //获取时不处理 [2.40.0,) 这种,在判断时认为是最新的
+        }
+    }
+
+    // -------------------------------------------------------------------------
+
+    @Override
+    public ProjectEntity findById(Long projectId) {
+        return projectRepository.findById(projectId).get();
+    }
+
+    @Override
+    public List<ProjectEntity> findByIds(Iterable<Long> projectIds) {
+        return projectRepository.findAllById(projectIds);
+    }
+
+    @Override
+    public Map<Long, ProjectEntity> findMapByIds(Iterable<Long> projectIds) {
+        List<ProjectEntity> projectEntities = projectRepository.findAllById(projectIds);
+        Map<Long, ProjectEntity> projectMap = new HashMap<>();
+        for (ProjectEntity projectEntity : projectEntities) {
+            projectMap.put(projectEntity.getId(), projectEntity);
+        }
+        return projectMap;
+    }
+
+    @Override
+    public List<ProjectEntity> findByUserId(String userId) {
+        return projectRepository.findByUserId(userId);
+    }
+
+    private ProjectEntity save(ProjectEntity projectEntity) {
+        // 是否已经存在
+        ProjectEntity example = new ProjectEntity();
+        example.setGroupId(projectEntity.getGroupId());
+        example.setArtifactId(projectEntity.getArtifactId());
+        // 暂时不考虑多版本控制
+        //example.setVersion(projectEntity.getVersion());
+        example.setUserId(projectEntity.getUserId());
+        ProjectEntity projectInDb = projectRepository.findOne(Example.of(example))
+                .orElse(null);
+        ProjectEntity result;
+        // 在旧数据的基础上改动并保存
+        if (projectInDb != null) {
+            /*
+            // 考虑演示版不允许更新
+            throw new IllegalStateException(
+                    String.format("the project[groupId=%s, artifactId=%s] already exists in your account.",
+                    projectInDb.getGroupId(), projectInDb.getArtifactId()));
+                    */
+
+            projectInDb.setVersion(projectEntity.getVersion());
+            projectInDb.setName(projectEntity.getName());
+            if (StrUtil.isNotBlank(projectEntity.getDescription())) {
+                projectInDb.setDescription(projectEntity.getDescription());
+            }
+            // 发出 项目变更事件;删除待通知记录中 projectId = this,且待通知的记录
+            result = projectRepository.save(projectInDb);
+            projectInDb.setUpdateTime(new Date());
+            eventPublisher.publish(new ProjectReLoadEvent(projectInDb.getId()));
+        } else {
+            result = projectRepository.save(projectEntity);
+        }
+        return result;
+    }
+
+    private ProjectEntity createProject(ProjectDTO projectDTO, String userId) {
+        ProjectEntity project = new ProjectEntity();
+        project.setGroupId(projectDTO.getGroupId());
+        if(StringUtils.isEmpty(projectDTO.getGroupId())) {
+            Optional.ofNullable(projectDTO.getParent())
+                    .map(DependencyBaseDTO::getGroupId)
+                    .ifPresentOrElse(project::setGroupId, () -> {throw new RuntimeException("invalid groupId");});
+        }
+        project.setArtifactId(projectDTO.getArtifactId());
+        project.setName(StrUtil.isEmpty(projectDTO.getName()) ? projectDTO.getArtifactId() : projectDTO.getName());
+        project.setDescription(projectDTO.getDescription());
+        project.setVersion(projectDTO.getVersion());
+        project.setUserId(userId);
+        project.setCreateTime(new Date());
+        return project;
+    }
+
+}

+ 210 - 0
src/main/java/org/lym/pom/service/impl/ThirdProjectInfoRefreshServiceImpl.java

@@ -0,0 +1,210 @@
+package org.lym.pom.service.impl;
+
+import cn.hutool.core.util.ReUtil;
+import org.lym.pom.annotation.ThirdProjectInfoSpider;
+import org.lym.pom.config.DependencyExtInfoProperties;
+import org.lym.pom.constant.ThirdProjectInfoSource;
+import org.lym.pom.constant.ThirdProjectInfoSourceEnum;
+import org.lym.pom.constant.ThirdProjectVersionStatusEnum;
+import org.lym.pom.entity.ThirdProjectEntity;
+import org.lym.pom.service.IThirdProjectInfoRefreshService;
+import org.lym.pom.service.impl.select.VersionSelector;
+import org.lym.pom.service.impl.select.VersionSelectorManager;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.client.HttpServerErrorException;
+import org.springframework.web.client.RestClientException;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.regex.Pattern;
+
+/**
+ * @author lym
+ */
+@Service
+public class ThirdProjectInfoRefreshServiceImpl implements IThirdProjectInfoRefreshService {
+
+    @ThirdProjectInfoSpider
+    @Autowired
+    private RestTemplate rest;
+
+    private ThirdProjectInfoSource thirdProjectInfoSource = ThirdProjectInfoSourceEnum.MVN_JAR;
+
+    private static Map<String, Pattern> patternMap = new HashMap<>();
+
+    private final String perHour = "0 0 * * * ?";
+
+    @Scheduled(cron = perHour)
+    public void resetThirdProjectInfoSource() {
+        thirdProjectInfoSource = ThirdProjectInfoSourceEnum.MVN_JAR;
+    }
+
+    @Override
+    public void refreshInfo(ThirdProjectEntity thirdProject) throws HttpServerErrorException, RestClientException {
+
+        // 获取页面
+        String html = "";
+        try {
+            html = getHtmlResult(thirdProject);
+        } catch (RestClientException restEx) {
+            // 如果是 RestClientException 则更换其他源重试
+            try {
+                // 临时换成其他备用源
+                thirdProjectInfoSource = ThirdProjectInfoSourceEnum.ALI_CLOUD;
+                html = getHtmlResult(thirdProject);
+            } catch (Exception ignored) {
+                thirdProjectInfoSource = ThirdProjectInfoSourceEnum.MVN_JAR;
+            }
+        }
+
+        // 刷新版本号信息
+        refreshVersion(html, thirdProject);
+
+        // 更新依赖url
+        fillProjectUrl(thirdProject);
+
+        // 刷新基本信息
+        refreshBaseInfo(html, thirdProject);
+
+    }
+
+    /**
+     * 返回 html 字符串
+     *
+     * @param thirdProject 待更新的第三方工程
+     * @return html 字符串
+     */
+    private String getHtmlResult(ThirdProjectEntity thirdProject) throws RestClientException {
+        String groupId = thirdProject.getId().getGroupId();
+        String artifactId = thirdProject.getId().getArtifactId();
+
+        // 目标网站
+        String aimUrl = thirdProjectInfoSource.getUrl(groupId, artifactId);
+
+        return rest.getForObject(aimUrl, String.class);
+    }
+
+
+    /**
+     * 刷新基本信息
+     */
+    private void refreshBaseInfo(String html, ThirdProjectEntity thirdProject) {
+
+        if (thirdProjectInfoSource != ThirdProjectInfoSourceEnum.MVN_JAR) {
+            // 仅 mvnJar 支持获取详细信息
+            return;
+        }
+
+        boolean firstRefresh = ThirdProjectVersionStatusEnum.BORN.getStatus().equals(thirdProject.getStatus());
+        if (firstRefresh) {
+            // projectName
+            List<String> nameList = ReUtil.findAll(getPattern(thirdProjectInfoSource.getNamePattern()), html, 1);
+            thirdProject.setName(nameList.get(0));
+
+        }
+
+        // Description
+        List<String> descriptionList = ReUtil.findAll(getPattern(thirdProjectInfoSource.getDescriptionPattern()), html,
+                1);
+        thirdProject.setDescription(descriptionList.get(0));
+
+        // 以下这些信息不太容易从 mvnrepository 这类 jar 包管理的地方获取,可能需要从特定的官方文档 / 代码仓库获取------------
+        // homeUrl
+//        List<String> homeUrlList = ReUtil.findAll(getPattern(thirdProjectInfoSource.getHomeUrlPattern()), html, 1);
+//        thirdProject.setHomeUrl(homeUrlList.get(0));
+//
+//        // OpenSourceProtocol
+//        List<String> openSourceProtocolList =
+//                ReUtil.findAll(getPattern(thirdProjectInfoSource.getOpenSourceProtocolPattern()), html, 1);
+//        thirdProject.setOpenSourceProtocol(openSourceProtocolList.get(0));
+//
+//        // note changeLogUrl 未设置
+//        List<String> changeLogUrlList =
+//                ReUtil.findAll(getPattern(thirdProjectInfoSource.getChangeLogUrlPattern()), html, 1);
+//        thirdProject.setChangeLogUrl(changeLogUrlList.get(0));
+    }
+
+
+    /**
+     * 刷新版本号信息
+     */
+    private void refreshVersion(String html, ThirdProjectEntity thirdProject) {
+        Pattern versionPattern = getPattern(thirdProjectInfoSource.getVersionsPattern());
+
+        // 结果列表
+        List<String> versionList;
+
+        versionList = ReUtil.findAll(versionPattern, html, 1);
+
+        if (CollectionUtils.isEmpty(versionList)) {
+            throw new IllegalStateException("can't find versions.[groupId=" +
+                    thirdProject.getId().getGroupId() +
+                    ", artifactId=" +
+                    thirdProject.getId().getArtifactId() + "]");
+        }
+        // 这两个必须都遍历,否则若在检查更新周期内,发布一次稳定版,又发布一次非稳定版,无法感知到最新稳定版
+        // todo 【扩展性】筛选出最新版本;目前只有一个选择器暂时不需要决策
+        VersionSelector versionSelector = VersionSelectorManager.getVersionSelector("");
+        thirdProject.setVersion(versionSelector.selectLatest(versionList));
+        // 获取最新 stable 版本
+        String stableVersion = versionSelector.selectLatestStable(versionList);
+        if(stableVersion != null) {
+            thirdProject.setStableVersion(stableVersion);
+        }
+    }
+
+
+    /**
+     * 带缓存的动态编译正则表达式
+     *
+     * @param regex 正则表达式
+     * @return 匹配符
+     */
+    private static Pattern getPattern(String regex) {
+        Pattern pattern = patternMap.get(regex);
+        if (pattern == null) {
+            // 设置为允许多行匹配
+            pattern = Pattern.compile(regex, Pattern.DOTALL);
+            patternMap.put(regex, pattern);
+        }
+        return pattern;
+    }
+
+    public void fillProjectUrl(ThirdProjectEntity thirdProject) {
+        DependencyExtInfoProperties.DependencyExtInfo extInfo = Optional.ofNullable(thirdProject)
+                .map(ThirdProjectEntity::getId)
+                .map(id -> id.getGroupId() + ":" + id.getArtifactId())
+                .map(DependencyExtInfoProperties::fetchExtInfoFromCache)
+                .orElse(null);
+
+        if (extInfo != null) {
+            String changeLogUrl = extInfo.getChangeLogUrl();
+            if (changeLogUrl.contains("{")) {
+                changeLogUrl = changeLogUrl.replace("{VERSION}", thirdProject.getVersion());
+            }
+            thirdProject.setChangeLogUrl(changeLogUrl);
+            thirdProject.setHomeUrl(extInfo.getOpensourceUrl());
+        }
+
+
+//        // 固定地址:github - releases
+//        String githubReleasePage = "https://github.com/projen/projen/releases";
+//
+//        // 固定地址:github - file
+//        String githubFilePage = "https://github.com/redisson/redisson/blob/master/CHANGELOG.md";
+//
+//        // 拼接version:github - releases tag(区分版本)
+//        String githubReleaseTagPage = "https://github.com/openjdk/jdk/releases/tag/{jdk-22%2B13}";
+//
+//        // 拼接version:doc html
+//        String projectDocPage = "https://docs.spring.io/spring-boot/docs/{3.0.10}/reference/html/";
+
+    }
+
+}

+ 241 - 0
src/main/java/org/lym/pom/service/impl/ThirdProjectServiceImpl.java

@@ -0,0 +1,241 @@
+package org.lym.pom.service.impl;
+
+import cn.hutool.core.util.StrUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.lym.pom.constant.ThirdProjectVersionStatusEnum;
+import org.lym.pom.dto.business.ThirdDependencyUpdateBO;
+import org.lym.pom.entity.DependencyEntity;
+import org.lym.pom.entity.DependencyIndex;
+import org.lym.pom.entity.ThirdProjectEntity;
+import org.lym.pom.notify.event.DependencyInsertEvent;
+import org.lym.pom.notify.publisher.EventPublisher;
+import org.lym.pom.repository.IThirdProjectRepository;
+import org.lym.pom.notify.event.CheckProjectAllDependenciesEvent;
+import org.lym.pom.service.IThirdProjectInfoRefreshService;
+import org.lym.pom.service.IThirdProjectService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.event.EventListener;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.lang.Nullable;
+import org.springframework.stereotype.Service;
+import org.springframework.web.client.HttpServerErrorException;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 第三方依赖查询
+ *
+ * @author lym
+ */
+@Slf4j
+@Service
+public class ThirdProjectServiceImpl implements IThirdProjectService {
+
+    @Autowired
+    private IThirdProjectRepository thirdProjectRepository;
+
+    @Autowired
+    private IThirdProjectInfoRefreshService thirdProjectInfoRefreshService;
+
+    @Autowired
+    private JdbcTemplate jdbcTemplate;
+
+    @Autowired
+    private EventPublisher eventPublisher;
+
+    /**
+     * 依赖项插入后,检查数据库是否已有,以及最新版本信息
+     */
+    @EventListener(DependencyInsertEvent.class)
+    public void onDependencyInsertEvent(DependencyInsertEvent dependencyInsertEvent) {
+        Set<DependencyIndex> dependencyIndices = dependencyInsertEvent.getDependencyIndices();
+
+        /*String sql = "SELECT group_id as groupId, artifact_id as artifactId from tb_third_project where id in (:ids)";
+        NamedParameterJdbcTemplate template =
+                new NamedParameterJdbcTemplate(jdbcTemplate.getDataSource());
+        MapSqlParameterSource parameters = new MapSqlParameterSource();
+        parameters.addValue("ids", ids);
+        parameters.addValue("updateTime", new Date());
+        template.update(sql, parameters);
+
+        List<DependencyIndex> dependencyIndices = thirdProjectRepository.findAllId();*/
+
+        // SQL 优化 DONE,只查 id,目前复杂度为(n + 0.5n² - n,m * n) 查 n 条,数据库共 m 条
+
+        List<ThirdProjectEntity> thirdProjectEntitiesInDB = this.findByIds(dependencyIndices);
+        if (thirdProjectEntitiesInDB.size() < dependencyIndices.size()) {
+            // 数据库中缺少,插入缺少的
+            thirdProjectEntitiesInDB.forEach(
+                    thirdProjectEntity -> dependencyIndices.remove(thirdProjectEntity.getId())
+            );
+
+            List<ThirdProjectEntity> toSave = dependencyIndices.stream().map(id -> {
+                ThirdProjectEntity entity = new ThirdProjectEntity();
+                entity.setId(id);
+                entity.setStatus(ThirdProjectVersionStatusEnum.BORN.getStatus());
+                return entity;
+            }).collect(Collectors.toList());
+            // 这些不存在,所以需要立即检测最新版本并保存 todo【性能】这里可以并行优化
+            toSave.forEach(this::checkUpdateAndSave);
+            thirdProjectEntitiesInDB.addAll(toSave);
+        }
+        eventPublisher.publish(
+                new CheckProjectAllDependenciesEvent(dependencyInsertEvent.getProjectId(),
+                        thirdProjectEntitiesInDB,
+                        dependencyInsertEvent.isSendNotifyInstantlyAfterVersionCheck(),
+                        dependencyInsertEvent.getNotifyReason()
+                )
+        );
+    }
+
+    @Override
+    public void save(List<ThirdProjectEntity> entities) {
+        thirdProjectRepository.saveAll(entities);
+    }
+
+    @Override
+    public ThirdProjectEntity save(ThirdProjectEntity entity) {
+        return thirdProjectRepository.save(entity);
+    }
+
+    @Override
+    public ThirdProjectEntity findById(DependencyIndex dependencyIndex) {
+        return thirdProjectRepository.findById(dependencyIndex).orElse(null);
+    }
+
+    @Override
+    public List<ThirdProjectEntity> findByIds(Iterable<DependencyIndex> dependencyIndex) {
+        return thirdProjectRepository.findAllById(dependencyIndex);
+    }
+
+    @Override
+    public Map<DependencyIndex, ThirdProjectEntity> findMapByIds(Iterable<DependencyIndex> dependencyIndex) {
+        List<ThirdProjectEntity> thirdProjectEntities = findByIds(dependencyIndex);
+
+        Map<DependencyIndex, ThirdProjectEntity> map = new HashMap<>(thirdProjectEntities.size());
+        thirdProjectEntities.forEach(
+                thirdProjectEntity -> {
+                    map.put(thirdProjectEntity.getId(), thirdProjectEntity);
+                }
+        );
+        return map;
+    }
+
+    /**
+     * 【低优先】主要解决插入完了可以立马创建待通知记录,不必等定时任务拉
+     *
+     * @param dependencies
+     */
+    @Override
+    public void compareAndSave(List<DependencyEntity> dependencies) {
+        // 组装 id
+        List<DependencyIndex> indexes = getIndexes(dependencies);
+
+        // 1. 先查旧的
+
+        Map<DependencyIndex, ThirdProjectEntity> indexedThirdProjectMap = this.findMapByIds(indexes);
+
+        // 2. 对比 id 把数据库里没有的直接保存, 对比已有的依赖的版本号,将版本号过期的筛选出来返回
+
+        List<ThirdProjectEntity> toSaveThirdDependencies = new ArrayList<>();
+        List<DependencyEntity> hasLatestVersion = new LinkedList<>();
+
+        for (DependencyIndex index : indexes) {
+            ThirdProjectEntity dbThirdProjectEntity = indexedThirdProjectMap.get(index);
+            if (dbThirdProjectEntity == null) {
+                // todo 【低优先】创建新第三方依赖
+                ThirdProjectEntity thirdProjectEntity = new ThirdProjectEntity();
+                thirdProjectEntity.setId(index);
+                thirdProjectEntity.setStatus(ThirdProjectVersionStatusEnum.BORN.getStatus());
+                toSaveThirdDependencies.add(thirdProjectEntity);
+
+            } else {
+                // todo 【低优先】已存在,对比版本,直接创建通知记录,等待第二天
+                if (ThirdProjectVersionStatusEnum.NORMAL.getStatus().equals(dbThirdProjectEntity.getStatus())) {
+                    // 且有更新,add hasLatestVersion,添加待更新通知
+                    String stableVersion = dbThirdProjectEntity.getStableVersion();
+                    String latestVersion = dbThirdProjectEntity.getVersion();
+                    // #genNotifyRecordEntities 创建通知记录
+                }
+
+            }
+        }
+        // 只将第三方依赖存入数据库,依赖定时更新
+        save(toSaveThirdDependencies);
+
+
+    }
+
+    /*private List<ThirdDependencyUpdateBO> genThirdDependencyUpdateBO(DependencyEntity dependencyEntity){
+        // todo 【低优先】从 db 查第三方依赖完整信息
+        ThirdProjectEntity thirdProjectEntity = new ThirdProjectEntity();
+        DependencyIndex id = new DependencyIndex(dependencyEntity.getGroupId(), dependencyEntity.getArtifactId());
+        thirdProjectEntity.setId(id);
+        // 然后生成
+        return new ThirdDependencyUpdateBO(thirdProjectEntity, dependencyEntity.getVersion());
+
+    }*/
+
+    private List<DependencyIndex> getIndexes(List<DependencyEntity> dependencies) {
+        List<DependencyIndex> indexes = new ArrayList<>(dependencies.size());
+        for (DependencyEntity dependencyEntity : dependencies) {
+            DependencyIndex index = new DependencyIndex(dependencyEntity.getGroupId(),
+                    dependencyEntity.getArtifactId());
+            indexes.add(index);
+        }
+        return indexes;
+    }
+
+
+    @Override
+    public List<ThirdDependencyUpdateBO> checkAndUpdateAll() {
+        // 当前只解析了 tb_third 中的,极小概率可能刚添加, project 中有,但third中没有,等待下次触发就好了
+        // todo 【性能|因定时任务触发、低优先改造】分批查 查找时只列出最近3天没有更新的、并行去检查
+        List<ThirdProjectEntity> allThirdProjects = findAll();
+        return allThirdProjects.stream()
+                .map(this::checkUpdateAndSave)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+    }
+
+    /**
+     * 获取所有
+     */
+    private List<ThirdProjectEntity> findAll() {
+        return thirdProjectRepository.findAll();
+    }
+
+    /**
+     * 获取更新状态 ThirdDependencyUpdateBO【注意该方法为同步调用,若要异步需要调用方使用线程】
+     *
+     * @param thirdProjectEntity thirdProjectEntity
+     * @return 第三方依赖,发送了版本更新 ThirdDependencyUpdateBO 否则返回 null
+     */
+    @Nullable
+    private ThirdDependencyUpdateBO checkUpdateAndSave(ThirdProjectEntity thirdProjectEntity) {
+        String currentVersion = thirdProjectEntity.getVersion();
+        String currentStableVersion = thirdProjectEntity.getStableVersion();
+        Date updateTime = new Date();
+        try {
+            thirdProjectInfoRefreshService.refreshInfo(thirdProjectEntity);
+            thirdProjectEntity.setStatus(ThirdProjectVersionStatusEnum.NORMAL.getStatus());
+        } catch (HttpServerErrorException serverEx) {
+            log.error("第三方依赖信息源不可访问", serverEx);
+        } catch (Exception e) {
+            log.error("刷新第三方依赖信息失败!", e);
+            thirdProjectEntity.setStatus(ThirdProjectVersionStatusEnum.EXCEPTION.getStatus());
+        }
+        thirdProjectEntity.setUpdateTime(updateTime);
+        save(thirdProjectEntity);
+        // 是否进行了版本更新
+        String latestVersion = thirdProjectEntity.getVersion();
+        // 认为中央仓库的版本是最新的,忽略中央仓库版本比当前更低,只要不相等,就是出新版本了
+        if (StrUtil.equals(currentVersion, latestVersion)) {
+            // noNewVersion
+            return null;
+        }
+        return new ThirdDependencyUpdateBO(thirdProjectEntity.getId(), latestVersion, thirdProjectEntity.getStableVersion());
+    }
+
+}

+ 36 - 0
src/main/java/org/lym/pom/service/impl/UserServiceImpl.java

@@ -0,0 +1,36 @@
+package org.lym.pom.service.impl;
+
+import org.lym.pom.entity.UserEntity;
+import org.lym.pom.repository.IUserRepository;
+import org.lym.pom.service.IUserService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import java.util.List;
+
+/**
+ * @author lym
+ */
+@Service
+public class UserServiceImpl implements IUserService {
+
+
+    @Autowired
+    private IUserRepository userRepository;
+
+    @Override
+    public void save(UserEntity userEntity){
+        userRepository.save(userEntity);
+    }
+
+    @Override
+    public UserEntity findById(String userId){
+        return userRepository.findById(userId).orElse(null);
+    }
+
+    @Override
+    public List<UserEntity> findByIds(Iterable<String> ids){
+        return userRepository.findAllById(ids);
+    }
+
+}

+ 35 - 0
src/main/java/org/lym/pom/service/impl/select/BaseVersionSelector.java

@@ -0,0 +1,35 @@
+package org.lym.pom.service.impl.select;
+
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * 最基本的排序器
+ * @author Admin
+ */
+public class BaseVersionSelector implements VersionSelector {
+
+    /**
+     * 是否为稳定版
+     */
+    @Override
+    public boolean isStable(String version){
+        return true;
+    }
+
+    @Override
+    public List<String> sort(List<String> versions){
+        versions.sort(getComparator());
+        return versions;
+    }
+
+    /**
+     * 获取版本比较器
+     * 默认支持 x.y.z 这种类型
+     */
+    @Override
+    public Comparator<String> getComparator(){
+        return VersionComparators.PART;
+    }
+
+}

+ 32 - 0
src/main/java/org/lym/pom/service/impl/select/DefaultVersionSelector.java

@@ -0,0 +1,32 @@
+package org.lym.pom.service.impl.select;
+
+import cn.hutool.core.util.StrUtil;
+
+/**
+ * 获取版本比较器
+ * 支持 x.y.z 这种类型
+ * @author lym
+ */
+public class DefaultVersionSelector  extends BaseVersionSelector {
+
+    final String[] unstableMark = {"alpha", "-b", "beta", "-ea", "rc", "snapshot", "2003", "2004"};
+
+    //apache commons 部分有 "2003/4"
+
+    final String[] releaseMark = {"RELEASE", "SR", "STABLE", "RTM", "RTW", "RVL", "EVAL", "FINAL", "GA"};
+
+    /**
+     * 是否为稳定版
+     */
+    @Override
+    public boolean isStable(String version){
+
+        if(StrUtil.containsAnyIgnoreCase(version, releaseMark)){
+            return true;
+        }else if(StrUtil.containsAnyIgnoreCase(version, unstableMark)){
+            return false;
+        }
+        return super.isStable(version);
+    }
+
+}

+ 60 - 0
src/main/java/org/lym/pom/service/impl/select/VersionComparators.java

@@ -0,0 +1,60 @@
+package org.lym.pom.service.impl.select;
+
+import cn.hutool.core.util.NumberUtil;
+import org.springframework.util.StringUtils;
+
+import java.util.Comparator;
+
+/**
+ * @author lym
+ */
+public interface VersionComparators {
+
+    /**
+     * 字母排序
+     * 适合 spring cloud 这类
+     */
+    Comparator<String> STRING = String::compareTo;
+
+
+    /**
+     * GNU 风格的版本号
+     * 适合类 Major.Minor.Patch 的格式
+     * 兼容 1.0 和 1.0.1 这类比较(版本号可能不全)
+     * 兼容 1.0.0 release、1.0.10 release 这种比较(分隔符不唯一)
+     * 兼容 -beta, -rc{x} 这种
+     * todo 【扩展点功能完善】有的 version 不应参与比较,需要先过滤出来
+     */
+    Comparator<String> PART = (version1, version2) -> {
+        if(StringUtils.isEmpty(version1)){
+            return StringUtils.isEmpty(version2) ? 0 : -1;
+        } else if(StringUtils.isEmpty(version2)){
+            return 1;
+        }
+        String split = "\\.| |\\-";
+        String[] version1Parts = version1.split(split);
+        String[] version2Parts = version2.split(split);
+
+        int minPartNum = Integer.min(version1Parts.length, version2Parts.length);
+        int difference = 0;
+
+        for (int i = 0; i < minPartNum; i++) {
+            boolean v1IsNum = NumberUtil.isNumber(version1Parts[i]);
+            boolean v2IsNum = NumberUtil.isNumber(version2Parts[i]);
+            if (v1IsNum && v2IsNum) {
+                difference = Integer.valueOf(version1Parts[i]).compareTo(Integer.valueOf(version2Parts[i]));
+            } else if(!v1IsNum && !v2IsNum){
+                // 都不是数字
+                difference = version1Parts[i].compareToIgnoreCase(version2Parts[i]);
+            } else {
+                // 认为有数字的版本号更新
+                return v1IsNum ? 1 : -1;
+            }
+            if (difference != 0) {
+                return difference;
+            }
+        }
+        return Integer.compare(version1Parts.length, minPartNum);
+    };
+
+}

+ 44 - 0
src/main/java/org/lym/pom/service/impl/select/VersionSelector.java

@@ -0,0 +1,44 @@
+package org.lym.pom.service.impl.select;
+
+import org.springframework.lang.NonNull;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public interface VersionSelector {
+
+    /**
+     * 是否为稳定版
+     *
+     * @see org.lym.pom.entity.ThirdProjectEntity#stableVersionPattern
+     */
+    boolean isStable(String version);
+
+    /**
+     * 排序:最新....最旧t     */
+    List<String> sort(List<String> versions);
+
+    /**
+     * 获取 最新版
+     */
+    default String selectLatest(@NonNull List<String> versions){
+        return versions.stream().max(getComparator()).orElseThrow();
+    }
+
+    /**
+     * 获取 最新稳定版
+     */
+    default String selectLatestStable(@NonNull List<String> versions){
+        return versions.stream().filter(this::isStable).max(getComparator()).orElse(null);
+    }
+
+    /**
+     * 获取所有稳定版
+     */
+    default List<String> selectStable(List<String> versions){
+        return versions.stream().filter(this::isStable).collect(Collectors.toList());
+    }
+
+    Comparator<String> getComparator();
+}

+ 22 - 0
src/main/java/org/lym/pom/service/impl/select/VersionSelectorManager.java

@@ -0,0 +1,22 @@
+package org.lym.pom.service.impl.select;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author lym
+ */
+public class VersionSelectorManager {
+
+    private static final Map<String, VersionSelector> SELECTOR_MAP;
+
+    public static final VersionSelector DEFAULT = new DefaultVersionSelector();
+
+    static {
+        SELECTOR_MAP = new ConcurrentHashMap<>();
+    }
+
+    public static VersionSelector getVersionSelector(String k) {
+        return SELECTOR_MAP.getOrDefault(k, DEFAULT);
+    }
+}

+ 65 - 0
src/main/java/org/lym/pom/test/TestController.java

@@ -0,0 +1,65 @@
+package org.lym.pom.test;
+
+import org.lym.pom.dto.xml.ProjectDTO;
+import org.lym.pom.service.IProjectService;
+import org.lym.pom.scheduled.SendNotifyTask;
+import org.lym.pom.scheduled.VersionWatcherTask;
+import org.lym.pom.util.XmlUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.io.File;
+import java.io.FileInputStream;
+
+/**
+ * @author lym
+ */
+@RestController
+@RequestMapping("test")
+public class TestController {
+
+
+    @Autowired
+    private IProjectService projectService;
+
+    @Autowired
+    private VersionWatcherTask versionWatcherTask;
+
+    @Autowired
+    private SendNotifyTask sendNotifyTask;
+
+    @Value("${localPath:F:/codes/java/projects/pom-update/pom.xml}")
+    private String localPath;
+
+    /**
+     * http://localhost:12345/test/xml
+     */
+    //@RequestMapping("xml")
+    public String mockUploadPomXml() throws Exception {
+        File f = new File(localPath);
+        ProjectDTO projectDTO = XmlUtil.xmlToObject(new FileInputStream(f));
+        projectService.save(projectDTO);
+        return "analyze pom.xml success";
+    }
+
+    /**
+     * http://localhost:12345/test/version
+     */
+    @RequestMapping("version")
+    public String checkVersion() throws Exception {
+        versionWatcherTask.checkDependenciesHasUpdate();
+        return "check version success";
+    }
+
+    /**
+     * http://localhost:12345/test/notify
+     */
+    @RequestMapping("notify")
+    public String sendNotify() throws Exception {
+        sendNotifyTask.sendNotify();
+        return "notify success";
+    }
+
+}

+ 49 - 0
src/main/java/org/lym/pom/util/CleanIdeaFiles.java

@@ -0,0 +1,49 @@
+package org.lym.pom.util;
+
+import java.io.File;
+
+/**
+ * 删除 idea 自带的文件,方便上传 git
+ * @author lym
+ */
+public class CleanIdeaFiles {
+    public static void main(String[] args) {
+        trace(new File("F:\\temp\\shoulder-framework"));
+
+    }
+
+    static void trace(File file){
+        String fileName = file.getName();
+        if(".idea".equals(fileName) || fileName.endsWith(".iml")){
+            System.out.println("delete " + file.getAbsolutePath());
+            remove(file);
+        }
+        if(!file.isDirectory()){
+            return;
+        }
+        File[] files = file.listFiles();
+        if (files == null || files.length == 0){
+            return;
+        }
+        for (File f : files){
+            trace(f);
+        }
+    }
+
+    public static void remove(File f) {
+        if(!f.exists()){
+            return;
+        }
+        System.out.println("deleted file ::  "+ f.getAbsolutePath());
+        if(!f.isDirectory()){
+            f.delete();
+        }
+        File files[] = f.listFiles();
+        for (int i = 0; i < files.length; i++) {
+            remove(files[i]);
+        }
+        //删除目录自身
+        f.delete();
+        System.out.println("deleted DIR ::  "+f.toString());
+    }
+}

+ 134 - 0
src/main/java/org/lym/pom/util/HttpsClientRequestFactory.java

@@ -0,0 +1,134 @@
+package org.lym.pom.util;
+
+import org.springframework.http.client.SimpleClientHttpRequestFactory;
+
+import javax.net.ssl.*;
+import java.io.IOException;
+import java.net.HttpURLConnection;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.security.cert.X509Certificate;
+
+/**
+ * 创建兼容 http、https 的创建工厂
+ *
+ * @author lym
+ */
+public class HttpsClientRequestFactory extends SimpleClientHttpRequestFactory {
+	
+    @Override
+    protected void prepareConnection(HttpURLConnection connection, String httpMethod) {
+        try {
+            if (!(connection instanceof HttpsURLConnection)) {
+                // 对于 普通 http 请求的处理
+                //throw new RuntimeException("An instance of HttpsURLConnection is expected");
+                super.prepareConnection(connection, httpMethod);
+                return;
+            }
+ 
+            HttpsURLConnection httpsConnection = (HttpsURLConnection) connection;
+ 
+            TrustManager[] trustAllCerts = new TrustManager[]{
+                    new X509TrustManager() {
+                        @Override
+                        public X509Certificate[] getAcceptedIssuers() {
+                            return null;
+                        }
+                        @Override
+                        public void checkClientTrusted(X509Certificate[] certs, String authType) {
+                        }
+                        @Override
+                        public void checkServerTrusted(X509Certificate[] certs, String authType) {
+                        }
+ 
+                    }
+            };
+            SSLContext sslContext = SSLContext.getInstance("TLS");
+            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
+            httpsConnection.setSSLSocketFactory(new MyCustomSSLSocketFactory(sslContext.getSocketFactory()));
+ 
+            httpsConnection.setHostnameVerifier(new HostnameVerifier() {
+                @Override
+                public boolean verify(String s, SSLSession sslSession) {
+                    return true;
+                }
+            });
+ 
+            super.prepareConnection(httpsConnection, httpMethod);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+ 
+    /**
+     * We need to invoke sslSocket.setEnabledProtocols(new String[] {"SSLv3"});
+     * see http://www.oracle.com/technetwork/java/javase/documentation/cve-2014-3566-2342133.html (Java 8 section)
+     */
+    // SSLSocketFactory用于创建 SSLSockets
+    private static class MyCustomSSLSocketFactory extends SSLSocketFactory {
+ 
+        private final SSLSocketFactory delegate;
+ 
+        public MyCustomSSLSocketFactory(SSLSocketFactory delegate) {
+            this.delegate = delegate;
+        }
+ 
+        // 返回默认启用的密码套件。除非一个列表启用,对SSL连接的握手会使用这些密码套件。
+        // 这些默认的服务的最低质量要求保密保护和服务器身份验证
+        @Override
+        public String[] getDefaultCipherSuites() {
+            return delegate.getDefaultCipherSuites();
+        }
+ 
+        // 返回的密码套件可用于SSL连接启用的名字
+        @Override
+        public String[] getSupportedCipherSuites() {
+            return delegate.getSupportedCipherSuites();
+        }
+ 
+ 
+        @Override
+        public Socket createSocket(final Socket socket, final String host, final int port,
+                                   final boolean autoClose) throws IOException {
+            final Socket underlyingSocket = delegate.createSocket(socket, host, port, autoClose);
+            return overrideProtocol(underlyingSocket);
+        }
+ 
+ 
+        @Override
+        public Socket createSocket(final String host, final int port) throws IOException {
+            final Socket underlyingSocket = delegate.createSocket(host, port);
+            return overrideProtocol(underlyingSocket);
+        }
+ 
+        @Override
+        public Socket createSocket(final String host, final int port, final InetAddress localAddress,
+        		final int localPort) throws
+                IOException {
+            final Socket underlyingSocket = delegate.createSocket(host, port, localAddress, localPort);
+            return overrideProtocol(underlyingSocket);
+        }
+ 
+        @Override
+        public Socket createSocket(final InetAddress host, final int port) throws IOException {
+            final Socket underlyingSocket = delegate.createSocket(host, port);
+            return overrideProtocol(underlyingSocket);
+        }
+ 
+        @Override
+        public Socket createSocket(final InetAddress host, final int port, final InetAddress localAddress, 
+        		final int localPort) throws
+                IOException {
+            final Socket underlyingSocket = delegate.createSocket(host, port, localAddress, localPort);
+            return overrideProtocol(underlyingSocket);
+        }
+ 
+        private Socket overrideProtocol(final Socket socket) {
+            if (!(socket instanceof SSLSocket)) {
+                throw new RuntimeException("An instance of SSLSocket is expected");
+            }
+            ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1"});
+            return socket;
+        }
+    }
+}

+ 23 - 0
src/main/java/org/lym/pom/util/UserAgentInterceptor.java

@@ -0,0 +1,23 @@
+package org.lym.pom.util;
+
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.HttpRequest;
+import org.springframework.http.client.ClientHttpRequestExecution;
+import org.springframework.http.client.ClientHttpRequestInterceptor;
+import org.springframework.http.client.ClientHttpResponse;
+
+import java.io.IOException;
+
+public class UserAgentInterceptor implements ClientHttpRequestInterceptor {
+    @Override
+    public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
+            throws IOException {
+        HttpHeaders headers = request.getHeaders();
+        headers.add(HttpHeaders.REFERER, "https://mvnrepository.com");
+        headers.add(HttpHeaders.USER_AGENT,
+                "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.117 Safari/537.36");
+        headers.add(HttpHeaders.COOKIE, "cf_clearance=61e575da1405f308e4747fa497f1a1ee92471fa8-1584947991-0-150; __cfduid=d339e8997bb3f1de8d2bd31cf937122aa1584947991; _ga=GA1.2.439155402.1584948010; _gid=GA1.2.1028680018.1584948010; MVN_SESSION=eyJhbGciOiJIUzI1NiJ9.eyJkYXRhIjp7InVpZCI6ImFmOGM3MzgwLTZjZDYtMTFlYS1hNzI1LTQ5Y2RkNzA5MGQ5OCJ9LCJleHAiOjE2MTY0ODUzODgsIm5iZiI6MTU4NDk0OTM4OCwiaWF0IjoxNTg0OTQ5Mzg4fQ.AhPkfs5ccVH93Fdpud34Dagioy6RomqauWMTyblpK30");
+
+        return execution.execute(request, body);
+    }
+}

+ 111 - 0
src/main/java/org/lym/pom/util/XmlUtil.java

@@ -0,0 +1,111 @@
+package org.lym.pom.util;
+
+import com.thoughtworks.xstream.XStream;
+import com.thoughtworks.xstream.converters.reflection.ObjectAccessException;
+import com.thoughtworks.xstream.converters.reflection.PureJavaReflectionProvider;
+import com.thoughtworks.xstream.io.naming.NoNameCoder;
+import com.thoughtworks.xstream.io.xml.DomDriver;
+import org.lym.pom.dto.xml.*;
+
+import java.io.File;
+import java.io.InputStream;
+import java.lang.reflect.Field;
+
+/**
+ * @author lym
+ */
+public class XmlUtil {
+
+    /**
+     * 匹配准确度
+     * 语法复杂度(思考花费时间长短)
+     * 后续处理复杂度
+     * 可维护性
+     * 可读性
+     */
+    private static final XStream DEFAULT_X_STREAM;
+
+    static {
+        DEFAULT_X_STREAM = generateDefaultXStream();
+        //DEFAULT_X_STREAM.registerConverter(new PojoMapConverter());
+        Class<?>[] xmlClass = new Class[]{ProjectDTO.class, DependencyDTO.class, DependencyManagementDTO.class,
+                BuildDTO.class, PluginDTO.class, PluginManagementDTO.class};
+        DEFAULT_X_STREAM.processAnnotations(xmlClass);
+        DEFAULT_X_STREAM.allowTypes(xmlClass);
+    }
+
+    public static XStream generateDefaultXStream() {
+        XStream xStream = new XStream(new FieldDefaultValueProvider(), new DomDriver("UTF-8", new NoNameCoder()));
+        XStream.setupDefaultSecurity(xStream);
+        //自动探测注解
+        xStream.autodetectAnnotations(true);
+        //忽略未知元素
+        xStream.ignoreUnknownElements();
+        return xStream;
+    }
+
+    /**
+     * xml转对象时,默认值 null
+     */
+    public static class FieldDefaultValueProvider extends PureJavaReflectionProvider {
+
+        @Override
+        public void writeField(Object object, String fieldName, Object value, Class definedIn) {
+            //返回存在于xml中的字段
+            Field field = fieldDictionary.field(object.getClass(), fieldName, definedIn);
+            //验证字段可以被访问
+            validateFieldAccess(field);
+            try {
+                if (value instanceof String) {
+                    //字符串首尾去空
+                    String trim = ((String) value).trim();
+                    if (trim.length() == 0) {
+                        //如果是空字符串,则不做赋值,使用默认初始值
+                        return;
+                    }
+                    field.set(object, trim);
+                } else {
+                    field.set(object, value);
+                }
+            } catch (Exception e) {
+                throw new ObjectAccessException("Could not set field " + object.getClass() + "." + field.getName(), e);
+            }
+        }
+    }
+
+    /**
+     * 将xml文件解析为实体对象
+     *
+     * @param xml xml文件
+     * @return
+     */
+    public static <T extends Object> T xmlToObject(XStream xStream, File xml) {
+        if (xml == null) {
+            return null;
+        }
+        return (T) xStream.fromXML(xml);
+    }
+
+    public static <T extends Object> T xmlToObject(File xml) throws Exception {
+        try {
+            return (T) DEFAULT_X_STREAM.fromXML(xml);
+        } catch (Exception e) {
+            throw new Exception("convert xml to object FAIL!", e);
+        }
+    }
+
+    public static <T extends Object> T xmlToObject(InputStream inputStream) throws Exception {
+        try {
+            return (T) DEFAULT_X_STREAM.fromXML(inputStream);
+        } catch (Exception e) {
+            throw new Exception("convert xml to object FAIL!", e);
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        //ProjectDTO projectDTO = xmlToObject(new File("F:\\codes\\java\\self\\shoulder-framework\\shoulder-dependencies/pom.xml"));
+        ProjectDTO projectDTO = xmlToObject(new File("/Users/liuyanming/IdeaProjects/openSource/pom-update/pom.xml"));
+        System.out.println(projectDTO);
+    }
+
+}

+ 43 - 0
src/main/resources/application-dev.yml

@@ -0,0 +1,43 @@
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    druid:
+      driver-class-name: com.mysql.cj.jdbc.Driver
+      url: 'jdbc:mysql://${MYSQL_ADDR}/db_pom_update?characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=Asia/Shanghai&rewriteBatchStatements=true&allowPublicKeyRetrieval=true'
+      username: root
+      password: ${MYSQL_PWD}
+      initial-size: 10
+      max-active: 100
+      min-idle: 10
+      max-wait: 60000
+      pool-prepared-statements: true
+      max-pool-prepared-statement-per-connection-size: 20
+      time-between-eviction-runs-millis: 60000
+      min-evictable-idle-time-millis: 300000
+      #Oracle需要打开注释
+      #validation-query: SELECT 1 FROM DUAL
+      test-while-idle: true
+      test-on-borrow: false
+      test-on-return: false
+      stat-view-servlet:
+        enabled: true
+        url-pattern: /druid/*
+        # 开发没必要开后台
+        #login-username: admin
+        #login-password: admin
+      filter:
+        stat:
+          # 开发可以打开,但有一定性能损耗
+          log-slow-sql: true
+          slow-sql-millis: 5000
+          merge-sql: false
+        wall:
+          config:
+            multi-statement-allow: true
+
+  jpa:
+    show-sql: true    #开发时打开sql显示
+
+debug: true
+#localPath: 'F:/codes/java/self/shoulder-framework/shoulder-dependencies/pom.xml'
+localPath: 'F:/codes/java/projects/pom-update/pom.xml'

+ 41 - 0
src/main/resources/application-prod.yml

@@ -0,0 +1,41 @@
+spring:
+  datasource:
+    type: com.alibaba.druid.pool.DruidDataSource
+    druid:
+      driver-class-name: com.mysql.cj.jdbc.Driver
+      url: 'jdbc:mysql://localhost:3306/db_pom_update?characterEncoding=UTF-8&useSSL=false&autoReconnect=true&failOverReadOnly=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true'
+      username: pom_update
+      password: pompompom
+      initial-size: 10
+      max-active: 100
+      min-idle: 10
+      max-wait: 60000
+      pool-prepared-statements: true
+      max-pool-prepared-statement-per-connection-size: 20
+      time-between-eviction-runs-millis: 60000
+      min-evictable-idle-time-millis: 300000
+      #Oracle需要打开注释
+      #validation-query: SELECT 1 FROM DUAL
+      test-while-idle: true
+      test-on-borrow: false
+      test-on-return: false
+      stat-view-servlet:
+        enabled: true
+        url-pattern: /druid/*
+        login-username: admin
+        login-password: admin
+      filter:
+        stat:
+          log-slow-sql: false
+          slow-sql-millis: 5000
+          merge-sql: false
+        wall:
+          config:
+            multi-statement-allow: true
+
+    #日志配置
+logging:
+  file:
+    file:max-history: 10
+    file:max-size: 20mb
+    name: /home/web/pomUpdate/log/admin.log

+ 97 - 0
src/main/resources/application.yml

@@ -0,0 +1,97 @@
+# Tomcat
+server:
+  tomcat:
+    uri-encoding: UTF-8
+    max-threads: 1000
+    min-spare-threads: 30
+  port: 12345
+
+spring:
+  application:
+    name: pom-update
+  profiles:
+    active: dev
+  jackson:
+    date-format: yyyy-MM-dd HH:mm:ss
+    time-zone: GMT+8
+  servlet:
+    multipart:
+      max-file-size: 100MB
+      max-request-size: 100MB
+      enabled: true
+  output:
+    ansi:
+      enabled: NEVER
+
+  jpa:
+    hibernate:
+      naming:
+        physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy
+
+  mail:
+    test-connection: true
+
+shoulder:
+  application:
+    errorCodePrefix: '0x000b'
+
+  mail:
+    #smtp服务主机  qq邮箱则为smtp.qq.com
+    host: smtp.qq.com
+    port: 25
+    #服务协议
+    protocol: smtp
+    # 编码集
+    default-encoding: UTF-8 # Utf-8
+    sender-name: ${TEST_SENDER_EMAIL}
+    #发送邮件的账户
+    username: ${TEST_SENDER_EMAIL}
+    #授权码
+    password: ${TEST_EMAIL_TOKEN}
+    properties:
+      mail:
+        smtp:
+          auth: true
+          starttls:
+            enable: true
+            required: true
+            timeout: 10000
+
+pomupdate:
+  ext-info-list:
+    - id: org.springframework.boot:spring-boot-starter-parent
+      change-log-url: https://github.com/spring-projects/spring-boot/releases
+      opensource-url: https://github.com/spring-projects/spring-boot
+    - id: org.springframework.cloud:spring-cloud-dependencies
+      change-log-url: https://docs.spring.io/spring-cloud/docs/current/reference/html
+      opensource-url: https://spring.io/projects/spring-cloud#overview
+    - id: org.redisson:redisson
+      change-log-url: https://github.com/redisson/redisson/blob/master/CHANGELOG.md
+      opensource-url: https://github.com/redisson/redisson
+    - id: org.projectlombok:lombok
+      change-log-url: https://github.com/projectlombok/lombok/releases
+      opensource-url: https://github.com/projectlombok/lombok
+    - id: cn.hutool:hutool-all
+      change-log-url: https://gitee.com/dromara/hutool/blob/v5-master/CHANGELOG.md
+      opensource-url: https://gitee.com/dromara/hutool
+    - id: com.alibaba:transmittable-thread-local
+      change-log-url: https://github.com/alibaba/transmittable-thread-local/releases
+      opensource-url: https://github.com/alibaba/transmittable-thread-local
+    - id: com.baomidou:mybatis-plus-boot-starter
+      change-log-url: https://github.com/baomidou/mybatis-plus/blob/3.0/CHANGELOG.md
+      opensource-url: https://github.com/baomidou/mybatis-plus
+    - id: org.apache.tika:tika-core
+      change-log-url: https://github.com/apache/tika/blob/main/CHANGES.txt
+      opensource-url: https://github.com/apache/tika
+    - id: com.h2database:h2
+      change-log-url: https://github.com/h2database/h2database/releases
+      opensource-url: https://github.com/h2database/h2database
+    - id: commons-codec:commons-codec
+      change-log-url: https://github.com/apache/commons-codec/tags
+      opensource-url: https://github.com/apache/commons-codec
+    - id: mysql:mysql-connector-j
+      change-log-url: https://dev.mysql.com/doc/connector-j/{VERSION}/en/connector-j-whats-new.html
+      opensource-url: https://dev.mysql.com/doc/connector-j/en/
+    - id: mysql:mysql-connector-java
+      change-log-url: https://dev.mysql.com/doc/connector-j/{VERSION}/en/connector-j-whats-new.html
+      opensource-url: https://dev.mysql.com/doc/connector-j/en/

BIN
src/main/resources/static/favicon.ico


BIN
src/main/resources/static/favicon.png


+ 29 - 0
src/main/resources/static/index.html

@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <title>pom-update</title>
+</head>
+<body>
+
+<h1>添加 pom 依赖更新订阅</h1>
+添加后,每当依赖有新的稳定版本时,向您发送一封邮件,您可以在邮件中取消订阅。</br></br>
+<form action="/projects/create" method="post" enctype="multipart/form-data">
+    <label>pom.xml</label>
+    </br>
+    <input type="file" name="pomXml"/>
+    </br>
+    <label>您的邮箱</label>
+    </br>
+    <input type="email" name="email"/>
+    </br>
+    <label>检查完通知</label>
+    </br>
+    <input type="checkbox" name="notifyInstantlyAfterCheck"/>
+    </br>
+    <input type="submit" value="添加订阅"/>
+</form>
+<hr>
+
+</body>
+</html>

+ 88 - 0
src/test/java/TestSpiderVersion.java

@@ -0,0 +1,88 @@
+import cn.hutool.core.lang.Console;
+import cn.hutool.core.util.ReUtil;
+import org.lym.pom.constant.ThirdProjectInfoSourceEnum;
+import org.lym.pom.util.HttpsClientRequestFactory;
+import org.lym.pom.util.UserAgentInterceptor;
+import org.springframework.web.client.RestTemplate;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * @author lym
+ */
+public class TestSpiderVersion {
+
+    private static Map<String, Pattern> patternMap = new HashMap<>();
+
+    public static void main(String[] args) {
+
+        String groupId = "org.springframework";
+        String artifactId = "spring-core";
+
+
+        //https://search.maven.org/search?q=a:spring-tx
+
+        // maven
+        RestTemplate rest = new RestTemplate(new HttpsClientRequestFactory());
+        rest.getInterceptors().add(new UserAgentInterceptor());
+        // 目标网站
+        String aimUrl;
+        // 正则表达式
+        String regex;
+        Pattern pattern;
+        // 返回内容
+        String html;
+        // 结果列表
+        List<String> versionList;
+
+        ThirdProjectInfoSourceEnum thirdProjectInfo = ThirdProjectInfoSourceEnum.MVN_JAR;
+        // 目标网站
+        aimUrl = thirdProjectInfo.getUrl(groupId, artifactId);
+        // 正则表达式
+        regex = thirdProjectInfo.getVersionsPattern();
+
+        html = rest.getForObject(aimUrl, String.class);
+
+        versionList = ReUtil.findAll(getPattern(regex), html, 1);
+        for (String version : versionList) {
+            //打印标题
+            Console.log(version);
+        }
+
+        List<String> nameList = ReUtil.findAll(getPattern(thirdProjectInfo.getNamePattern()), html, 1);
+        System.out.println("=============== name ==================");
+        for (String version : nameList) {
+            Console.log(version);
+        }
+
+        nameList = ReUtil.findAll(getPattern(thirdProjectInfo.getDescriptionPattern()), html, 1);
+        System.out.println("=============== Description ==================");
+        for (String version : nameList) {
+            Console.log(version.trim());
+        }
+
+        nameList = ReUtil.findAll(getPattern(thirdProjectInfo.getHomeUrlPattern()), html, 1);
+        System.out.println("=============== HomeUrl ==================");
+        for (String version : nameList) {
+            Console.log(version);
+        }
+
+        nameList = ReUtil.findAll(getPattern(thirdProjectInfo.getOpenSourceProtocolPattern()), html, 1);
+        System.out.println("=============== OpenSourceProtocol ==================");
+        for (String version : nameList) {
+            Console.log(version.trim());
+        }
+    }
+
+    private static Pattern getPattern(String regex){
+        Pattern pattern = patternMap.get(regex);
+        if(pattern == null){
+            pattern = Pattern.compile(regex, Pattern.DOTALL);
+            patternMap.put(regex, pattern);
+        }
+        return pattern;
+    }
+}