├── .gitignore ├── README.md ├── back ├── .gitignore ├── Dockerfile ├── pom.xml ├── sql │ ├── shiny-data.sql │ └── shiny.sql └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── xkcoding │ │ │ └── shiny │ │ │ ├── ShinyApplication.java │ │ │ ├── common │ │ │ ├── ApiResponse.java │ │ │ ├── MyMapper.java │ │ │ ├── PageResult.java │ │ │ ├── ShinyConst.java │ │ │ ├── property │ │ │ │ └── ShinyProperties.java │ │ │ └── status │ │ │ │ ├── OperateStatus.java │ │ │ │ └── Status.java │ │ │ ├── config │ │ │ ├── AsyncConfig.java │ │ │ ├── ModelMapperConfig.java │ │ │ ├── RedisListenerConfig.java │ │ │ ├── RedisReceiverConfig.java │ │ │ └── ScheduleConfig.java │ │ │ ├── controller │ │ │ ├── SpiderConfigController.java │ │ │ ├── SpiderContentController.java │ │ │ ├── SpiderController.java │ │ │ └── SpiderLogController.java │ │ │ ├── exception │ │ │ └── ShinyException.java │ │ │ ├── handler │ │ │ └── GlobalExceptionHandler.java │ │ │ ├── mapper │ │ │ ├── EmailLogMapper.java │ │ │ ├── SpiderConfigMapper.java │ │ │ ├── SpiderContentMapper.java │ │ │ ├── SpiderLogMapper.java │ │ │ ├── SysConfigMapper.java │ │ │ ├── SysRoleMapper.java │ │ │ ├── SysUserMapper.java │ │ │ └── SysUserRoleMapper.java │ │ │ ├── model │ │ │ ├── EmailLogDO.java │ │ │ ├── SpiderConfigDO.java │ │ │ ├── SpiderContentDO.java │ │ │ ├── SpiderLogDO.java │ │ │ ├── SysConfigDO.java │ │ │ ├── SysRoleDO.java │ │ │ ├── SysUserDO.java │ │ │ ├── SysUserRoleDO.java │ │ │ ├── query │ │ │ │ ├── SpiderConfigPageQuery.java │ │ │ │ ├── SpiderContentPageQuery.java │ │ │ │ ├── SpiderLogPageQuery.java │ │ │ │ └── base │ │ │ │ │ └── PageCondition.java │ │ │ └── vo │ │ │ │ ├── SpiderConfigVO.java │ │ │ │ └── SpiderContentVO.java │ │ │ ├── service │ │ │ ├── IMailService.java │ │ │ ├── ISpiderConfigService.java │ │ │ ├── ISpiderContentService.java │ │ │ ├── ISpiderLogService.java │ │ │ ├── ISpiderService.java │ │ │ └── impl │ │ │ │ ├── MailServiceImpl.java │ │ │ │ ├── SpiderConfigServiceImpl.java │ │ │ │ ├── SpiderContentServiceImpl.java │ │ │ │ ├── SpiderLogServiceImpl.java │ │ │ │ └── SpiderServiceImpl.java │ │ │ ├── task │ │ │ ├── NotificationTask.java │ │ │ ├── SpiderTask.java │ │ │ ├── SpiderTaskFactory.java │ │ │ └── SpiderTaskManager.java │ │ │ └── util │ │ │ ├── DriverUtil.java │ │ │ ├── ShinyUtil.java │ │ │ └── SpringContextHolderUtil.java │ └── resources │ │ ├── META-INF │ │ └── additional-spring-configuration-metadata.json │ │ ├── application.yml │ │ ├── banner.txt │ │ ├── beetl.properties │ │ ├── email │ │ └── software-update.html │ │ ├── logback-spring.xml │ │ └── mybatis │ │ ├── generator │ │ ├── datasource.properties │ │ └── generatorConfig.xml │ │ └── mapper │ │ ├── EmailLogMapper.xml │ │ ├── SpiderConfigMapper.xml │ │ ├── SpiderContentMapper.xml │ │ ├── SpiderLogMapper.xml │ │ ├── SysConfigMapper.xml │ │ ├── SysRoleMapper.xml │ │ ├── SysUserMapper.xml │ │ └── SysUserRoleMapper.xml │ └── test │ └── java │ └── com │ └── xkcoding │ └── shiny │ ├── ShinyApplicationTests.java │ ├── service │ └── impl │ │ └── MailServiceImplTest.java │ └── spider │ ├── ChromeDriverTest.java │ ├── PhantomJsTest.java │ ├── SpiderTest.java │ ├── XclientSpiderChromeTest.java │ └── XclientSpiderPhantomJsTest.java ├── front ├── .browserslistrc ├── .editorconfig ├── .eslintrc.js ├── .gitignore ├── README.md ├── babel.config.js ├── package.json ├── postcss.config.js ├── public │ ├── favicon.ico │ └── index.html ├── src │ ├── App.vue │ ├── api │ │ └── index.js │ ├── assets │ │ └── images │ │ │ ├── avatar.jpg │ │ │ └── logo.png │ ├── components │ │ └── common │ │ │ └── custom-layout.vue │ ├── config │ │ └── index.js │ ├── directive │ │ └── index.js │ ├── lib │ │ ├── tools.js │ │ └── util.js │ ├── main.js │ ├── mock │ │ └── index.js │ ├── router │ │ ├── index.js │ │ └── router.js │ ├── store │ │ ├── actions.js │ │ ├── index.js │ │ ├── mutations.js │ │ └── state.js │ └── views │ │ ├── App.vue │ │ ├── Dev.vue │ │ ├── Manage.vue │ │ └── Push.vue ├── vue.config.js └── yarn.lock └── mysql ├── Dockerfile ├── mysqld.cnf ├── setup.sh └── sql ├── privileges.sql ├── shiny-data.sql └── shiny.sql /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### xkcoding-后端 template 3 | ### Spring Boot ### 4 | /target/ 5 | !.mvn/wrapper/maven-wrapper.jar 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.ipr 20 | out/ 21 | gen/ 22 | 23 | ### NetBeans ### 24 | /nbproject/private/ 25 | /build/ 26 | /nbbuild/ 27 | /dist/ 28 | /nbdist/ 29 | /.nb-gradle/ 30 | 31 | ### LOGS ### 32 | logs/ 33 | *.log 34 | 35 | ### Mac OS ### 36 | .DS_Store 37 | 38 | ### xkcoding-前端 template 39 | # Logs 40 | logs 41 | npm-debug.log* 42 | yarn-debug.log* 43 | yarn-error.log* 44 | 45 | # Runtime data 46 | pids 47 | *.pid 48 | *.seed 49 | *.pid.lock 50 | 51 | # Directory for instrumented libs generated by jscoverage/JSCover 52 | lib-cov 53 | 54 | # Coverage directory used by tools like istanbul 55 | coverage 56 | 57 | # nyc test coverage 58 | .nyc_output 59 | 60 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 61 | .grunt 62 | 63 | # Bower dependency directory (https://bower.io/) 64 | bower_components 65 | 66 | # node-waf configuration 67 | .lock-wscript 68 | 69 | # Compiled binary addons (https://nodejs.org/api/addons.html) 70 | build/Release 71 | 72 | # Dependency directories 73 | node_modules/ 74 | jspm_packages/ 75 | 76 | # TypeScript v1 declaration files 77 | typings/ 78 | 79 | # Optional npm cache directory 80 | .npm 81 | 82 | # Optional eslint cache 83 | .eslintcache 84 | 85 | # Optional REPL history 86 | .node_repl_history 87 | 88 | # Output of 'npm pack' 89 | *.tgz 90 | 91 | # Yarn Integrity file 92 | .yarn-integrity 93 | 94 | # dotenv environment variables file 95 | .env 96 | 97 | # parcel-bundler cache (https://parceljs.org/) 98 | .cache 99 | 100 | # next.js build output 101 | .next 102 | 103 | # nuxt.js build output 104 | .nuxt 105 | 106 | # vuepress build output 107 | .vuepress/dist 108 | 109 | # Serverless directories 110 | .serverless 111 | back/driver/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # shiny-telegram 2 | 3 | > 译为:闪耀的电报,为什么要取这个名字?因为 github 新建项目的时候有个随机名。。。 4 | 5 | ## 主要功能 6 | 1. 解析 http://xclient.info 网站获取对应软件历史版本 7 | 2. 软件名和对应在 xclient.info 的网页地址维护管理接口 8 | 3. 列表展示软件最近更新版本,以及最近更新时间 9 | 4. 点击列表页可以查看某个软件具体信息,包括软件基本信息,所有版本信息,所有版本更新时间,所有版本下载地址及提取码 10 | 5. 每天9点定时检查所有配置软件,若有最近两天更新的软件,则把最近更新的软件列表统一发邮件通知 11 | 12 | ## 使用技术 13 | 1. Spring Boot 后台框架 14 | 2. Spring Task 定时任务 15 | 3. Spring Email 邮件通知 16 | 4. Selenium + ChromeDriver( https://sites.google.com/a/chromium.org/chromedriver/downloads )/PhantomJs( http://phantomjs.org/download.html ) 模拟浏览器行为处理反爬 17 | 5. Jsoup + Xsoup 解析 DOM 节点 18 | 6. Mysql 存储 19 | 7. Vue + iView 前端框架 20 | 21 | ## 项目目录 22 | ```bash 23 | . 24 | ├── README.md 项目介绍 25 | ├── back 项目后端 26 | ├── front 项目前端 27 | └── mysql 项目 mysql docker镜像构建文件 28 | ``` 29 | 30 | ## 项目构建与运行 31 | ### 项目构建 32 | #### mysql 镜像构建 33 | 1. 构建 `mysql` 镜像 34 | ```bash 35 | $ cd mysql 36 | $ docker build -t shiny-mysql . 37 | Sending build context to Docker daemon 24.06kB 38 | Step 1/9 : FROM mysql:5.7 39 | ---> 0d16d0a97dd1 40 | Step 2/9 : MAINTAINER yangkai.shen 237497819@qq.com 41 | ---> Running in 7f5fa09ba5dd 42 | Removing intermediate container 7f5fa09ba5dd 43 | ---> 7188872d8492 44 | Step 3/9 : ENV MYSQL_ALLOW_EMPTY_PASSWORD yes 45 | ---> Running in f11ed6362744 46 | Removing intermediate container f11ed6362744 47 | ---> dbc977df5488 48 | Step 4/9 : COPY setup.sh /mysql/setup.sh 49 | ---> 7f31fff84f9e 50 | Step 5/9 : COPY sql/shiny.sql /mysql/shiny.sql 51 | ---> 44e65ddf7fa9 52 | Step 6/9 : COPY sql/shiny-data.sql /mysql/shiny-data.sql 53 | ---> 2a86658ba4f9 54 | Step 7/9 : COPY sql/privileges.sql /mysql/privileges.sql 55 | ---> 44b44deb7d07 56 | Step 8/9 : COPY ./mysqld.cnf /etc/mysql/mysql.conf.d/mysqld.cnf 57 | ---> 14a88aec77c0 58 | Step 9/9 : CMD ["sh", "/mysql/setup.sh"] 59 | ---> Running in e0e78e73e646 60 | Removing intermediate container e0e78e73e646 61 | ---> 8ea97c1bf792 62 | Successfully built 8ea97c1bf792 63 | Successfully tagged shiny-mysql:latest 64 | ``` 65 | 2. 运行 `mysql` 镜像 66 | 67 | ```bash 68 | $ mkdir -p $HOME/docker/shiny/mysql/data 69 | $ mkdir -p $HOME/docker/shiny/mysql/logs 70 | $ docker run -d --name shiny-mysql -p 13306:3306 -v $HOME/shiny/mysql/data:/var/lib/mysql -v $HOME/shiny/mysql/logs:/logs shiny-mysql 71 | 974de62c11fb294b2330af339f8b07299a69f956f2a0df1ee5d2e8cbab1dd485 72 | ``` 73 | 3. 查看镜像构建日志 74 | ```bash 75 | $ docker logs shiny-mysql 76 | 0.设置时区为东八区.... 77 | 2018-09-10 22:59:56 78 | MySQL Community Server 5.7.22 is not running. 79 | 1.启动mysql.... 80 | .. 81 | MySQL Community Server 5.7.22 is started. 82 | MySQL Community Server 5.7.22 is running. 83 | 2.开始创建数据库和表结构.... 84 | 3.创建数据库和表结构完毕.... 85 | 4.开始导入数据.... 86 | 5.导入数据完毕.... 87 | MySQL Community Server 5.7.22 is running. 88 | 6.开始修改密码.... 89 | host user 90 | localhost mysql.session 91 | localhost mysql.sys 92 | localhost root 93 | 7.修改密码完毕.... 94 | MySQL Community Server 5.7.22 is running. 95 | /mysql/setup.sh: 1: /mysql/setup.sh: mysql容器启动完毕,且数据导入成功: not found 96 | ``` 97 | 98 | ### 项目运行 99 | #### 源码运行 100 | 101 | #### 镜像运行 102 | 1. `mysql` 镜像 103 | - 使用上面自己构建的镜像 104 | - 拉取远端镜像,`docker pull registry.cn-hangzhou.aliyuncs.com/xkcoding/shiny-telegram-mysql:latest` 105 | 2. 运行 `mysql` 镜像 106 | ```bash 107 | $ mkdir -p $HOME/docker/shiny/mysql/data 108 | $ mkdir -p $HOME/docker/shiny/mysql/logs 109 | $ docker run -d --name shiny-mysql -p 13306:3306 -v $HOME/shiny/mysql/data:/var/lib/mysql -v $HOME/shiny/mysql/logs:/logs registry.cn-hangzhou.aliyuncs.com/xkcoding/shiny-telegram-mysql:latest 110 | 014226044c171d37a122128765b618560b992909eda6ccc71f07584a7fea6569 111 | ``` 112 | 113 | 114 | ## 项目截图 115 | 116 | ## 联系我 117 | - 邮箱: 237497819@qq.com 118 | - 扣扣: 237497819 -------------------------------------------------------------------------------- /back/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | !.mvn/wrapper/maven-wrapper.jar 3 | 4 | ### STS ### 5 | .apt_generated 6 | .classpath 7 | .factorypath 8 | .project 9 | .settings 10 | .springBeans 11 | .sts4-cache 12 | 13 | ### IntelliJ IDEA ### 14 | .idea 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | /nbproject/private/ 21 | /build/ 22 | /nbbuild/ 23 | /dist/ 24 | /nbdist/ 25 | /.nb-gradle/ -------------------------------------------------------------------------------- /back/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM hub.c.163.com/library/java:8-alpine 2 | 3 | MAINTAINER yangkai.shen 237497819@qq.com 4 | 5 | ADD target/*.jar back.jar 6 | 7 | EXPOSE 8080 8 | 9 | ENTRYPOINT ["java", "-jar", "/back.jar"] 10 | -------------------------------------------------------------------------------- /back/sql/shiny-data.sql: -------------------------------------------------------------------------------- 1 | use `shiny`; 2 | -- ---------------------------- 3 | -- 5、采集配置表数据 4 | -- ---------------------------- 5 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (1, 'Movist', 'http://xclient.info/s/movist.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', '一款CPU占用率低的高清多格式媒体播放器'); 6 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (2, 'Things', 'http://xclient.info/s/things.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', '一款优秀的GTD任务管理工具'); 7 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (3, 'iStatistica', 'http://xclient.info/s/istatistica.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', '一款高颜值的系统监控工具'); 8 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (4, 'TinyCal', 'http://xclient.info/s/tinycal.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', '小历 - 小而美的日历'); 9 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (5, 'Money Pro', 'http://xclient.info/s/money-pro.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', '可同步账单、预算和账户'); 10 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (6, 'OmniPlan', 'http://xclient.info/s/omni-plan.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', '专业版 最NB的项目管理流程软件'); 11 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (7, 'Navicat Premium', 'http://xclient.info/s/navicat-premium.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', '强大的数据库管理工具'); 12 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (8, 'OmniGraffle Pro', 'http://xclient.info/s/omnigraffle.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', '强大的图形工具'); 13 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (9, 'XMind 8 Pro', 'http://xclient.info/s/xmind.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', '最受欢迎思维导图软件'); 14 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (10, 'StarUML', 'http://xclient.info/s/staruml.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', '强大的UML工具'); 15 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (11, 'ScreenFlow', 'http://xclient.info/s/screenflow.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', '优秀的屏幕录像软件'); 16 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (12, 'EdrawMax', 'http://xclient.info/s/edraw-max.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', '亿图图示专家 基于矢量的绘图工具'); 17 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (13, 'Charles', 'http://xclient.info/s/charles.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', 'Mac上的抓包工具'); 18 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (14, 'SnippetsLab', 'http://xclient.info/s/snippetslab.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', '构建你的私人代码片段库'); 19 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (15, 'Adobe Photoshop CC', 'http://xclient.info/s/adobe-photoshop-cc.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', ''); 20 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (16, 'Adobe Photoshop Lightroom CC', 'http://xclient.info/s/adobe-lightroom-cc.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', ''); 21 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (17, 'VMware Fusion', 'http://xclient.info/s/vmware-fusion.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', '强大的虚拟机应用'); 22 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (18, 'Tuxera NTFS', 'http://xclient.info/s/tuxera-ntfs.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', '让你的Mac支持NTFS'); 23 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (19, 'Parallels Desktop', 'http://xclient.info/s/parallels-desktop.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', '最佳Mac虚拟机解决方案'); 24 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (20, 'Microsoft Office', 'http://xclient.info/s/office-for-mac.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', '多国语言大客户版'); 25 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (21, 'Beyond Compare', 'http://xclient.info/s/beyond-compare.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', '文件对比利器'); 26 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (22, 'Sublime Text', 'http://xclient.info/s/sublime-text.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', '一款优秀的代码编辑器'); 27 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (23, 'UltraEdit', 'http://xclient.info/s/ultraedit.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', '老牌文本编辑器'); 28 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (24, 'Understand', 'http://xclient.info/s/understand.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', '代码阅读分析软件'); 29 | INSERT INTO `spider_config`(`id`, `spider_name`, `spider_url`, `last_spider_time`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`) VALUES (25, 'Paste', 'http://xclient.info/s/paste-for-mac.html', NULL, '管理员', '2018-09-10 00:00:00', '管理员', '2018-09-10 00:00:00', '剪切板增强工具'); 30 | -------------------------------------------------------------------------------- /back/sql/shiny.sql: -------------------------------------------------------------------------------- 1 | -- 创建数据库 2 | create database IF NOT EXISTS `shiny` default character set utf8 collate utf8_general_ci; 3 | 4 | use `shiny`; 5 | 6 | -- ---------------------------- 7 | -- 1、参数配置表 8 | -- ---------------------------- 9 | CREATE TABLE IF NOT EXISTS `sys_config` ( 10 | `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '参数主键', 11 | `config_name` varchar(100) DEFAULT '' COMMENT '参数名称', 12 | `config_key` varchar(100) DEFAULT '' COMMENT '参数键名', 13 | `config_value` varchar(100) DEFAULT '' COMMENT '参数键值', 14 | `config_type` int(2) DEFAULT 0 COMMENT '系统内置(0否 1是)', 15 | `create_by` varchar(64) DEFAULT '' COMMENT '创建者', 16 | `create_time` datetime DEFAULT NULL COMMENT '创建时间', 17 | `update_by` varchar(64) DEFAULT '' COMMENT '更新者', 18 | `update_time` datetime DEFAULT NULL COMMENT '更新时间', 19 | `remark` varchar(500) DEFAULT '' COMMENT '备注', 20 | PRIMARY KEY (`id`) 21 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='参数配置表'; 22 | 23 | -- ---------------------------- 24 | -- 2、系统用户表 25 | -- ---------------------------- 26 | CREATE TABLE IF NOT EXISTS `sys_user` ( 27 | `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID', 28 | `dept_id` int(11) DEFAULT NULL COMMENT '部门ID', 29 | `login_name` varchar(30) NOT NULL COMMENT '登录账号', 30 | `user_name` varchar(30) NOT NULL COMMENT '用户昵称', 31 | `user_type` varchar(2) DEFAULT '00' COMMENT '用户类型(00系统用户)', 32 | `email` varchar(50) DEFAULT '' COMMENT '用户邮箱', 33 | `phonenumber` varchar(11) DEFAULT '' COMMENT '手机号码', 34 | `sex` int(2) DEFAULT 0 COMMENT '用户性别(0男 1女 2未知)', 35 | `avatar` varchar(100) DEFAULT '' COMMENT '头像路径', 36 | `password` varchar(100) DEFAULT '' COMMENT '密码', 37 | `status` int(2) DEFAULT 1 COMMENT '帐号状态(0停用 1正常)', 38 | `del_flag` int(2) DEFAULT 0 COMMENT '删除标志(0代表存在 1代表删除)', 39 | `login_ip` varchar(20) DEFAULT '' COMMENT '最后登陆IP', 40 | `login_date` datetime DEFAULT NULL COMMENT '最后登陆时间', 41 | `create_by` varchar(64) DEFAULT '' COMMENT '创建者', 42 | `create_time` datetime DEFAULT NULL COMMENT '创建时间', 43 | `update_by` varchar(64) DEFAULT '' COMMENT '更新者', 44 | `update_time` datetime DEFAULT NULL COMMENT '更新时间', 45 | `remark` varchar(500) DEFAULT '' COMMENT '备注', 46 | PRIMARY KEY (`id`) 47 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='系统用户表'; 48 | 49 | -- ---------------------------- 50 | -- 3、角色信息表 51 | -- ---------------------------- 52 | CREATE TABLE IF NOT EXISTS `sys_role` ( 53 | `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '角色ID', 54 | `role_name` varchar(30) NOT NULL COMMENT '角色名称', 55 | `role_key` varchar(100) NOT NULL COMMENT '角色权限字符串', 56 | `role_sort` int(4) NOT NULL COMMENT '显示顺序', 57 | `status` int(2) DEFAULT 1 COMMENT '角色状态(0停用 1正常)', 58 | `create_by` varchar(64) DEFAULT '' COMMENT '创建者', 59 | `create_time` datetime DEFAULT NULL COMMENT '创建时间', 60 | `update_by` varchar(64) DEFAULT '' COMMENT '更新者', 61 | `update_time` datetime DEFAULT NULL COMMENT '更新时间', 62 | `remark` varchar(500) DEFAULT '' COMMENT '备注', 63 | PRIMARY KEY (`id`) 64 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色信息表'; 65 | 66 | -- ---------------------------- 67 | -- 4、用户和角色关联表 68 | -- ---------------------------- 69 | CREATE TABLE IF NOT EXISTS `sys_user_role` ( 70 | `user_id` int(11) NOT NULL COMMENT '用户ID', 71 | `role_id` int(11) NOT NULL COMMENT '角色ID', 72 | PRIMARY KEY (`user_id`,`role_id`) 73 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户和角色关联表'; 74 | 75 | -- ---------------------------- 76 | -- 5、采集配置 77 | -- ---------------------------- 78 | CREATE TABLE IF NOT EXISTS `spider_config` ( 79 | `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '配置主键', 80 | `spider_name` varchar(100) DEFAULT '' COMMENT '采集名称', 81 | `spider_url` varchar(500) DEFAULT '' COMMENT '采集URL', 82 | `last_spider_time` datetime DEFAULT NULL COMMENT '上次采集时间', 83 | `create_by` varchar(64) DEFAULT '' COMMENT '创建者', 84 | `create_time` datetime DEFAULT NULL COMMENT '创建时间', 85 | `update_by` varchar(64) DEFAULT '' COMMENT '更新者', 86 | `update_time` datetime DEFAULT NULL COMMENT '更新时间', 87 | `remark` varchar(500) DEFAULT '' COMMENT '备注', 88 | PRIMARY KEY (`id`) 89 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='采集配置'; 90 | 91 | -- ---------------------------- 92 | -- 6、采集内容 93 | -- ---------------------------- 94 | CREATE TABLE IF NOT EXISTS `spider_content` ( 95 | `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '内容主键', 96 | `config_id` int(11) NOT NULL COMMENT '采集配置id', 97 | `config_name` varchar(100) NOT NULL COMMENT '采集配置名称', 98 | `title` varchar(100) DEFAULT '' COMMENT '软件名称', 99 | `content` text COMMENT '软件详细信息', 100 | `version` varchar(100) DEFAULT '' COMMENT '软件版本', 101 | `language` varchar(100) DEFAULT '' COMMENT '软件语言', 102 | `update_time` date DEFAULT NULL COMMENT '软件更新时间', 103 | `size` varchar(100) DEFAULT '' COMMENT '软件大小', 104 | `ct_pan_url` varchar(500) DEFAULT '' COMMENT '城通网盘链接', 105 | `ct_pan_code` varchar(500) DEFAULT '' COMMENT '城通网盘提取码', 106 | `bd_pan_url` varchar(500) DEFAULT '' COMMENT '百度网盘链接', 107 | `bd_pan_code` varchar(500) DEFAULT '' COMMENT '百度网盘提取码', 108 | `spider_time` datetime DEFAULT NULL COMMENT '采集时间', 109 | PRIMARY KEY (`id`) 110 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='采集内容'; 111 | 112 | -- ---------------------------- 113 | -- 7、采集日志记录 114 | -- ---------------------------- 115 | CREATE TABLE IF NOT EXISTS `spider_log` ( 116 | `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '日志主键', 117 | `config_id` int(11) NOT NULL COMMENT '采集配置 id', 118 | `spider_name` varchar(100) DEFAULT '' COMMENT '采集名称', 119 | `version` varchar(100) DEFAULT '' COMMENT '采集版本', 120 | `spider_url` varchar(500) DEFAULT '' COMMENT '采集URL', 121 | `status` int(2) DEFAULT 1 COMMENT '采集状态(0异常 1正常)', 122 | `error_msg` varchar(2000) DEFAULT '' COMMENT '错误消息', 123 | `spider_time` datetime DEFAULT NULL COMMENT '采集时间', 124 | PRIMARY KEY (`id`) 125 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='采集日志记录'; 126 | 127 | -- ---------------------------- 128 | -- 8、邮件记录 129 | -- ---------------------------- 130 | CREATE TABLE IF NOT EXISTS `email_log` ( 131 | `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '邮件主键', 132 | `to` text NOT NULL COMMENT '收件人邮箱地址(多个逗号分隔)', 133 | `subject` varchar(100) DEFAULT '' COMMENT '邮件主题', 134 | `content` text NOT NULL COMMENT '邮件内容', 135 | `is_template` int(2) DEFAULT 1 COMMENT '是否是模板邮件(0否 1是)', 136 | `template_path` varchar(100) DEFAULT NULL COMMENT '模板路径', 137 | `template_name` varchar(100) DEFAULT NULL COMMENT '模板名称', 138 | `send_time` datetime DEFAULT NULL COMMENT '邮件发送时间', 139 | PRIMARY KEY (`id`) 140 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='邮件记录'; -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/ShinyApplication.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny; 2 | 3 | import com.xkcoding.shiny.common.property.ShinyProperties; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 7 | import tk.mybatis.spring.annotation.MapperScan; 8 | 9 | /** 10 | *
11 | * 后端启动类 12 | *
13 | * 14 | * @package: com.xkcoding.shiny 15 | * @description: 后端启动类 16 | * @author: yangkai.shen 17 | * @date: Created in 2018/8/15 上午10:24 18 | * @copyright: Copyright (c) 2018 19 | * @version: V1.0 20 | * @modified: yangkai.shen 21 | */ 22 | @SpringBootApplication 23 | @MapperScan(basePackages = {"com.xkcoding.shiny.mapper"}) 24 | @EnableConfigurationProperties(ShinyProperties.class) 25 | public class ShinyApplication { 26 | 27 | public static void main(String[] args) { 28 | SpringApplication.run(ShinyApplication.class, args); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/common/ApiResponse.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.common; 2 | 3 | import com.xkcoding.shiny.common.status.Status; 4 | import lombok.Data; 5 | 6 | import java.io.Serializable; 7 | 8 | /** 9 | *10 | * API 统一返回格式封装 11 | *
12 | * 13 | * @package: com.xkcoding.shiny.common 14 | * @description: API 统一返回格式封装 15 | * @author: yangkai.shen 16 | * @date: Created in 2018/8/15 下午8:42 17 | * @copyright: Copyright (c) 2018 18 | * @version: V1.0 19 | * @modified: yangkai.shen 20 | */ 21 | @Data 22 | public class ApiResponse implements Serializable { 23 | 24 | private static final long serialVersionUID = 1672493411204459264L; 25 | 26 | /** 27 | * 返回码 28 | */ 29 | private Integer code; 30 | 31 | /** 32 | * 返回信息 33 | */ 34 | private String msg; 35 | 36 | /** 37 | * 返回数据 38 | */ 39 | private Object data; 40 | 41 | /** 42 | * 默认构造 43 | */ 44 | public ApiResponse() { 45 | this.code = Status.SUCCESS.getCode(); 46 | this.msg = Status.SUCCESS.getMsg(); 47 | } 48 | 49 | /** 50 | * 构造 API 返回对象 51 | * 52 | * @param code 返回码 53 | * @param msg 返回信息 54 | * @param data 数据 55 | */ 56 | public ApiResponse(Integer code, String msg, Object data) { 57 | this.code = code; 58 | this.msg = msg; 59 | this.data = data; 60 | } 61 | 62 | /** 63 | * 通用构造包含返回信息的 ApiResponse8 | * 通用 Mapper 9 | *
10 | * 11 | * @package: com.xkcoding.shiny.common 12 | * @description: 通用 Mapper 13 | * @author: yangkai.shen 14 | * @date: Created in 2018/8/15 下午6:43 15 | * @copyright: Copyright (c) 2018 16 | * @version: V1.0 17 | * @modified: yangkai.shen 18 | */ 19 | public interface MyMapper11 | * 分页结果 12 | *
13 | * 14 | * @package: com.xkcoding.shiny.common 15 | * @description: 分页结果 16 | * @author: yangkai.shen 17 | * @date: Created in 2018/8/15 下午10:00 18 | * @copyright: Copyright (c) 2018 19 | * @version: V1.0 20 | * @modified: yangkai.shen 21 | */ 22 | @Data 23 | @NoArgsConstructor 24 | @AllArgsConstructor 25 | public class PageResult5 | * Shiny常量池 6 | *
7 | * 8 | * @package: com.xkcoding.shiny.common 9 | * @description: Shiny常量池 10 | * @author: yangkai.shen 11 | * @date: Created in 2018/8/15 下午10:04 12 | * @copyright: Copyright (c) 2018 13 | * @version: V1.0 14 | * @modified: yangkai.shen 15 | */ 16 | public interface ShinyConst { 17 | /** 18 | * 默认当前页 19 | */ 20 | Integer DEFAULT_CURRENT_PAGE = 1; 21 | 22 | /** 23 | * 默认每页条数 24 | */ 25 | Integer DEFAULT_PAGE_SIZE = 20; 26 | 27 | /** 28 | * Redis 中监听的邮件通道 29 | */ 30 | String MAIL_CHANNEL = "channel_mail"; 31 | } 32 | -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/common/property/ShinyProperties.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.common.property; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | 6 | /** 7 | *8 | * 自定义配置 9 | *
10 | * 11 | * @package: com.xkcoding.shiny.common.property 12 | * @description: 自定义配置 13 | * @author: yangkai.shen 14 | * @date: Created in 2018/8/27 上午9:57 15 | * @copyright: Copyright (c) 2018 16 | * @version: V1.0 17 | * @modified: yangkai.shen 18 | */ 19 | @ConfigurationProperties(prefix = "shiny") 20 | @Data 21 | public class ShinyProperties { 22 | /** 23 | * 软件名称 24 | */ 25 | private String name; 26 | 27 | /** 28 | * 软件版本 29 | */ 30 | private String version; 31 | 32 | /** 33 | * 版权年份 34 | */ 35 | private String copyrightYear; 36 | 37 | /** 38 | * 作者 39 | */ 40 | private String developer; 41 | 42 | /** 43 | * driver 路径 44 | */ 45 | private String driverPath; 46 | 47 | /** 48 | * 并发软件采集的数量 49 | */ 50 | private Integer spiderNum; 51 | 52 | /** 53 | * 邮件发送人 54 | */ 55 | private String mailFrom; 56 | 57 | } 58 | -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/common/status/OperateStatus.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.common.status; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | *7 | * 操作状态枚举 8 | *
9 | * 10 | * @package: com.xkcoding.shiny.common.status 11 | * @description: 操作状态枚举 12 | * @author: yangkai.shen 13 | * @date: Created in 2018/8/28 下午9:04 14 | * @copyright: Copyright (c) 2018 15 | * @version: V1.0 16 | * @modified: yangkai.shen 17 | */ 18 | @Getter 19 | public enum OperateStatus { 20 | /** 21 | * 成功 22 | */ 23 | SUCCESS(1), 24 | 25 | /** 26 | * 失败 27 | */ 28 | ERROR(0); 29 | 30 | OperateStatus(Integer code) { 31 | this.code = code; 32 | } 33 | 34 | private Integer code; 35 | } 36 | -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/common/status/Status.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.common.status; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | *7 | * 状态码枚举 8 | *
9 | * 10 | * @package: com.xkcoding.shiny.common.status 11 | * @description: 状态码枚举 12 | * @author: yangkai.shen 13 | * @date: Created in 2018/8/15 下午8:37 14 | * @copyright: Copyright (c) 2018 15 | * @version: V1.0 16 | * @modified: yangkai.shen 17 | */ 18 | @Getter 19 | public enum Status { 20 | /** 21 | * 操作成功 22 | */ 23 | SUCCESS(200, "操作成功"), 24 | 25 | /** 26 | * 请求错误 27 | */ 28 | BAD_REQUEST(400, "请求错误"), 29 | 30 | /** 31 | * 尚未登录 32 | */ 33 | UNAUTHORIZED(401, "尚未登录"), 34 | 35 | /** 36 | * 权限不够 37 | */ 38 | FORBIDDEN(403, "权限不够"), 39 | 40 | /** 41 | * 请求不存在 42 | */ 43 | REQUEST_NOT_FOUND(404, "请求不存在"), 44 | 45 | /** 46 | * 服务器内部错误 47 | */ 48 | INTERNAL_SERVER_ERROR(500, "服务器内部错误"), 49 | 50 | /** 51 | * 请求参数错误 52 | */ 53 | REQUEST_PARAMS_ERROR(50000, "请求参数错误"), 54 | 55 | /** 56 | * 采集配置不存在 57 | */ 58 | CONFIG_NOT_EXIST(50001, "采集配置不存在"), 59 | 60 | /** 61 | * 日志id列表不能为空 62 | */ 63 | LOG_ID_LIST_NOT_EMPTY(50002, "日志id列表不能为空"), 64 | 65 | /** 66 | * 采集id列表不能为空 67 | */ 68 | CONFIG_ID_LIST_NOT_EMPTY(50003, "采集id列表不能为空"), 69 | 70 | /** 71 | * 采集配置 URL 不能为空 72 | */ 73 | CONFIG_URL_NOT_BLANK(50004, "采集配置 URL 不能为空"), 74 | 75 | /** 76 | * 采集配置已存在 77 | */ 78 | CONFIG_EXIST(50005, "采集配置已存在"); 79 | 80 | private Integer code; 81 | private String msg; 82 | 83 | Status(Integer code, String msg) { 84 | this.code = code; 85 | this.msg = msg; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/config/AsyncConfig.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.scheduling.annotation.EnableAsync; 6 | import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; 7 | 8 | import java.util.concurrent.Executor; 9 | 10 | /** 11 | *12 | * 异步任务配置 13 | *
14 | * 15 | * @package: com.xkcoding.shiny.config 16 | * @description: 异步任务配置 17 | * @author: yangkai.shen 18 | * @date: Created in 2018/8/27 下午6:41 19 | * @copyright: Copyright (c) 2018 20 | * @version: V1.0 21 | * @modified: yangkai.shen 22 | */ 23 | @Configuration 24 | @EnableAsync 25 | public class AsyncConfig { 26 | 27 | @Bean 28 | public Executor asyncExecutor() { 29 | ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); 30 | executor.setCorePoolSize(200); 31 | executor.setMaxPoolSize(250); 32 | executor.setQueueCapacity(50); 33 | executor.setThreadNamePrefix("Async-Thread-"); 34 | executor.initialize(); 35 | return executor; 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/config/ModelMapperConfig.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.config; 2 | 3 | import org.modelmapper.ModelMapper; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | /** 8 | *9 | * ModelMapper 配置类 10 | *
11 | * 12 | * @package: com.xkcoding.shiny.config 13 | * @description: ModelMapper 配置类 14 | * @author: yangkai.shen 15 | * @date: Created in 2018/8/15 下午8:35 16 | * @copyright: Copyright (c) 2018 17 | * @version: V1.0 18 | * @modified: yangkai.shen 19 | */ 20 | @Configuration 21 | public class ModelMapperConfig { 22 | @Bean 23 | public ModelMapper modelMapper() { 24 | return new ModelMapper(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/config/RedisListenerConfig.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.config; 2 | 3 | import com.xkcoding.shiny.common.ShinyConst; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.data.redis.connection.RedisConnectionFactory; 8 | import org.springframework.data.redis.core.StringRedisTemplate; 9 | import org.springframework.data.redis.listener.PatternTopic; 10 | import org.springframework.data.redis.listener.RedisMessageListenerContainer; 11 | import org.springframework.data.redis.listener.adapter.MessageListenerAdapter; 12 | 13 | import java.util.concurrent.CountDownLatch; 14 | 15 | /** 16 | *17 | * Redis 发布/订阅配置 18 | *
19 | * 20 | * @package: com.xkcoding.shiny.config 21 | * @description: Redis 发布/订阅配置 22 | * @author: yangkai.shen 23 | * @date: Created in 2018/9/6 下午4:15 24 | * @copyright: Copyright (c) 2018 25 | * @version: V1.0 26 | * @modified: yangkai.shen 27 | */ 28 | @Configuration 29 | @Slf4j 30 | public class RedisListenerConfig { 31 | 32 | /** 33 | * 初始化监听器 34 | * 35 | * @param connectionFactory 连接工厂 36 | * @param listenerAdapter 监听器 37 | * @return 监听器容器 38 | */ 39 | @Bean 40 | public RedisMessageListenerContainer container(RedisConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) { 41 | log.info("【Redis】启动监听......"); 42 | RedisMessageListenerContainer container = new RedisMessageListenerContainer(); 43 | container.setConnectionFactory(connectionFactory); 44 | container.addMessageListener(listenerAdapter, new PatternTopic(ShinyConst.MAIL_CHANNEL)); 45 | return container; 46 | } 47 | 48 | /** 49 | * 利用反射来创建监听到消息之后的执行方法 50 | * 51 | * @param receiver 接收到消息的对象 52 | * @return {@link MessageListenerAdapter} 53 | */ 54 | @Bean 55 | public MessageListenerAdapter listenerAdapter(RedisReceiverConfig receiver) { 56 | return new MessageListenerAdapter(receiver, "receiveMessage"); 57 | } 58 | 59 | @Bean 60 | public RedisReceiverConfig receiver(CountDownLatch latch) { 61 | return new RedisReceiverConfig(latch); 62 | } 63 | 64 | @Bean 65 | public CountDownLatch latch() { 66 | return new CountDownLatch(1); 67 | } 68 | 69 | /** 70 | * 使用默认的工厂初始化redis操作模板 71 | * 72 | * @param connectionFactory 连接工厂 73 | * @return {@link StringRedisTemplate} 74 | */ 75 | @Bean 76 | public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory connectionFactory) { 77 | return new StringRedisTemplate(connectionFactory); 78 | } 79 | 80 | } -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/config/RedisReceiverConfig.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.config; 2 | 3 | import cn.hutool.core.lang.Dict; 4 | import cn.hutool.json.JSONUtil; 5 | import com.xkcoding.shiny.model.SpiderContentDO; 6 | import com.xkcoding.shiny.service.IMailService; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | 10 | import javax.mail.MessagingException; 11 | import java.util.concurrent.CountDownLatch; 12 | 13 | /** 14 | *15 | * redis 接收消息接口 实现 16 | *
17 | * 18 | * @package: com.xkcoding.shiny.service.impl 19 | * @description: redis 接收消息接口 实现 20 | * @author: yangkai.shen 21 | * @date: Created in 2018/9/6 下午4:20 22 | * @copyright: Copyright (c) 2018 23 | * @version: V1.0 24 | * @modified: yangkai.shen 25 | */ 26 | @Slf4j 27 | public class RedisReceiverConfig { 28 | private CountDownLatch latch; 29 | 30 | @Autowired 31 | private IMailService mailService; 32 | 33 | @Autowired 34 | public RedisReceiverConfig(CountDownLatch latch) { 35 | this.latch = latch; 36 | } 37 | 38 | /** 39 | * 接收消息执行的方法 40 | * 41 | * @param message 消息 42 | */ 43 | public void receiveMessage(Object message) throws MessagingException { 44 | log.info("【收到消息】消息内容:{}", JSONUtil.toJsonStr(message)); 45 | mailService.sendHtmlTemplateMail("237497819@qq.com", "软件更新通知", Dict.create().set("trDataList", JSONUtil.toList(JSONUtil.parseArray(message), SpiderContentDO.class)), "email", "software-update.html"); 46 | latch.countDown(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/config/ScheduleConfig.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.config; 2 | 3 | import org.apache.commons.lang3.concurrent.BasicThreadFactory; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.ComponentScan; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.scheduling.annotation.EnableScheduling; 8 | import org.springframework.scheduling.annotation.SchedulingConfigurer; 9 | import org.springframework.scheduling.config.ScheduledTaskRegistrar; 10 | 11 | import java.util.concurrent.Executor; 12 | import java.util.concurrent.ScheduledThreadPoolExecutor; 13 | 14 | /** 15 | *16 | * 定时任务配置 17 | *
18 | * 19 | * @package: com.xkcoding.shiny.config 20 | * @description: 定时任务配置 21 | * @author: yangkai.shen 22 | * @date: Created in 2018/8/22 下午9:59 23 | * @copyright: Copyright (c) 2018 24 | * @version: V1.0 25 | * @modified: yangkai.shen 26 | */ 27 | @Configuration 28 | @EnableScheduling 29 | @ComponentScan(basePackages = "com.xkcoding.shiny.task") 30 | public class ScheduleConfig implements SchedulingConfigurer { 31 | 32 | @Override 33 | public void configureTasks(ScheduledTaskRegistrar taskRegistrar) { 34 | taskRegistrar.setScheduler(taskExecutor()); 35 | } 36 | 37 | @Bean 38 | public Executor taskExecutor() { 39 | return new ScheduledThreadPoolExecutor(100, new BasicThreadFactory.Builder().namingPattern("Schedule-Thread-%d").build()); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/controller/SpiderConfigController.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.controller; 2 | 3 | import cn.hutool.core.collection.CollUtil; 4 | import cn.hutool.core.util.ObjectUtil; 5 | import com.xkcoding.shiny.common.ApiResponse; 6 | import com.xkcoding.shiny.common.PageResult; 7 | import com.xkcoding.shiny.common.status.Status; 8 | import com.xkcoding.shiny.exception.ShinyException; 9 | import com.xkcoding.shiny.model.SpiderConfigDO; 10 | import com.xkcoding.shiny.model.query.SpiderConfigPageQuery; 11 | import com.xkcoding.shiny.model.vo.SpiderConfigVO; 12 | import com.xkcoding.shiny.service.ISpiderConfigService; 13 | import com.xkcoding.shiny.util.ShinyUtil; 14 | import lombok.extern.slf4j.Slf4j; 15 | import org.springframework.beans.factory.annotation.Autowired; 16 | import org.springframework.web.bind.annotation.*; 17 | 18 | import java.util.List; 19 | 20 | /** 21 | *22 | * 采集配置Controller 23 | *
24 | * 25 | * @package: com.xkcoding.shiny.controller 26 | * @description: 采集配置Controller 27 | * @author: yangkai.shen 28 | * @date: Created in 2018/8/15 下午8:33 29 | * @copyright: Copyright (c) 2018 30 | * @version: V1.0 31 | * @modified: yangkai.shen 32 | */ 33 | @RestController 34 | @RequestMapping("/api/spider/config") 35 | @Slf4j 36 | public class SpiderConfigController { 37 | private final ISpiderConfigService spiderConfigService; 38 | 39 | @Autowired 40 | public SpiderConfigController(ISpiderConfigService spiderConfigService) { 41 | this.spiderConfigService = spiderConfigService; 42 | } 43 | 44 | /** 45 | * 保存采集配置 46 | * 47 | * @param spiderConfigVO 采集配置 VO 48 | * @return 采集配置 DO 49 | * @throws ShinyException 参数异常 50 | */ 51 | @PostMapping("") 52 | public ApiResponse addConfig(@RequestBody SpiderConfigVO spiderConfigVO) throws ShinyException { 53 | if (ShinyUtil.isEmpty(spiderConfigVO, SpiderConfigVO.class)) { 54 | throw new ShinyException(Status.REQUEST_PARAMS_ERROR); 55 | } 56 | SpiderConfigDO spiderConfigDO = spiderConfigService.saveConfig(spiderConfigVO); 57 | return ApiResponse.ofSuccess(spiderConfigDO); 58 | } 59 | 60 | /** 61 | * 更新采集配置 62 | * 63 | * @param id 配置 id 64 | * @param spiderConfigVO 采集配置 VO 65 | * @return 采集配置 DO 66 | * @throws ShinyException 参数异常 67 | */ 68 | @PutMapping("/{id}") 69 | public ApiResponse updateConfig(@PathVariable Integer id, @RequestBody SpiderConfigVO spiderConfigVO) throws ShinyException { 70 | if (ShinyUtil.isEmpty(spiderConfigVO, SpiderConfigVO.class) || !ObjectUtil.equal(id, spiderConfigVO.getId())) { 71 | throw new ShinyException(Status.REQUEST_PARAMS_ERROR); 72 | } 73 | SpiderConfigDO spiderConfigDO = spiderConfigService.updateConfig(id, spiderConfigVO); 74 | return ApiResponse.ofSuccess(spiderConfigDO); 75 | } 76 | 77 | /** 78 | * 根据 id 删除采集配置 79 | * 80 | * @param id 配置 id 81 | * @throws ShinyException 参数异常 82 | */ 83 | @DeleteMapping("/{id}") 84 | public ApiResponse deleteConfig(@PathVariable Integer id) throws ShinyException { 85 | if (ObjectUtil.isNull(id)) { 86 | throw new ShinyException(Status.REQUEST_PARAMS_ERROR); 87 | } 88 | spiderConfigService.deleteConfig(id); 89 | return ApiResponse.ofSuccess(); 90 | } 91 | 92 | /** 93 | * 批量删除采集配置 94 | * 95 | * @param ids 配置 id 列表 96 | * @throws ShinyException 参数不能为空 97 | */ 98 | @DeleteMapping("") 99 | public ApiResponse deleteLogBatch(@RequestBody List21 | * 采集内容 Controller 22 | *
23 | * 24 | * @package: com.xkcoding.shiny.controller 25 | * @description: 采集内容 Controller 26 | * @author: yangkai.shen 27 | * @date: Created in 2018/9/3 下午9:38 28 | * @copyright: Copyright (c) 2018 29 | * @version: V1.0 30 | * @modified: yangkai.shen 31 | */ 32 | @RestController 33 | @RequestMapping("/api/spider/content") 34 | @Slf4j 35 | public class SpiderContentController { 36 | private final ISpiderContentService spiderContentService; 37 | 38 | @Autowired 39 | public SpiderContentController(ISpiderContentService spiderContentService) { 40 | this.spiderContentService = spiderContentService; 41 | } 42 | 43 | /** 44 | * 查看单个采集内容详情 45 | * 46 | * @param configId 采集配置id 47 | * @return 单个采集内容 48 | * @throws ShinyException 参数错误 49 | */ 50 | @GetMapping("/{configId}") 51 | public ApiResponse listSpiderContent(@PathVariable Integer configId, SpiderContentPageQuery query) throws ShinyException { 52 | if (ObjectUtil.isNull(configId)) { 53 | throw new ShinyException(Status.REQUEST_PARAMS_ERROR); 54 | } 55 | query = ShinyUtil.checkPageCondition(query, SpiderContentPageQuery.class); 56 | PageResult20 | * 采集 Controller 21 | *
22 | * 23 | * @package: com.xkcoding.shiny.controller 24 | * @description: 采集 Controller 25 | * @author: yangkai.shen 26 | * @date: Created in 2018/8/27 下午2:28 27 | * @copyright: Copyright (c) 2018 28 | * @version: V1.0 29 | * @modified: yangkai.shen 30 | */ 31 | @RestController 32 | @RequestMapping("/api/spider") 33 | @Slf4j 34 | public class SpiderController { 35 | private final ISpiderConfigService spiderConfigService; 36 | 37 | private final ISpiderContentService spiderContentService; 38 | 39 | private final ISpiderService spiderService; 40 | 41 | @Autowired 42 | public SpiderController(ISpiderConfigService spiderConfigService, ISpiderContentService spiderContentService, ISpiderService spiderService) { 43 | this.spiderConfigService = spiderConfigService; 44 | this.spiderContentService = spiderContentService; 45 | this.spiderService = spiderService; 46 | } 47 | 48 | /** 49 | * 重新爬取今天采集的所有软件信息 50 | */ 51 | @GetMapping("") 52 | public ApiResponse reSpiderAllToday() throws InterruptedException { 53 | // 删除所有今天采集的内容 54 | spiderContentService.deleteAllToday(); 55 | 56 | // 重新采集 57 | spiderService.reSpiderAllToday(); 58 | return ApiResponse.ofSuccess(); 59 | } 60 | 61 | /** 62 | * 重新爬取今天采集的某个软件信息 63 | */ 64 | @GetMapping("/{id}") 65 | public ApiResponse reSpiderToday(@PathVariable Integer id) throws ShinyException, InterruptedException { 66 | SpiderConfigDO spiderConfigDO = spiderConfigService.selectSpiderConfig(id); 67 | if (ObjectUtil.isNull(spiderConfigDO)) { 68 | throw new ShinyException(Status.CONFIG_NOT_EXIST); 69 | } 70 | 71 | // 删除当前配置 id 对应的今天采集的内容 72 | spiderContentService.deleteToday(id); 73 | 74 | // 重新采集 75 | spiderService.reSpiderToday(id); 76 | return ApiResponse.ofSuccess(); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/controller/SpiderLogController.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.controller; 2 | 3 | import cn.hutool.core.collection.CollUtil; 4 | import com.xkcoding.shiny.common.ApiResponse; 5 | import com.xkcoding.shiny.common.PageResult; 6 | import com.xkcoding.shiny.common.status.Status; 7 | import com.xkcoding.shiny.exception.ShinyException; 8 | import com.xkcoding.shiny.model.SpiderLogDO; 9 | import com.xkcoding.shiny.model.query.SpiderLogPageQuery; 10 | import com.xkcoding.shiny.service.ISpiderLogService; 11 | import com.xkcoding.shiny.util.ShinyUtil; 12 | import lombok.extern.slf4j.Slf4j; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.web.bind.annotation.*; 15 | 16 | import java.util.List; 17 | 18 | /** 19 | *20 | * 采集日志 Controller 21 | *
22 | * 23 | * @package: com.xkcoding.shiny.controller 24 | * @description: 采集日志 Controller 25 | * @author: yangkai.shen 26 | * @date: Created in 2018/8/29 下午9:09 27 | * @copyright: Copyright (c) 2018 28 | * @version: V1.0 29 | * @modified: yangkai.shen 30 | */ 31 | @RestController 32 | @RequestMapping("/api/spider/log") 33 | @Slf4j 34 | public class SpiderLogController { 35 | private final ISpiderLogService spiderLogService; 36 | 37 | @Autowired 38 | public SpiderLogController(ISpiderLogService spiderLogService) { 39 | this.spiderLogService = spiderLogService; 40 | } 41 | 42 | /** 43 | * 返回采集日志列表 44 | * 45 | * @param query 查询条件 46 | * @return 采集配置日志列表 47 | */ 48 | @GetMapping("") 49 | public ApiResponse listLog(SpiderLogPageQuery query) { 50 | query = ShinyUtil.checkPageCondition(query, SpiderLogPageQuery.class); 51 | PageResult8 | * 通用全局异常 9 | *
10 | * 11 | * @package: com.xkcoding.shiny.exception 12 | * @description: 通用全局异常 13 | * @author: yangkai.shen 14 | * @date: Created in 2018/8/15 下午8:39 15 | * @copyright: Copyright (c) 2018 16 | * @version: V1.0 17 | * @modified: yangkai.shen 18 | */ 19 | @Getter 20 | public class ShinyException extends Exception { 21 | /** 22 | * 异常码 23 | */ 24 | private Integer code; 25 | 26 | /** 27 | * 错误信息 28 | */ 29 | private String msg; 30 | 31 | /** 32 | * 返回内容 33 | */ 34 | private Object data; 35 | 36 | public ShinyException(Integer code, String msg) { 37 | super(msg); 38 | this.code = code; 39 | this.msg = msg; 40 | } 41 | 42 | public ShinyException(Integer code, String msg, Object data) { 43 | super(msg); 44 | this.code = code; 45 | this.msg = msg; 46 | this.data = data; 47 | } 48 | 49 | 50 | public ShinyException(String msg, Integer code, Object data) { 51 | super(msg); 52 | this.msg = msg; 53 | this.code = code; 54 | this.data = data; 55 | } 56 | 57 | public ShinyException(Status status) { 58 | super(status.getMsg()); 59 | this.code = status.getCode(); 60 | this.msg = status.getMsg(); 61 | } 62 | 63 | public ShinyException(Status status, Object data) { 64 | super(status.getMsg()); 65 | this.code = status.getCode(); 66 | this.msg = status.getMsg(); 67 | this.data = data; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/handler/GlobalExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.handler; 2 | 3 | import com.xkcoding.shiny.common.ApiResponse; 4 | import com.xkcoding.shiny.common.status.Status; 5 | import com.xkcoding.shiny.exception.ShinyException; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.http.converter.HttpMessageNotReadableException; 8 | import org.springframework.web.bind.MethodArgumentNotValidException; 9 | import org.springframework.web.bind.annotation.ControllerAdvice; 10 | import org.springframework.web.bind.annotation.ExceptionHandler; 11 | import org.springframework.web.bind.annotation.ResponseBody; 12 | import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; 13 | import org.springframework.web.servlet.NoHandlerFoundException; 14 | 15 | /** 16 | *17 | * 全局异常处理 18 | *
19 | * 20 | * @package: com.xkcoding.shiny.handler 21 | * @description: 全局异常处理 22 | * @author: yangkai.shen 23 | * @date: Created in 2018/8/15 下午8:40 24 | * @copyright: Copyright (c) 2018 25 | * @version: V1.0 26 | * @modified: yangkai.shen 27 | */ 28 | @Slf4j 29 | @ControllerAdvice 30 | public class GlobalExceptionHandler { 31 | 32 | @ExceptionHandler(value = Exception.class) 33 | @ResponseBody 34 | public ApiResponse handlerException(Exception e) { 35 | if (e instanceof NoHandlerFoundException) { 36 | log.error("【全局异常拦截】NoHandlerFoundException: 请求方法 {}, 请求路径 {}", ((NoHandlerFoundException) e).getRequestURL(), ((NoHandlerFoundException) e).getHttpMethod()); 37 | return ApiResponse.ofStatus(Status.REQUEST_NOT_FOUND); 38 | } else if (e instanceof MethodArgumentNotValidException) { 39 | log.error("【全局异常拦截】MethodArgumentNotValidException", e); 40 | return ApiResponse.ofStatus(Status.REQUEST_PARAMS_ERROR); 41 | } else if (e instanceof MethodArgumentTypeMismatchException) { 42 | log.error("【全局异常拦截】MethodArgumentTypeMismatchException: 参数名 {}, 异常信息 {}", ((MethodArgumentTypeMismatchException) e).getName(), ((MethodArgumentTypeMismatchException) e).getMessage()); 43 | return ApiResponse.ofStatus(Status.REQUEST_PARAMS_ERROR); 44 | } else if (e instanceof HttpMessageNotReadableException) { 45 | log.error("【全局异常拦截】HttpMessageNotReadableException: 错误信息 {}", ((HttpMessageNotReadableException) e).getMessage()); 46 | return ApiResponse.ofStatus(Status.REQUEST_PARAMS_ERROR); 47 | } else if (e instanceof ShinyException) { 48 | log.error("【全局异常拦截】ShinyException: 状态码 {}, 异常信息 {}", ((ShinyException) e).getCode(), e.getMessage()); 49 | return new ApiResponse(((ShinyException) e).getCode(), e.getMessage(), ((ShinyException) e).getData()); 50 | } 51 | log.error("【全局异常拦截】: 异常信息 {} ", e.getMessage()); 52 | return ApiResponse.ofStatus(Status.INTERNAL_SERVER_ERROR); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/mapper/EmailLogMapper.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.mapper; 2 | 3 | import com.xkcoding.shiny.common.MyMapper; 4 | import com.xkcoding.shiny.model.EmailLogDO; 5 | import org.springframework.stereotype.Component; 6 | 7 | /** 8 | *9 | * 邮件记录 Mapper 10 | *
11 | * 12 | * @package: com.xkcoding.shiny.mapper 13 | * @description: 邮件记录 Mapper 14 | * @author: yangkai.shen 15 | * @date: Created in 2018/9/9 下午2:57 16 | * @copyright: Copyright (c) 2018 17 | * @version: V1.0 18 | * @modified: yangkai.shen 19 | */ 20 | @Component 21 | public interface EmailLogMapper extends MyMapper12 | * 采集参数配置Mapper类 13 | *
14 | * 15 | * @package: com.xkcoding.shiny.mapper 16 | * @description: 采集参数配置Mapper类 17 | * @author: yangkai.shen 18 | * @date: Created in 2018/8/15 下午6:45 19 | * @copyright: Copyright (c) 2018 20 | * @version: V1.0 21 | * @modified: yangkai.shen 22 | */ 23 | @Component 24 | public interface SpiderConfigMapper extends MyMapper13 | * 采集内容Mapper类 14 | *
15 | * 16 | * @package: com.xkcoding.shiny.mapper 17 | * @description: 采集内容Mapper类 18 | * @author: yangkai.shen 19 | * @date: Created in 2018/8/15 下午6:45 20 | * @copyright: Copyright (c) 2018 21 | * @version: V1.0 22 | * @modified: yangkai.shen 23 | */ 24 | @Component 25 | public interface SpiderContentMapper extends MyMapper12 | * 采集日志Mapper类 13 | *
14 | * 15 | * @package: com.xkcoding.shiny.mapper 16 | * @description: 采集日志Mapper类 17 | * @author: yangkai.shen 18 | * @date: Created in 2018/8/15 下午6:47 19 | * @copyright: Copyright (c) 2018 20 | * @version: V1.0 21 | * @modified: yangkai.shen 22 | */ 23 | @Component 24 | public interface SpiderLogMapper extends MyMapper9 | * 系统参数配置Mapper类 10 | *
11 | * 12 | * @package: com.xkcoding.shiny.mapper 13 | * @description: 系统参数配置Mapper类 14 | * @author: yangkai.shen 15 | * @date: Created in 2018/8/15 下午6:46 16 | * @copyright: Copyright (c) 2018 17 | * @version: V1.0 18 | * @modified: yangkai.shen 19 | */ 20 | @Component 21 | public interface SysConfigMapper extends MyMapper9 | * 系统角色Mapper类 10 | *
11 | * 12 | * @package: com.xkcoding.shiny.mapper 13 | * @description: 系统角色Mapper类 14 | * @author: yangkai.shen 15 | * @date: Created in 2018/8/15 下午6:46 16 | * @copyright: Copyright (c) 2018 17 | * @version: V1.0 18 | * @modified: yangkai.shen 19 | */ 20 | @Component 21 | public interface SysRoleMapper extends MyMapper9 | * 系统用户Mapper类 10 | *
11 | * 12 | * @package: com.xkcoding.shiny.mapper 13 | * @description: 系统用户Mapper类 14 | * @author: yangkai.shen 15 | * @date: Created in 2018/8/15 下午6:49 16 | * @copyright: Copyright (c) 2018 17 | * @version: V1.0 18 | * @modified: yangkai.shen 19 | */ 20 | @Component 21 | public interface SysUserMapper extends MyMapper9 | * 系统用户-角色关联关系Mapper类 10 | *
11 | * 12 | * @package: com.xkcoding.shiny.mapper 13 | * @description: 系统用户-角色关联关系Mapper类 14 | * @author: yangkai.shen 15 | * @date: Created in 2018/8/15 下午6:50 16 | * @copyright: Copyright (c) 2018 17 | * @version: V1.0 18 | * @modified: yangkai.shen 19 | */ 20 | @Component 21 | public interface SysUserRoleMapper extends MyMapper13 | * 邮件记录 DO 14 | *
15 | * 16 | * @package: com.xkcoding.shiny.model 17 | * @description: 邮件记录 DO 18 | * @author: yangkai.shen 19 | * @date: Created in 2018/9/9 下午2:56 20 | * @copyright: Copyright (c) 2018 21 | * @version: V1.0 22 | * @modified: yangkai.shen 23 | */ 24 | @Data 25 | @Table(name = "email_log") 26 | public class EmailLogDO { 27 | /** 28 | * 邮件主键 29 | */ 30 | @Id 31 | @Column(name = "id") 32 | @GeneratedValue(generator = "JDBC") 33 | private Integer id; 34 | 35 | /** 36 | * 邮件主题 37 | */ 38 | @Column(name = "subject") 39 | private String subject; 40 | 41 | /** 42 | * 是否是模板邮件(0否 1是) 43 | */ 44 | @Column(name = "is_template") 45 | private Integer isTemplate; 46 | 47 | /** 48 | * 模板路径 49 | */ 50 | @Column(name = "template_path") 51 | private String templatePath; 52 | 53 | /** 54 | * 模板名称 55 | */ 56 | @Column(name = "template_name") 57 | private String templateName; 58 | 59 | /** 60 | * 邮件发送时间 61 | */ 62 | @Column(name = "send_time") 63 | private Date sendTime; 64 | 65 | /** 66 | * 收件人邮箱地址(多个逗号分隔) 67 | */ 68 | @Column(name = "to") 69 | private String to; 70 | 71 | /** 72 | * 邮件内容 73 | */ 74 | @Column(name = "content") 75 | private String content; 76 | 77 | /** 78 | * 获取邮件主键 79 | * 80 | * @return id - 邮件主键 81 | */ 82 | public Integer getId() { 83 | return id; 84 | } 85 | 86 | /** 87 | * 设置邮件主键 88 | * 89 | * @param id 邮件主键 90 | */ 91 | public void setId(Integer id) { 92 | this.id = id; 93 | } 94 | 95 | /** 96 | * 获取邮件主题 97 | * 98 | * @return subject - 邮件主题 99 | */ 100 | public String getSubject() { 101 | return subject; 102 | } 103 | 104 | /** 105 | * 设置邮件主题 106 | * 107 | * @param subject 邮件主题 108 | */ 109 | public void setSubject(String subject) { 110 | this.subject = subject; 111 | } 112 | 113 | /** 114 | * 获取是否是模板邮件(0否 1是) 115 | * 116 | * @return is_template - 是否是模板邮件(0否 1是) 117 | */ 118 | public Integer getIsTemplate() { 119 | return isTemplate; 120 | } 121 | 122 | /** 123 | * 设置是否是模板邮件(0否 1是) 124 | * 125 | * @param isTemplate 是否是模板邮件(0否 1是) 126 | */ 127 | public void setIsTemplate(Integer isTemplate) { 128 | this.isTemplate = isTemplate; 129 | } 130 | 131 | /** 132 | * 获取模板路径 133 | * 134 | * @return template_path - 模板路径 135 | */ 136 | public String getTemplatePath() { 137 | return templatePath; 138 | } 139 | 140 | /** 141 | * 设置模板路径 142 | * 143 | * @param templatePath 模板路径 144 | */ 145 | public void setTemplatePath(String templatePath) { 146 | this.templatePath = templatePath; 147 | } 148 | 149 | /** 150 | * 获取模板名称 151 | * 152 | * @return template_name - 模板名称 153 | */ 154 | public String getTemplateName() { 155 | return templateName; 156 | } 157 | 158 | /** 159 | * 设置模板名称 160 | * 161 | * @param templateName 模板名称 162 | */ 163 | public void setTemplateName(String templateName) { 164 | this.templateName = templateName; 165 | } 166 | 167 | /** 168 | * 获取邮件发送时间 169 | * 170 | * @return send_time - 邮件发送时间 171 | */ 172 | public Date getSendTime() { 173 | return sendTime; 174 | } 175 | 176 | /** 177 | * 设置邮件发送时间 178 | * 179 | * @param sendTime 邮件发送时间 180 | */ 181 | public void setSendTime(Date sendTime) { 182 | this.sendTime = sendTime; 183 | } 184 | 185 | /** 186 | * 获取收件人邮箱地址(多个逗号分隔) 187 | * 188 | * @return to - 收件人邮箱地址(多个逗号分隔) 189 | */ 190 | public String getTo() { 191 | return to; 192 | } 193 | 194 | /** 195 | * 设置收件人邮箱地址(多个逗号分隔) 196 | * 197 | * @param to 收件人邮箱地址(多个逗号分隔) 198 | */ 199 | public void setTo(String to) { 200 | this.to = to; 201 | } 202 | 203 | /** 204 | * 获取邮件内容 205 | * 206 | * @return content - 邮件内容 207 | */ 208 | public String getContent() { 209 | return content; 210 | } 211 | 212 | /** 213 | * 设置邮件内容 214 | * 215 | * @param content 邮件内容 216 | */ 217 | public void setContent(String content) { 218 | this.content = content; 219 | } 220 | } -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/model/SpiderConfigDO.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.model; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import javax.persistence.Column; 9 | import javax.persistence.GeneratedValue; 10 | import javax.persistence.Id; 11 | import javax.persistence.Table; 12 | import java.util.Date; 13 | 14 | /** 15 | *16 | * 采集配置 17 | *
18 | * 19 | * @package: com.xkcoding.shiny.model 20 | * @description: 采集配置 21 | * @author: yangkai.shen 22 | * @date: Created in 2018/8/15 下午6:50 23 | * @copyright: Copyright (c) 2018 24 | * @version: V1.0 25 | * @modified: yangkai.shen 26 | */ 27 | @Table(name = "spider_config") 28 | @Data 29 | @Builder 30 | @NoArgsConstructor 31 | @AllArgsConstructor 32 | public class SpiderConfigDO { 33 | /** 34 | * 配置主键 35 | */ 36 | @Id 37 | @Column(name = "id") 38 | @GeneratedValue(generator = "JDBC") 39 | private Integer id; 40 | 41 | /** 42 | * 采集名称 43 | */ 44 | @Column(name = "spider_name") 45 | private String spiderName; 46 | 47 | /** 48 | * 采集URL 49 | */ 50 | @Column(name = "spider_url") 51 | private String spiderUrl; 52 | 53 | /** 54 | * 上次采集时间 55 | */ 56 | @Column(name = "last_spider_time") 57 | private Date lastSpiderTime; 58 | 59 | /** 60 | * 创建者 61 | */ 62 | @Column(name = "create_by") 63 | private String createBy; 64 | 65 | /** 66 | * 创建时间 67 | */ 68 | @Column(name = "create_time") 69 | private Date createTime; 70 | 71 | /** 72 | * 更新者 73 | */ 74 | @Column(name = "update_by") 75 | private String updateBy; 76 | 77 | /** 78 | * 更新时间 79 | */ 80 | @Column(name = "update_time") 81 | private Date updateTime; 82 | 83 | /** 84 | * 备注 85 | */ 86 | @Column(name = "remark") 87 | private String remark; 88 | 89 | /** 90 | * 获取配置主键 91 | * 92 | * @return id - 配置主键 93 | */ 94 | public Integer getId() { 95 | return id; 96 | } 97 | 98 | /** 99 | * 设置配置主键 100 | * 101 | * @param id 配置主键 102 | */ 103 | public void setId(Integer id) { 104 | this.id = id; 105 | } 106 | 107 | /** 108 | * 获取采集名称 109 | * 110 | * @return spider_name - 采集名称 111 | */ 112 | public String getSpiderName() { 113 | return spiderName; 114 | } 115 | 116 | /** 117 | * 设置采集名称 118 | * 119 | * @param spiderName 采集名称 120 | */ 121 | public void setSpiderName(String spiderName) { 122 | this.spiderName = spiderName; 123 | } 124 | 125 | /** 126 | * 获取采集URL 127 | * 128 | * @return spider_url - 采集URL 129 | */ 130 | public String getSpiderUrl() { 131 | return spiderUrl; 132 | } 133 | 134 | /** 135 | * 设置采集URL 136 | * 137 | * @param spiderUrl 采集URL 138 | */ 139 | public void setSpiderUrl(String spiderUrl) { 140 | this.spiderUrl = spiderUrl; 141 | } 142 | 143 | /** 144 | * 获取上次采集时间 145 | * 146 | * @return last_spider_time - 上次采集时间 147 | */ 148 | public Date getLastSpiderTime() { 149 | return lastSpiderTime; 150 | } 151 | 152 | /** 153 | * 设置上次采集时间 154 | * 155 | * @param lastSpiderTime 上次采集时间 156 | */ 157 | public void setLastSpiderTime(Date lastSpiderTime) { 158 | this.lastSpiderTime = lastSpiderTime; 159 | } 160 | 161 | /** 162 | * 获取创建者 163 | * 164 | * @return create_by - 创建者 165 | */ 166 | public String getCreateBy() { 167 | return createBy; 168 | } 169 | 170 | /** 171 | * 设置创建者 172 | * 173 | * @param createBy 创建者 174 | */ 175 | public void setCreateBy(String createBy) { 176 | this.createBy = createBy; 177 | } 178 | 179 | /** 180 | * 获取创建时间 181 | * 182 | * @return create_time - 创建时间 183 | */ 184 | public Date getCreateTime() { 185 | return createTime; 186 | } 187 | 188 | /** 189 | * 设置创建时间 190 | * 191 | * @param createTime 创建时间 192 | */ 193 | public void setCreateTime(Date createTime) { 194 | this.createTime = createTime; 195 | } 196 | 197 | /** 198 | * 获取更新者 199 | * 200 | * @return update_by - 更新者 201 | */ 202 | public String getUpdateBy() { 203 | return updateBy; 204 | } 205 | 206 | /** 207 | * 设置更新者 208 | * 209 | * @param updateBy 更新者 210 | */ 211 | public void setUpdateBy(String updateBy) { 212 | this.updateBy = updateBy; 213 | } 214 | 215 | /** 216 | * 获取更新时间 217 | * 218 | * @return update_time - 更新时间 219 | */ 220 | public Date getUpdateTime() { 221 | return updateTime; 222 | } 223 | 224 | /** 225 | * 设置更新时间 226 | * 227 | * @param updateTime 更新时间 228 | */ 229 | public void setUpdateTime(Date updateTime) { 230 | this.updateTime = updateTime; 231 | } 232 | 233 | /** 234 | * 获取备注 235 | * 236 | * @return remark - 备注 237 | */ 238 | public String getRemark() { 239 | return remark; 240 | } 241 | 242 | /** 243 | * 设置备注 244 | * 245 | * @param remark 备注 246 | */ 247 | public void setRemark(String remark) { 248 | this.remark = remark; 249 | } 250 | } -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/model/SpiderContentDO.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.model; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import javax.persistence.Column; 9 | import javax.persistence.GeneratedValue; 10 | import javax.persistence.Id; 11 | import javax.persistence.Table; 12 | import java.util.Date; 13 | 14 | /** 15 | *16 | * 采集内容 17 | *
18 | * 19 | * @package: com.xkcoding.shiny.model 20 | * @description: 采集内容 21 | * @author: yangkai.shen 22 | * @date: Created in 2018/8/15 下午6:51 23 | * @copyright: Copyright (c) 2018 24 | * @version: V1.0 25 | * @modified: yangkai.shen 26 | */ 27 | @Table(name = "spider_content") 28 | @Builder 29 | @Data 30 | @NoArgsConstructor 31 | @AllArgsConstructor 32 | public class SpiderContentDO { 33 | /** 34 | * 内容主键 35 | */ 36 | @Id 37 | @Column(name = "id") 38 | @GeneratedValue(generator = "JDBC") 39 | private Integer id; 40 | 41 | /** 42 | * 采集配置id 43 | */ 44 | @Column(name = "config_id") 45 | private Integer configId; 46 | 47 | /** 48 | * 采集配置名称 49 | */ 50 | @Column(name = "config_name") 51 | private String configName; 52 | 53 | /** 54 | * 软件名称 55 | */ 56 | @Column(name = "title") 57 | private String title; 58 | 59 | /** 60 | * 软件版本 61 | */ 62 | @Column(name = "version") 63 | private String version; 64 | 65 | /** 66 | * 软件语言 67 | */ 68 | @Column(name = "language") 69 | private String language; 70 | 71 | /** 72 | * 软件更新时间 73 | */ 74 | @Column(name = "update_time") 75 | private Date updateTime; 76 | 77 | /** 78 | * 软件大小 79 | */ 80 | @Column(name = "size") 81 | private String size; 82 | 83 | /** 84 | * 城通网盘链接 85 | */ 86 | @Column(name = "ct_pan_url") 87 | private String ctPanUrl; 88 | 89 | /** 90 | * 城通网盘提取码 91 | */ 92 | @Column(name = "ct_pan_code") 93 | private String ctPanCode; 94 | 95 | /** 96 | * 百度网盘链接 97 | */ 98 | @Column(name = "bd_pan_url") 99 | private String bdPanUrl; 100 | 101 | /** 102 | * 百度网盘提取码 103 | */ 104 | @Column(name = "bd_pan_code") 105 | private String bdPanCode; 106 | 107 | /** 108 | * 采集时间 109 | */ 110 | @Column(name = "spider_time") 111 | private Date spiderTime; 112 | 113 | /** 114 | * 软件详细信息 115 | */ 116 | @Column(name = "content") 117 | private String content; 118 | 119 | /** 120 | * 获取内容主键 121 | * 122 | * @return id - 内容主键 123 | */ 124 | public Integer getId() { 125 | return id; 126 | } 127 | 128 | /** 129 | * 设置内容主键 130 | * 131 | * @param id 内容主键 132 | */ 133 | public void setId(Integer id) { 134 | this.id = id; 135 | } 136 | 137 | /** 138 | * 获取采集配置id 139 | * 140 | * @return config_id - 采集配置id 141 | */ 142 | public Integer getConfigId() { 143 | return configId; 144 | } 145 | 146 | /** 147 | * 设置采集配置id 148 | * 149 | * @param configId 采集配置id 150 | */ 151 | public void setConfigId(Integer configId) { 152 | this.configId = configId; 153 | } 154 | 155 | /** 156 | * 获取采集配置名称 157 | * 158 | * @return config_name - 采集配置名称 159 | */ 160 | public String getConfigName() { 161 | return configName; 162 | } 163 | 164 | /** 165 | * 设置采集配置名称 166 | * 167 | * @param configName 采集配置名称 168 | */ 169 | public void setConfigName(String configName) { 170 | this.configName = configName; 171 | } 172 | 173 | /** 174 | * 获取软件名称 175 | * 176 | * @return title - 软件名称 177 | */ 178 | public String getTitle() { 179 | return title; 180 | } 181 | 182 | /** 183 | * 设置软件名称 184 | * 185 | * @param title 软件名称 186 | */ 187 | public void setTitle(String title) { 188 | this.title = title; 189 | } 190 | 191 | /** 192 | * 获取软件版本 193 | * 194 | * @return version - 软件版本 195 | */ 196 | public String getVersion() { 197 | return version; 198 | } 199 | 200 | /** 201 | * 设置软件版本 202 | * 203 | * @param version 软件版本 204 | */ 205 | public void setVersion(String version) { 206 | this.version = version; 207 | } 208 | 209 | /** 210 | * 获取软件语言 211 | * 212 | * @return language - 软件语言 213 | */ 214 | public String getLanguage() { 215 | return language; 216 | } 217 | 218 | /** 219 | * 设置软件语言 220 | * 221 | * @param language 软件语言 222 | */ 223 | public void setLanguage(String language) { 224 | this.language = language; 225 | } 226 | 227 | /** 228 | * 获取软件更新时间 229 | * 230 | * @return update_time - 软件更新时间 231 | */ 232 | public Date getUpdateTime() { 233 | return updateTime; 234 | } 235 | 236 | /** 237 | * 设置软件更新时间 238 | * 239 | * @param updateTime 软件更新时间 240 | */ 241 | public void setUpdateTime(Date updateTime) { 242 | this.updateTime = updateTime; 243 | } 244 | 245 | /** 246 | * 获取软件大小 247 | * 248 | * @return size - 软件大小 249 | */ 250 | public String getSize() { 251 | return size; 252 | } 253 | 254 | /** 255 | * 设置软件大小 256 | * 257 | * @param size 软件大小 258 | */ 259 | public void setSize(String size) { 260 | this.size = size; 261 | } 262 | 263 | /** 264 | * 获取城通网盘链接 265 | * 266 | * @return ct_pan_url - 城通网盘链接 267 | */ 268 | public String getCtPanUrl() { 269 | return ctPanUrl; 270 | } 271 | 272 | /** 273 | * 设置城通网盘链接 274 | * 275 | * @param ctPanUrl 城通网盘链接 276 | */ 277 | public void setCtPanUrl(String ctPanUrl) { 278 | this.ctPanUrl = ctPanUrl; 279 | } 280 | 281 | /** 282 | * 获取城通网盘提取码 283 | * 284 | * @return ct_pan_code - 城通网盘提取码 285 | */ 286 | public String getCtPanCode() { 287 | return ctPanCode; 288 | } 289 | 290 | /** 291 | * 设置城通网盘提取码 292 | * 293 | * @param ctPanCode 城通网盘提取码 294 | */ 295 | public void setCtPanCode(String ctPanCode) { 296 | this.ctPanCode = ctPanCode; 297 | } 298 | 299 | /** 300 | * 获取百度网盘链接 301 | * 302 | * @return bd_pan_url - 百度网盘链接 303 | */ 304 | public String getBdPanUrl() { 305 | return bdPanUrl; 306 | } 307 | 308 | /** 309 | * 设置百度网盘链接 310 | * 311 | * @param bdPanUrl 百度网盘链接 312 | */ 313 | public void setBdPanUrl(String bdPanUrl) { 314 | this.bdPanUrl = bdPanUrl; 315 | } 316 | 317 | /** 318 | * 获取百度网盘提取码 319 | * 320 | * @return bd_pan_code - 百度网盘提取码 321 | */ 322 | public String getBdPanCode() { 323 | return bdPanCode; 324 | } 325 | 326 | /** 327 | * 设置百度网盘提取码 328 | * 329 | * @param bdPanCode 百度网盘提取码 330 | */ 331 | public void setBdPanCode(String bdPanCode) { 332 | this.bdPanCode = bdPanCode; 333 | } 334 | 335 | /** 336 | * 获取采集时间 337 | * 338 | * @return spider_time - 采集时间 339 | */ 340 | public Date getSpiderTime() { 341 | return spiderTime; 342 | } 343 | 344 | /** 345 | * 设置采集时间 346 | * 347 | * @param spiderTime 采集时间 348 | */ 349 | public void setSpiderTime(Date spiderTime) { 350 | this.spiderTime = spiderTime; 351 | } 352 | 353 | /** 354 | * 获取软件详细信息 355 | * 356 | * @return content - 软件详细信息 357 | */ 358 | public String getContent() { 359 | return content; 360 | } 361 | 362 | /** 363 | * 设置软件详细信息 364 | * 365 | * @param content 软件详细信息 366 | */ 367 | public void setContent(String content) { 368 | this.content = content; 369 | } 370 | } -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/model/SpiderLogDO.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.model; 2 | 3 | import lombok.Data; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.GeneratedValue; 7 | import javax.persistence.Id; 8 | import javax.persistence.Table; 9 | import java.util.Date; 10 | 11 | /** 12 | *13 | * 采集日志 14 | *
15 | * 16 | * @package: com.xkcoding.shiny.model 17 | * @description: 采集日志 18 | * @author: yangkai.shen 19 | * @date: Created in 2018/8/15 下午6:51 20 | * @copyright: Copyright (c) 2018 21 | * @version: V1.0 22 | * @modified: yangkai.shen 23 | */ 24 | @Table(name = "spider_log") 25 | @Data 26 | public class SpiderLogDO { 27 | /** 28 | * 日志主键 29 | */ 30 | @Id 31 | @Column(name = "id") 32 | @GeneratedValue(generator = "JDBC") 33 | private Integer id; 34 | 35 | /** 36 | * 采集配置id 37 | */ 38 | @Column(name = "config_id") 39 | private Integer configId; 40 | 41 | /** 42 | * 采集名称 43 | */ 44 | @Column(name = "spider_name") 45 | private String spiderName; 46 | 47 | /** 48 | * 采集版本 49 | */ 50 | @Column(name = "version") 51 | private String version; 52 | 53 | /** 54 | * 采集URL 55 | */ 56 | @Column(name = "spider_url") 57 | private String spiderUrl; 58 | 59 | /** 60 | * 采集状态(0异常 1正常) 61 | */ 62 | @Column(name = "status") 63 | private Integer status; 64 | 65 | /** 66 | * 错误消息 67 | */ 68 | @Column(name = "error_msg") 69 | private String errorMsg; 70 | 71 | /** 72 | * 采集时间 73 | */ 74 | @Column(name = "spider_time") 75 | private Date spiderTime; 76 | 77 | /** 78 | * 获取日志主键 79 | * 80 | * @return id - 日志主键 81 | */ 82 | public Integer getId() { 83 | return id; 84 | } 85 | 86 | /** 87 | * 设置日志主键 88 | * 89 | * @param id 日志主键 90 | */ 91 | public void setId(Integer id) { 92 | this.id = id; 93 | } 94 | 95 | /** 96 | * 获取采集名称 97 | * 98 | * @return spider_name - 采集名称 99 | */ 100 | public String getSpiderName() { 101 | return spiderName; 102 | } 103 | 104 | /** 105 | * 设置采集名称 106 | * 107 | * @param spiderName 采集名称 108 | */ 109 | public void setSpiderName(String spiderName) { 110 | this.spiderName = spiderName; 111 | } 112 | 113 | /** 114 | * 获取采集版本 115 | * 116 | * @return version - 采集版本 117 | */ 118 | public String getVersion() { 119 | return version; 120 | } 121 | 122 | /** 123 | * 设置采集版本 124 | * 125 | * @param version 采集版本 126 | */ 127 | public void setVersion(String version) { 128 | this.version = version; 129 | } 130 | 131 | /** 132 | * 获取采集URL 133 | * 134 | * @return spider_url - 采集URL 135 | */ 136 | public String getSpiderUrl() { 137 | return spiderUrl; 138 | } 139 | 140 | /** 141 | * 设置采集URL 142 | * 143 | * @param spiderUrl 采集URL 144 | */ 145 | public void setSpiderUrl(String spiderUrl) { 146 | this.spiderUrl = spiderUrl; 147 | } 148 | 149 | /** 150 | * 获取采集状态(0异常 1正常) 151 | * 152 | * @return status - 采集状态(0异常 1正常) 153 | */ 154 | public Integer getStatus() { 155 | return status; 156 | } 157 | 158 | /** 159 | * 设置采集状态(0异常 1正常) 160 | * 161 | * @param status 采集状态(0异常 1正常) 162 | */ 163 | public void setStatus(Integer status) { 164 | this.status = status; 165 | } 166 | 167 | /** 168 | * 获取错误消息 169 | * 170 | * @return error_msg - 错误消息 171 | */ 172 | public String getErrorMsg() { 173 | return errorMsg; 174 | } 175 | 176 | /** 177 | * 设置错误消息 178 | * 179 | * @param errorMsg 错误消息 180 | */ 181 | public void setErrorMsg(String errorMsg) { 182 | this.errorMsg = errorMsg; 183 | } 184 | 185 | /** 186 | * 获取采集时间 187 | * 188 | * @return spider_time - 采集时间 189 | */ 190 | public Date getSpiderTime() { 191 | return spiderTime; 192 | } 193 | 194 | /** 195 | * 设置采集时间 196 | * 197 | * @param spiderTime 采集时间 198 | */ 199 | public void setSpiderTime(Date spiderTime) { 200 | this.spiderTime = spiderTime; 201 | } 202 | } -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/model/SysConfigDO.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.model; 2 | 3 | import lombok.Data; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.GeneratedValue; 7 | import javax.persistence.Id; 8 | import javax.persistence.Table; 9 | import java.util.Date; 10 | 11 | /** 12 | *13 | * 系统配置 14 | *
15 | * 16 | * @package: com.xkcoding.shiny.model 17 | * @description: 系统配置 18 | * @author: yangkai.shen 19 | * @date: Created in 2018/8/15 下午6:51 20 | * @copyright: Copyright (c) 2018 21 | * @version: V1.0 22 | * @modified: yangkai.shen 23 | */ 24 | @Table(name = "sys_config") 25 | @Data 26 | public class SysConfigDO { 27 | /** 28 | * 参数主键 29 | */ 30 | @Id 31 | @Column(name = "id") 32 | @GeneratedValue(generator = "JDBC") 33 | private Integer id; 34 | 35 | /** 36 | * 参数名称 37 | */ 38 | @Column(name = "config_name") 39 | private String configName; 40 | 41 | /** 42 | * 参数键名 43 | */ 44 | @Column(name = "config_key") 45 | private String configKey; 46 | 47 | /** 48 | * 参数键值 49 | */ 50 | @Column(name = "config_value") 51 | private String configValue; 52 | 53 | /** 54 | * 系统内置(0否 1是) 55 | */ 56 | @Column(name = "config_type") 57 | private Integer configType; 58 | 59 | /** 60 | * 创建者 61 | */ 62 | @Column(name = "create_by") 63 | private String createBy; 64 | 65 | /** 66 | * 创建时间 67 | */ 68 | @Column(name = "create_time") 69 | private Date createTime; 70 | 71 | /** 72 | * 更新者 73 | */ 74 | @Column(name = "update_by") 75 | private String updateBy; 76 | 77 | /** 78 | * 更新时间 79 | */ 80 | @Column(name = "update_time") 81 | private Date updateTime; 82 | 83 | /** 84 | * 备注 85 | */ 86 | @Column(name = "remark") 87 | private String remark; 88 | 89 | /** 90 | * 获取参数主键 91 | * 92 | * @return id - 参数主键 93 | */ 94 | public Integer getId() { 95 | return id; 96 | } 97 | 98 | /** 99 | * 设置参数主键 100 | * 101 | * @param id 参数主键 102 | */ 103 | public void setId(Integer id) { 104 | this.id = id; 105 | } 106 | 107 | /** 108 | * 获取参数名称 109 | * 110 | * @return config_name - 参数名称 111 | */ 112 | public String getConfigName() { 113 | return configName; 114 | } 115 | 116 | /** 117 | * 设置参数名称 118 | * 119 | * @param configName 参数名称 120 | */ 121 | public void setConfigName(String configName) { 122 | this.configName = configName; 123 | } 124 | 125 | /** 126 | * 获取参数键名 127 | * 128 | * @return config_key - 参数键名 129 | */ 130 | public String getConfigKey() { 131 | return configKey; 132 | } 133 | 134 | /** 135 | * 设置参数键名 136 | * 137 | * @param configKey 参数键名 138 | */ 139 | public void setConfigKey(String configKey) { 140 | this.configKey = configKey; 141 | } 142 | 143 | /** 144 | * 获取参数键值 145 | * 146 | * @return config_value - 参数键值 147 | */ 148 | public String getConfigValue() { 149 | return configValue; 150 | } 151 | 152 | /** 153 | * 设置参数键值 154 | * 155 | * @param configValue 参数键值 156 | */ 157 | public void setConfigValue(String configValue) { 158 | this.configValue = configValue; 159 | } 160 | 161 | /** 162 | * 获取系统内置(0否 1是) 163 | * 164 | * @return config_type - 系统内置(0否 1是) 165 | */ 166 | public Integer getConfigType() { 167 | return configType; 168 | } 169 | 170 | /** 171 | * 设置系统内置(0否 1是) 172 | * 173 | * @param configType 系统内置(0否 1是) 174 | */ 175 | public void setConfigType(Integer configType) { 176 | this.configType = configType; 177 | } 178 | 179 | /** 180 | * 获取创建者 181 | * 182 | * @return create_by - 创建者 183 | */ 184 | public String getCreateBy() { 185 | return createBy; 186 | } 187 | 188 | /** 189 | * 设置创建者 190 | * 191 | * @param createBy 创建者 192 | */ 193 | public void setCreateBy(String createBy) { 194 | this.createBy = createBy; 195 | } 196 | 197 | /** 198 | * 获取创建时间 199 | * 200 | * @return create_time - 创建时间 201 | */ 202 | public Date getCreateTime() { 203 | return createTime; 204 | } 205 | 206 | /** 207 | * 设置创建时间 208 | * 209 | * @param createTime 创建时间 210 | */ 211 | public void setCreateTime(Date createTime) { 212 | this.createTime = createTime; 213 | } 214 | 215 | /** 216 | * 获取更新者 217 | * 218 | * @return update_by - 更新者 219 | */ 220 | public String getUpdateBy() { 221 | return updateBy; 222 | } 223 | 224 | /** 225 | * 设置更新者 226 | * 227 | * @param updateBy 更新者 228 | */ 229 | public void setUpdateBy(String updateBy) { 230 | this.updateBy = updateBy; 231 | } 232 | 233 | /** 234 | * 获取更新时间 235 | * 236 | * @return update_time - 更新时间 237 | */ 238 | public Date getUpdateTime() { 239 | return updateTime; 240 | } 241 | 242 | /** 243 | * 设置更新时间 244 | * 245 | * @param updateTime 更新时间 246 | */ 247 | public void setUpdateTime(Date updateTime) { 248 | this.updateTime = updateTime; 249 | } 250 | 251 | /** 252 | * 获取备注 253 | * 254 | * @return remark - 备注 255 | */ 256 | public String getRemark() { 257 | return remark; 258 | } 259 | 260 | /** 261 | * 设置备注 262 | * 263 | * @param remark 备注 264 | */ 265 | public void setRemark(String remark) { 266 | this.remark = remark; 267 | } 268 | } -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/model/SysRoleDO.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.model; 2 | 3 | import lombok.Data; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.GeneratedValue; 7 | import javax.persistence.Id; 8 | import javax.persistence.Table; 9 | import java.util.Date; 10 | 11 | /** 12 | *13 | * 系统角色 14 | *
15 | * 16 | * @package: com.xkcoding.shiny.model 17 | * @description: 系统角色 18 | * @author: yangkai.shen 19 | * @date: Created in 2018/8/15 下午6:51 20 | * @copyright: Copyright (c) 2018 21 | * @version: V1.0 22 | * @modified: yangkai.shen 23 | */ 24 | @Table(name = "sys_role") 25 | @Data 26 | public class SysRoleDO { 27 | /** 28 | * 角色ID 29 | */ 30 | @Id 31 | @Column(name = "id") 32 | @GeneratedValue(generator = "JDBC") 33 | private Integer id; 34 | 35 | /** 36 | * 角色名称 37 | */ 38 | @Column(name = "role_name") 39 | private String roleName; 40 | 41 | /** 42 | * 角色权限字符串 43 | */ 44 | @Column(name = "role_key") 45 | private String roleKey; 46 | 47 | /** 48 | * 显示顺序 49 | */ 50 | @Column(name = "role_sort") 51 | private Integer roleSort; 52 | 53 | /** 54 | * 角色状态(0停用 1正常) 55 | */ 56 | @Column(name = "status") 57 | private Integer status; 58 | 59 | /** 60 | * 创建者 61 | */ 62 | @Column(name = "create_by") 63 | private String createBy; 64 | 65 | /** 66 | * 创建时间 67 | */ 68 | @Column(name = "create_time") 69 | private Date createTime; 70 | 71 | /** 72 | * 更新者 73 | */ 74 | @Column(name = "update_by") 75 | private String updateBy; 76 | 77 | /** 78 | * 更新时间 79 | */ 80 | @Column(name = "update_time") 81 | private Date updateTime; 82 | 83 | /** 84 | * 备注 85 | */ 86 | @Column(name = "remark") 87 | private String remark; 88 | 89 | /** 90 | * 获取角色ID 91 | * 92 | * @return id - 角色ID 93 | */ 94 | public Integer getId() { 95 | return id; 96 | } 97 | 98 | /** 99 | * 设置角色ID 100 | * 101 | * @param id 角色ID 102 | */ 103 | public void setId(Integer id) { 104 | this.id = id; 105 | } 106 | 107 | /** 108 | * 获取角色名称 109 | * 110 | * @return role_name - 角色名称 111 | */ 112 | public String getRoleName() { 113 | return roleName; 114 | } 115 | 116 | /** 117 | * 设置角色名称 118 | * 119 | * @param roleName 角色名称 120 | */ 121 | public void setRoleName(String roleName) { 122 | this.roleName = roleName; 123 | } 124 | 125 | /** 126 | * 获取角色权限字符串 127 | * 128 | * @return role_key - 角色权限字符串 129 | */ 130 | public String getRoleKey() { 131 | return roleKey; 132 | } 133 | 134 | /** 135 | * 设置角色权限字符串 136 | * 137 | * @param roleKey 角色权限字符串 138 | */ 139 | public void setRoleKey(String roleKey) { 140 | this.roleKey = roleKey; 141 | } 142 | 143 | /** 144 | * 获取显示顺序 145 | * 146 | * @return role_sort - 显示顺序 147 | */ 148 | public Integer getRoleSort() { 149 | return roleSort; 150 | } 151 | 152 | /** 153 | * 设置显示顺序 154 | * 155 | * @param roleSort 显示顺序 156 | */ 157 | public void setRoleSort(Integer roleSort) { 158 | this.roleSort = roleSort; 159 | } 160 | 161 | /** 162 | * 获取角色状态(0停用 1正常) 163 | * 164 | * @return status - 角色状态(0停用 1正常) 165 | */ 166 | public Integer getStatus() { 167 | return status; 168 | } 169 | 170 | /** 171 | * 设置角色状态(0停用 1正常) 172 | * 173 | * @param status 角色状态(0停用 1正常) 174 | */ 175 | public void setStatus(Integer status) { 176 | this.status = status; 177 | } 178 | 179 | /** 180 | * 获取创建者 181 | * 182 | * @return create_by - 创建者 183 | */ 184 | public String getCreateBy() { 185 | return createBy; 186 | } 187 | 188 | /** 189 | * 设置创建者 190 | * 191 | * @param createBy 创建者 192 | */ 193 | public void setCreateBy(String createBy) { 194 | this.createBy = createBy; 195 | } 196 | 197 | /** 198 | * 获取创建时间 199 | * 200 | * @return create_time - 创建时间 201 | */ 202 | public Date getCreateTime() { 203 | return createTime; 204 | } 205 | 206 | /** 207 | * 设置创建时间 208 | * 209 | * @param createTime 创建时间 210 | */ 211 | public void setCreateTime(Date createTime) { 212 | this.createTime = createTime; 213 | } 214 | 215 | /** 216 | * 获取更新者 217 | * 218 | * @return update_by - 更新者 219 | */ 220 | public String getUpdateBy() { 221 | return updateBy; 222 | } 223 | 224 | /** 225 | * 设置更新者 226 | * 227 | * @param updateBy 更新者 228 | */ 229 | public void setUpdateBy(String updateBy) { 230 | this.updateBy = updateBy; 231 | } 232 | 233 | /** 234 | * 获取更新时间 235 | * 236 | * @return update_time - 更新时间 237 | */ 238 | public Date getUpdateTime() { 239 | return updateTime; 240 | } 241 | 242 | /** 243 | * 设置更新时间 244 | * 245 | * @param updateTime 更新时间 246 | */ 247 | public void setUpdateTime(Date updateTime) { 248 | this.updateTime = updateTime; 249 | } 250 | 251 | /** 252 | * 获取备注 253 | * 254 | * @return remark - 备注 255 | */ 256 | public String getRemark() { 257 | return remark; 258 | } 259 | 260 | /** 261 | * 设置备注 262 | * 263 | * @param remark 备注 264 | */ 265 | public void setRemark(String remark) { 266 | this.remark = remark; 267 | } 268 | } -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/model/SysUserRoleDO.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.model; 2 | 3 | import lombok.Data; 4 | 5 | import javax.persistence.Column; 6 | import javax.persistence.Id; 7 | import javax.persistence.Table; 8 | 9 | /** 10 | *11 | * 系统用户角色 12 | *
13 | * 14 | * @package: com.xkcoding.shiny.model 15 | * @description: 系统用户角色 16 | * @author: yangkai.shen 17 | * @date: Created in 2018/8/15 下午6:51 18 | * @copyright: Copyright (c) 2018 19 | * @version: V1.0 20 | * @modified: yangkai.shen 21 | */ 22 | @Table(name = "sys_user_role") 23 | @Data 24 | public class SysUserRoleDO { 25 | /** 26 | * 用户ID 27 | */ 28 | @Id 29 | @Column(name = "user_id") 30 | private Integer userId; 31 | 32 | /** 33 | * 角色ID 34 | */ 35 | @Id 36 | @Column(name = "role_id") 37 | private Integer roleId; 38 | 39 | /** 40 | * 获取用户ID 41 | * 42 | * @return user_id - 用户ID 43 | */ 44 | public Integer getUserId() { 45 | return userId; 46 | } 47 | 48 | /** 49 | * 设置用户ID 50 | * 51 | * @param userId 用户ID 52 | */ 53 | public void setUserId(Integer userId) { 54 | this.userId = userId; 55 | } 56 | 57 | /** 58 | * 获取角色ID 59 | * 60 | * @return role_id - 角色ID 61 | */ 62 | public Integer getRoleId() { 63 | return roleId; 64 | } 65 | 66 | /** 67 | * 设置角色ID 68 | * 69 | * @param roleId 角色ID 70 | */ 71 | public void setRoleId(Integer roleId) { 72 | this.roleId = roleId; 73 | } 74 | } -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/model/query/SpiderConfigPageQuery.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.model.query; 2 | 3 | import com.xkcoding.shiny.model.query.base.PageCondition; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | 7 | /** 8 | *9 | * 采集配置查询条件 10 | *
11 | * 12 | * @package: com.xkcoding.shiny.model.query 13 | * @description: 采集配置查询条件 14 | * @author: yangkai.shen 15 | * @date: Created in 2018/8/15 下午10:10 16 | * @copyright: Copyright (c) 2018 17 | * @version: V1.0 18 | * @modified: yangkai.shen 19 | */ 20 | @Data 21 | @EqualsAndHashCode(callSuper = true) 22 | public class SpiderConfigPageQuery extends PageCondition { 23 | /** 24 | * 采集配置名称 / 采集配置备注 25 | */ 26 | private String text; 27 | } 28 | -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/model/query/SpiderContentPageQuery.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.model.query; 2 | 3 | import com.xkcoding.shiny.model.query.base.PageCondition; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | 7 | /** 8 | *9 | * 采集内容查询条件 10 | *
11 | * 12 | * @package: com.xkcoding.shiny.model.query 13 | * @description: 采集内容查询条件 14 | * @author: yangkai.shen 15 | * @date: Created in 2018/9/3 下午9:56 16 | * @copyright: Copyright (c) 2018 17 | * @version: V1.0 18 | * @modified: yangkai.shen 19 | */ 20 | @Data 21 | @EqualsAndHashCode(callSuper = true) 22 | public class SpiderContentPageQuery extends PageCondition { 23 | /** 24 | * 采集配置名称 25 | */ 26 | private String configName; 27 | 28 | /** 29 | * 软件名称 30 | */ 31 | private String title; 32 | 33 | /** 34 | * 软件描述内容 35 | */ 36 | private String content; 37 | 38 | /** 39 | * 软件版本 40 | */ 41 | private String version; 42 | 43 | /** 44 | * 软件语言 45 | */ 46 | private String language; 47 | 48 | /** 49 | * 软件更新日期 50 | */ 51 | private String updateTime; 52 | 53 | /** 54 | * 采集时间 55 | */ 56 | private String spiderTime; 57 | } 58 | -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/model/query/SpiderLogPageQuery.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.model.query; 2 | 3 | import com.xkcoding.shiny.model.query.base.PageCondition; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | 7 | /** 8 | *9 | * 采集日志查询条件 10 | *
11 | * 12 | * @package: com.xkcoding.shiny.model.query 13 | * @description: 采集日志查询条件 14 | * @author: yangkai.shen 15 | * @date: Created in 2018/8/29 下午9:11 16 | * @copyright: Copyright (c) 2018 17 | * @version: V1.0 18 | * @modified: yangkai.shen 19 | */ 20 | @Data 21 | @EqualsAndHashCode(callSuper = true) 22 | public class SpiderLogPageQuery extends PageCondition { 23 | /** 24 | * 采集名称 25 | */ 26 | private String spiderName; 27 | 28 | /** 29 | * 采集版本 30 | */ 31 | private String version; 32 | 33 | /** 34 | * 采集状态(0异常 1正常) 35 | */ 36 | private Integer status; 37 | 38 | /** 39 | * 错误消息 40 | */ 41 | private String errorMsg; 42 | 43 | /** 44 | * 采集时间 - 起始时间 45 | */ 46 | private String startTime; 47 | 48 | /** 49 | * 采集时间 - 结束时间 50 | */ 51 | private String endTime; 52 | } -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/model/query/base/PageCondition.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.model.query.base; 2 | 3 | import lombok.Data; 4 | 5 | import javax.validation.constraints.Pattern; 6 | 7 | /** 8 | *9 | * 分页基本条件 10 | *
11 | * 12 | * @package: com.xkcoding.shiny.model.query.base 13 | * @description: 分页基本条件 14 | * @author: yangkai.shen 15 | * @date: Created in 2018/8/15 下午10:08 16 | * @copyright: Copyright (c) 2018 17 | * @version: V1.0 18 | * @modified: yangkai.shen 19 | */ 20 | @Data 21 | public class PageCondition { 22 | /** 23 | * 当前页 24 | */ 25 | private Integer currentPage; 26 | 27 | /** 28 | * 每页条数 29 | */ 30 | private Integer pageSize; 31 | } 32 | -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/model/vo/SpiderConfigVO.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.model.vo; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.util.Date; 7 | 8 | /** 9 | *10 | * 采集配置VO 11 | *
12 | * 13 | * @package: com.xkcoding.shiny.model.vo 14 | * @description: 采集配置VO 15 | * @author: yangkai.shen 16 | * @date: Created in 2018/8/15 下午9:51 17 | * @copyright: Copyright (c) 2018 18 | * @version: V1.0 19 | * @modified: yangkai.shen 20 | */ 21 | @Data 22 | public class SpiderConfigVO implements Serializable { 23 | /** 24 | * 配置主键 25 | */ 26 | private Integer id; 27 | 28 | /** 29 | * 采集名称 30 | */ 31 | private String spiderName; 32 | 33 | /** 34 | * 采集URL 35 | */ 36 | private String spiderUrl; 37 | 38 | /** 39 | * 上次采集时间 40 | */ 41 | private Date lastSpiderTime; 42 | 43 | /** 44 | * 创建者 45 | */ 46 | private String createBy; 47 | 48 | /** 49 | * 创建时间 50 | */ 51 | private Date createTime; 52 | 53 | /** 54 | * 更新者 55 | */ 56 | private String updateBy; 57 | 58 | /** 59 | * 更新时间 60 | */ 61 | private Date updateTime; 62 | 63 | /** 64 | * 备注 65 | */ 66 | private String remark; 67 | } 68 | -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/model/vo/SpiderContentVO.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.model.vo; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | import java.io.Serializable; 9 | import java.util.Date; 10 | 11 | /** 12 | *13 | * 采集内容VO 14 | *
15 | * 16 | * @package: com.xkcoding.shiny.model.vo 17 | * @description: 采集内容VO 18 | * @author: yangkai.shen 19 | * @date: Created in 2018/9/3 下午9:46 20 | * @copyright: Copyright (c) 2018 21 | * @version: V1.0 22 | * @modified: yangkai.shen 23 | */ 24 | @Builder 25 | @Data 26 | @NoArgsConstructor 27 | @AllArgsConstructor 28 | public class SpiderContentVO implements Serializable { 29 | 30 | private static final long serialVersionUID = 1230401625684294310L; 31 | /** 32 | * 内容主键 33 | */ 34 | private Integer id; 35 | 36 | /** 37 | * 采集配置id 38 | */ 39 | private Integer configId; 40 | 41 | /** 42 | * 采集配置名称 43 | */ 44 | private String configName; 45 | 46 | /** 47 | * 软件名称 48 | */ 49 | private String title; 50 | 51 | /** 52 | * 软件版本 53 | */ 54 | private String version; 55 | 56 | /** 57 | * 软件语言 58 | */ 59 | private String language; 60 | 61 | /** 62 | * 软件更新时间 63 | */ 64 | private Date updateTime; 65 | 66 | /** 67 | * 软件大小 68 | */ 69 | private String size; 70 | 71 | /** 72 | * 城通网盘链接 73 | */ 74 | private String ctPanUrl; 75 | 76 | /** 77 | * 城通网盘提取码 78 | */ 79 | private String ctPanCode; 80 | 81 | /** 82 | * 百度网盘链接 83 | */ 84 | private String bdPanUrl; 85 | 86 | /** 87 | * 百度网盘提取码 88 | */ 89 | private String bdPanCode; 90 | 91 | /** 92 | * 采集时间 93 | */ 94 | private Date spiderTime; 95 | 96 | /** 97 | * 软件详细信息 98 | */ 99 | private String content; 100 | 101 | } -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/service/IMailService.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.service; 2 | 3 | import javax.mail.MessagingException; 4 | import java.util.Map; 5 | 6 | /** 7 | *8 | * 邮件接口 9 | *
10 | * 11 | * @package: com.xkcoding.shiny.service 12 | * @description: 邮件接口 13 | * @author: yangkai.shen 14 | * @date: Created in 2018/9/5 下午10:37 15 | * @copyright: Copyright (c) 2018 16 | * @version: V1.0 17 | * @modified: yangkai.shen 18 | */ 19 | public interface IMailService { 20 | 21 | /** 22 | * 发送简单邮件 23 | * 24 | * @param to 收件人 25 | * @param subject 邮件主题 26 | * @param content 邮件内容 27 | */ 28 | void sendSimpleMail(String to, String subject, String content); 29 | 30 | /** 31 | * 发送简单 HTML 邮件 32 | * 33 | * @param to 收件人 34 | * @param subject 邮件主题 35 | * @param html HTML 内容 36 | */ 37 | void sendHtmlMail(String to, String subject, String html); 38 | 39 | /** 40 | * 发送 HTML 模板邮件 41 | * 42 | * @param to 收件人 43 | * @param subject 邮件主题 44 | * @param params 模板参数 45 | * @param templatePath 模板路径 46 | * @param templateName 模板名称 47 | */ 48 | void sendHtmlTemplateMail(String to, String subject, Map13 | * 采集配置Service接口 14 | *
15 | * 16 | * @package: com.xkcoding.shiny.service 17 | * @description: 采集配置Service接口 18 | * @author: yangkai.shen 19 | * @date: Created in 2018/8/15 下午9:48 20 | * @copyright: Copyright (c) 2018 21 | * @version: V1.0 22 | * @modified: yangkai.shen 23 | */ 24 | public interface ISpiderConfigService { 25 | 26 | /** 27 | * 分页采集配置列表 28 | * 29 | * @param query 查询条件 30 | * @return 分页采集配置列表信息 31 | */ 32 | PageResult13 | * 采集内容接口 14 | *
15 | * 16 | * @package: com.xkcoding.shiny.service 17 | * @description: 采集内容接口 18 | * @author: yangkai.shen 19 | * @date: Created in 2018/8/27 下午9:48 20 | * @copyright: Copyright (c) 2018 21 | * @version: V1.0 22 | * @modified: yangkai.shen 23 | */ 24 | public interface ISpiderContentService { 25 | /** 26 | * 删除今天采集的所有软件信息 27 | */ 28 | void deleteAllToday(); 29 | 30 | /** 31 | * 删除今天采集的某个软件信息 32 | * 33 | * @param configId 采集配置 id 34 | */ 35 | void deleteToday(Integer configId); 36 | 37 | /** 38 | * 查看单个软件的采集信息 39 | * 40 | * @param configId 配置id 41 | * @param query 查询条件 42 | * @return 分页信息 43 | * @throws ShinyException 采集配置不存在 44 | */ 45 | PageResult11 | * 采集日志服务接口 12 | *
13 | * 14 | * @package: com.xkcoding.shiny.service 15 | * @description: 采集日志服务接口 16 | * @author: yangkai.shen 17 | * @date: Created in 2018/8/28 下午8:54 18 | * @copyright: Copyright (c) 2018 19 | * @version: V1.0 20 | * @modified: yangkai.shen 21 | */ 22 | public interface ISpiderLogService { 23 | /** 24 | * 保存采集日志 25 | * 26 | * @param spiderLogDO 采集日志 DO 27 | */ 28 | void saveSpiderLog(SpiderLogDO spiderLogDO); 29 | 30 | /** 31 | * 采集日志列表 32 | * 33 | * @param query 查询条件 34 | * @return 采集日志列表 35 | */ 36 | PageResult9 | * 爬虫接口 10 | *
11 | * 12 | * @package: com.xkcoding.shiny.service 13 | * @description: 爬虫接口 14 | * @author: yangkai.shen 15 | * @date: Created in 2018/8/27 下午6:35 16 | * @copyright: Copyright (c) 2018 17 | * @version: V1.0 18 | * @modified: yangkai.shen 19 | */ 20 | public interface ISpiderService { 21 | /** 22 | * 根据配置列表采集信息 23 | * 24 | * @param configDOList 采集配置列表 25 | */ 26 | void spider(List19 | * 邮件接口实现 20 | *
21 | * 22 | * @package: com.xkcoding.shiny.service.impl 23 | * @description: 邮件接口实现 24 | * @author: yangkai.shen 25 | * @date: Created in 2018/9/6 下午8:56 26 | * @copyright: Copyright (c) 2018 27 | * @version: V1.0 28 | * @modified: yangkai.shen 29 | */ 30 | @Service 31 | @Slf4j 32 | public class MailServiceImpl implements IMailService { 33 | private final JavaMailSender mailSender; 34 | 35 | private final ShinyProperties shinyProperties; 36 | 37 | @Autowired 38 | public MailServiceImpl(JavaMailSender mailSender, ShinyProperties shinyProperties) { 39 | this.mailSender = mailSender; 40 | this.shinyProperties = shinyProperties; 41 | } 42 | 43 | /** 44 | * 发送简单邮件 45 | * 46 | * @param to 收件人 47 | * @param subject 邮件主题 48 | * @param content 邮件内容 49 | */ 50 | @Override 51 | public void sendSimpleMail(String to, String subject, String content) { 52 | 53 | } 54 | 55 | /** 56 | * 发送简单 HTML 邮件 57 | * 58 | * @param to 收件人 59 | * @param subject 邮件主题 60 | * @param html HTML 内容 61 | */ 62 | @Override 63 | public void sendHtmlMail(String to, String subject, String html) { 64 | 65 | } 66 | 67 | /** 68 | * 发送 HTML 模板邮件 69 | * 70 | * @param to 收件人 71 | * @param subject 邮件主题 72 | * @param params 模板参数 73 | * @param templatePath 模板路径 74 | * @param templateName 模板名称 75 | */ 76 | @Override 77 | public void sendHtmlTemplateMail(String to, String subject, Map26 | * 采集配置Service接口实现 27 | *
28 | * 29 | * @package: com.xkcoding.shiny.service.impl 30 | * @description: 采集配置Service接口实现 31 | * @author: yangkai.shen 32 | * @date: Created in 2018/8/15 下午10:02 33 | * @copyright: Copyright (c) 2018 34 | * @version: V1.0 35 | * @modified: yangkai.shen 36 | */ 37 | @Service 38 | public class SpiderConfigServiceImpl implements ISpiderConfigService { 39 | private final SpiderConfigMapper spiderConfigMapper; 40 | 41 | private final ModelMapper modelMapper; 42 | 43 | @Autowired 44 | public SpiderConfigServiceImpl(SpiderConfigMapper spiderConfigMapper, ModelMapper modelMapper) { 45 | this.spiderConfigMapper = spiderConfigMapper; 46 | this.modelMapper = modelMapper; 47 | } 48 | 49 | /** 50 | * 分页采集配置列表 51 | * 52 | * @param query 查询条件 53 | * @return 分页采集配置列表信息 54 | */ 55 | @Override 56 | public PageResult28 | * 采集内容接口实现 29 | *
30 | * 31 | * @package: com.xkcoding.shiny.service.impl 32 | * @description: 采集内容接口实现 33 | * @author: yangkai.shen 34 | * @date: Created in 2018/8/27 下午9:50 35 | * @copyright: Copyright (c) 2018 36 | * @version: V1.0 37 | * @modified: yangkai.shen 38 | */ 39 | @Service 40 | @Slf4j 41 | public class SpiderContentServiceImpl implements ISpiderContentService { 42 | private final SpiderContentMapper spiderContentMapper; 43 | 44 | private final SpiderConfigMapper spiderConfigMapper; 45 | 46 | private final ModelMapper modelMapper; 47 | 48 | @Autowired 49 | public SpiderContentServiceImpl(SpiderContentMapper spiderContentMapper, SpiderConfigMapper spiderConfigMapper, ModelMapper modelMapper) { 50 | this.spiderContentMapper = spiderContentMapper; 51 | this.spiderConfigMapper = spiderConfigMapper; 52 | this.modelMapper = modelMapper; 53 | } 54 | 55 | /** 56 | * 删除今天采集的所有软件信息 57 | */ 58 | @Override 59 | public void deleteAllToday() { 60 | SpiderContentDO query = SpiderContentDO.builder().spiderTime(DateUtil.parseDate(DateUtil.today())).build(); 61 | int delete = spiderContentMapper.delete(query); 62 | log.info("【删除采集内容】已删除 {} 条采集日期为 {} 的软件信息", delete, DateUtil.parseDate(DateUtil.today())); 63 | } 64 | 65 | /** 66 | * 删除今天采集的某个软件信息 67 | * 68 | * @param configId 采集配置 id 69 | */ 70 | @Override 71 | public void deleteToday(Integer configId) { 72 | SpiderContentDO query = SpiderContentDO.builder().configId(configId).spiderTime(DateUtil.parseDate(DateUtil.today())).build(); 73 | int delete = spiderContentMapper.delete(query); 74 | log.info("【删除采集内容】已删除 {} 条,配置 id 为 {} 并且采集日期为 {} 的软件信息", delete, configId, DateUtil.parseDate(DateUtil.today())); 75 | } 76 | 77 | /** 78 | * 查看单个软件的采集信息 79 | * 80 | * @param configId 配置id 81 | * @param query 查询条件 82 | * @return 分页信息 83 | * @throws ShinyException 采集配置不存在 84 | */ 85 | @Override 86 | public PageResult21 | * 采集日志接口实现 22 | *
23 | * 24 | * @package: com.xkcoding.shiny.service.impl 25 | * @description: 采集日志接口实现 26 | * @author: yangkai.shen 27 | * @date: Created in 2018/8/28 下午8:55 28 | * @copyright: Copyright (c) 2018 29 | * @version: V1.0 30 | * @modified: yangkai.shen 31 | */ 32 | @Service 33 | @Slf4j 34 | public class SpiderLogServiceImpl implements ISpiderLogService { 35 | private final SpiderLogMapper spiderLogMapper; 36 | 37 | @Autowired 38 | public SpiderLogServiceImpl(SpiderLogMapper spiderLogMapper) { 39 | this.spiderLogMapper = spiderLogMapper; 40 | } 41 | 42 | /** 43 | * 保存采集日志 44 | * 45 | * @param spiderLogDO 采集日志 DO 46 | */ 47 | @Async("asyncExecutor") 48 | @Override 49 | public void saveSpiderLog(SpiderLogDO spiderLogDO) { 50 | spiderLogMapper.insertUseGeneratedKeys(spiderLogDO); 51 | } 52 | 53 | /** 54 | * 采集日志列表 55 | * 56 | * @param query 查询条件 57 | * @return 采集日志列表 58 | */ 59 | @Override 60 | public PageResult20 | * 爬虫接口实现 21 | *
22 | * 23 | * @package: com.xkcoding.shiny.service.impl 24 | * @description: 爬虫接口实现 25 | * @author: yangkai.shen 26 | * @date: Created in 2018/8/27 下午6:36 27 | * @copyright: Copyright (c) 2018 28 | * @version: V1.0 29 | * @modified: yangkai.shen 30 | */ 31 | @Service 32 | @Slf4j 33 | public class SpiderServiceImpl implements ISpiderService { 34 | private final SpiderConfigMapper spiderConfigMapper; 35 | 36 | private final ShinyProperties shinyProperties; 37 | 38 | @Autowired 39 | public SpiderServiceImpl(SpiderConfigMapper spiderConfigMapper, ShinyProperties shinyProperties) { 40 | this.spiderConfigMapper = spiderConfigMapper; 41 | this.shinyProperties = shinyProperties; 42 | } 43 | 44 | /** 45 | * 根据配置列表采集信息 46 | * 47 | * @param configDOList 采集配置列表 48 | */ 49 | @Override 50 | public void spider(List18 | * 通知任务 19 | *
20 | * 21 | * @package: com.xkcoding.shiny.task 22 | * @description: 通知任务 23 | * @author: yangkai.shen 24 | * @date: Created in 2018/9/4 下午8:18 25 | * @copyright: Copyright (c) 2018 26 | * @version: V1.0 27 | * @modified: yangkai.shen 28 | */ 29 | @Component 30 | @Slf4j 31 | public class NotificationTask { 32 | private final ISpiderContentService spiderContentService; 33 | 34 | private final StringRedisTemplate stringRedisTemplate; 35 | 36 | @Autowired 37 | public NotificationTask(ISpiderContentService spiderContentService, StringRedisTemplate stringRedisTemplate) { 38 | this.spiderContentService = spiderContentService; 39 | this.stringRedisTemplate = stringRedisTemplate; 40 | } 41 | 42 | /** 43 | * 每天早晨9点执行一次 44 | */ 45 | @Scheduled(cron = "0 0 9 1/1 1/1 ?") 46 | public void notification() { 47 | log.info("【定时任务】检查今天采集的软件版本更新情况......"); 48 | boolean hasUpdate = checkContent(); 49 | log.info("【定时任务】今天采集的软件版本更新情况,检查完成,{}", hasUpdate ? "软件有更新,邮件已发送" : "软件近两天无更新"); 50 | } 51 | 52 | /** 53 | * 检查采集内容 54 | * 55 | * @return 是否存在更新 56 | */ 57 | private boolean checkContent() { 58 | List15 | * 定时采集任务 16 | *
17 | * 18 | * @package: com.xkcoding.shiny.task 19 | * @description: 定时采集任务 20 | * @author: yangkai.shen 21 | * @date: Created in 2018/8/22 下午9:58 22 | * @copyright: Copyright (c) 2018 23 | * @version: V1.0 24 | * @modified: yangkai.shen 25 | */ 26 | @Component 27 | @Slf4j 28 | public class SpiderTask { 29 | private final SpiderConfigMapper spiderConfigMapper; 30 | 31 | private final ISpiderService spiderService; 32 | 33 | @Autowired 34 | public SpiderTask(SpiderConfigMapper spiderConfigMapper, ISpiderService spiderService) { 35 | this.spiderConfigMapper = spiderConfigMapper; 36 | this.spiderService = spiderService; 37 | } 38 | 39 | /** 40 | * 每天凌晨2点执行一次 41 | */ 42 | @Scheduled(cron = "0 0 2 1/1 1/1 ?") 43 | public void spider() throws InterruptedException { 44 | log.info("【定时任务】开始采集软件信息......"); 45 | // 获取所有软件名称-采集页面配置 46 | List11 | * 采集任务管理器 12 | *
13 | * 14 | * @package: com.xkcoding.shiny.task 15 | * @description: 采集任务管理器 16 | * @author: yangkai.shen 17 | * @date: Created in 2018/8/22 下午9:46 18 | * @copyright: Copyright (c) 2018 19 | * @version: V1.0 20 | * @modified: yangkai.shen 21 | */ 22 | public class SpiderTaskManager { 23 | /** 24 | * 采集操作延时 25 | */ 26 | private static final int SPIDER_DELAY_TIME = 2000; 27 | 28 | /** 29 | * 异步操作采集的线程池 30 | */ 31 | private ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(50, new BasicThreadFactory.Builder().namingPattern("Spider-Thread-%d").build()); 32 | 33 | private SpiderTaskManager() { 34 | } 35 | 36 | private static SpiderTaskManager manager = new SpiderTaskManager(); 37 | 38 | public static SpiderTaskManager me() { 39 | return manager; 40 | } 41 | 42 | public void execute(TimerTask task) { 43 | executor.schedule(task, SPIDER_DELAY_TIME, TimeUnit.MILLISECONDS); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/util/DriverUtil.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.util; 2 | 3 | import com.xkcoding.shiny.common.property.ShinyProperties; 4 | import org.openqa.selenium.chrome.ChromeDriver; 5 | import org.openqa.selenium.phantomjs.PhantomJSDriver; 6 | import org.openqa.selenium.phantomjs.PhantomJSDriverService; 7 | import org.openqa.selenium.remote.DesiredCapabilities; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.stereotype.Component; 10 | 11 | import java.io.File; 12 | 13 | /** 14 | *15 | * DriverUtil 工具类 16 | *
17 | * 18 | * @package: com.xkcoding.shiny.util 19 | * @description: DriverUtil 工具类 20 | * @author: yangkai.shen 21 | * @date: Created in 2018/8/25 下午1:48 22 | * @copyright: Copyright (c) 2018 23 | * @version: V1.0 24 | * @modified: yangkai.shen 25 | */ 26 | @Component 27 | public class DriverUtil { 28 | @Autowired 29 | private ShinyProperties shinyProperties; 30 | 31 | /** 32 | * 获取 ChromeDriver 驱动 33 | * 34 | * @return ChromeDriver 驱动 35 | */ 36 | public ChromeDriver getChromeDriver() { 37 | System.setProperty("webdriver.chrome.driver", getChromeDriverPath()); 38 | 39 | return new ChromeDriver(); 40 | } 41 | 42 | /** 43 | * 获取适合本机系统的 ChromeDriver 路径 44 | * 45 | * @return ChromeDriver 路径 46 | */ 47 | private String getChromeDriverPath() { 48 | if (ShinyUtil.isMac()) { 49 | return shinyProperties.getDriverPath() + File.separator + "chrome-driver/macos/chromedriver"; 50 | } else if (ShinyUtil.isLinux()) { 51 | return shinyProperties.getDriverPath() + File.separator + "chrome-driver/linux/chromedriver"; 52 | } else { 53 | return shinyProperties.getDriverPath() + File.separator + "chrome-driver/windows/chromedriver.exe"; 54 | } 55 | } 56 | 57 | /** 58 | * 获取 PhantomJs 驱动 59 | * 60 | * @return PhantomJs 驱动 61 | */ 62 | public PhantomJSDriver getPhantomJSDriver() { 63 | //设置必要参数 64 | DesiredCapabilities capabilities = new DesiredCapabilities(); 65 | //ssl证书支持 66 | capabilities.setCapability("acceptSslCerts", true); 67 | //截屏支持 68 | capabilities.setCapability("takesScreenshot", false); 69 | //css搜索支持 70 | capabilities.setCapability("cssSelectorsEnabled", true); 71 | //js支持 72 | capabilities.setJavascriptEnabled(true); 73 | //驱动支持 74 | capabilities.setCapability(PhantomJSDriverService.PHANTOMJS_EXECUTABLE_PATH_PROPERTY, getPhantomJsPath()); 75 | 76 | return new PhantomJSDriver(capabilities); 77 | } 78 | 79 | /** 80 | * 获取适合本机系统的 PhantomJs 路径 81 | * 82 | * @return PhantomJs 路径 83 | */ 84 | private String getPhantomJsPath() { 85 | if (ShinyUtil.isMac()) { 86 | return shinyProperties.getDriverPath() + File.separator + "phantomjs/macos/phantomjs"; 87 | } else if (ShinyUtil.isLinux()) { 88 | return shinyProperties.getDriverPath() + File.separator + "phantomjs/linux/X64/phantomjs"; 89 | } else { 90 | return shinyProperties.getDriverPath() + File.separator + "phantomjs/windows/phantomjs.exe"; 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /back/src/main/java/com/xkcoding/shiny/util/ShinyUtil.java: -------------------------------------------------------------------------------- 1 | package com.xkcoding.shiny.util; 2 | 3 | import cn.hutool.core.util.ObjectUtil; 4 | import cn.hutool.core.util.ReflectUtil; 5 | import cn.hutool.system.SystemUtil; 6 | import com.xkcoding.shiny.common.ShinyConst; 7 | import com.xkcoding.shiny.model.query.base.PageCondition; 8 | 9 | import java.lang.reflect.Field; 10 | import java.lang.reflect.Method; 11 | import java.util.Date; 12 | 13 | /** 14 | *15 | * Shiny常用工具类 16 | *
17 | * 18 | * @package: com.xkcoding.shiny.util 19 | * @description: Shiny常用工具类 20 | * @author: yangkai.shen 21 | * @date: Created in 2018/8/15 下午10:06 22 | * @copyright: Copyright (c) 2018 23 | * @version: V1.0 24 | * @modified: yangkai.shen 25 | */ 26 | public class ShinyUtil { 27 | 28 | /** 29 | * 校验分页参数,为NULL,设置分页参数默认值 30 | * 31 | * @param condition 查询参数 32 | * @param clazz 类 33 | * @paramtrue
是 false
否
53 | */
54 | static Boolean isMac() {
55 | return SystemUtil.getOsInfo().isMac() || SystemUtil.getOsInfo().isMacOsX();
56 | }
57 |
58 | /**
59 | * 是否是 Linux 系统
60 | *
61 | * @return true
是 false
否
62 | */
63 | static Boolean isLinux() {
64 | return SystemUtil.getOsInfo().isLinux();
65 | }
66 |
67 | /**
68 | * 是否是 Windows 系统
69 | *
70 | * @return true
是 false
否
71 | */
72 | public static Boolean isWindows() {
73 | return SystemUtil.getOsInfo().isWindows();
74 | }
75 |
76 | /**
77 | * 判断对象是否为空对象,属性都为null
78 | *
79 | * @param object 对象
80 | * @param clazz 对象类型
81 | * @return 是否为空,true
- 空 / false
- 非空
82 | */
83 | public static Boolean isEmpty(Object object, Class clazz) {
84 | if (ObjectUtil.isNull(object)) {
85 | return true;
86 | }
87 | Field[] fields = ReflectUtil.getFields(clazz);
88 | for (Field field : fields) {
89 | Object fieldValue = ReflectUtil.getFieldValue(object, field);
90 | if (ObjectUtil.isNotNull(fieldValue)) {
91 | return false;
92 | }
93 | }
94 | return true;
95 | }
96 |
97 | /**
98 | * 插入前操作
99 | *
100 | * @param obj 对象
101 | * @param clazz 对象类型
102 | * @param override 是否覆盖属性
103 | */
104 | public static void beforeInsert(Object obj, Class clazz, boolean override) {
105 | Method setCreateBy = ReflectUtil.getMethod(clazz, "setCreateBy");
106 | Method getCreateBy = ReflectUtil.getMethod(clazz, "getCreateBy");
107 | Method setCreateTime = ReflectUtil.getMethod(clazz, "setCreateTime");
108 | Method getCreateTime = ReflectUtil.getMethod(clazz, "getCreateTime");
109 |
110 | if (setCreateBy != null) {
111 | if (override || ObjectUtil.isNull(ReflectUtil.invoke(obj, getCreateBy))) {
112 | ReflectUtil.invoke(obj, setCreateBy, "管理员");
113 | }
114 | }
115 | if (setCreateTime != null) {
116 | if (override || ObjectUtil.isNull(ReflectUtil.invoke(obj, getCreateTime))) {
117 | ReflectUtil.invoke(obj, setCreateTime, new Date());
118 | }
119 | }
120 |
121 | beforeUpdate(obj, clazz, override);
122 | }
123 |
124 | /**
125 | * 更新前操作
126 | *
127 | * @param obj 对象
128 | * @param clazz 对象类型
129 | * @param override 是否覆盖属性
130 | */
131 | public static void beforeUpdate(Object obj, Class clazz, boolean override) {
132 | Method setUpdateBy = ReflectUtil.getMethod(clazz, "setUpdateBy");
133 | Method getUpdateBy = ReflectUtil.getMethod(clazz, "getUpdateBy");
134 | Method setUpdateTime = ReflectUtil.getMethod(clazz, "setUpdateTime");
135 | Method getUpdateTime = ReflectUtil.getMethod(clazz, "getUpdateTime");
136 |
137 | if (setUpdateBy != null) {
138 | if (override || ObjectUtil.isNull(ReflectUtil.invoke(obj, getUpdateBy))) {
139 | ReflectUtil.invoke(obj, setUpdateBy, "管理员");
140 | }
141 | }
142 | if (setUpdateTime != null) {
143 | if (override || ObjectUtil.isNull(ReflectUtil.invoke(obj, getUpdateTime))) {
144 | ReflectUtil.invoke(obj, setUpdateTime, new Date());
145 | }
146 | }
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/back/src/main/java/com/xkcoding/shiny/util/SpringContextHolderUtil.java:
--------------------------------------------------------------------------------
1 | package com.xkcoding.shiny.util;
2 |
3 | import org.springframework.beans.BeansException;
4 | import org.springframework.context.ApplicationContext;
5 | import org.springframework.context.ApplicationContextAware;
6 | import org.springframework.stereotype.Component;
7 |
8 | /**
9 | * 10 | * Spring的ApplicationContext的持有者,可以用静态方法的方式获取spring容器中的bean 11 | *
12 | * 13 | * @package: com.xkcoding.shiny.util 14 | * @description: Spring的ApplicationContext的持有者, 可以用静态方法的方式获取spring容器中的bean 15 | * @author: yangkai.shen 16 | * @date: Created in 2018/8/25 下午2:40 17 | * @copyright: Copyright (c) 2018 18 | * @version: V1.0 19 | * @modified: yangkai.shen 20 | */ 21 | @Component 22 | public class SpringContextHolderUtil implements ApplicationContextAware { 23 | 24 | private static ApplicationContext applicationContext; 25 | 26 | @Override 27 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 28 | SpringContextHolderUtil.applicationContext = applicationContext; 29 | } 30 | 31 | public static ApplicationContext getApplicationContext() { 32 | assertApplicationContext(); 33 | return applicationContext; 34 | } 35 | 36 | @SuppressWarnings("unchecked") 37 | public static软件名 | 113 |软件版本 | 114 |更新日期 | 115 |城通网盘链接 | 116 |百度网盘链接 | 117 |提取码 | 118 |采集日期 | 119 |
---|
${trData.configName} | 129 |${trData.version} | 130 |${trData.updateTime,"yyyy-MM-dd"} | 131 |132 | @if(trData.ctPanUrl!=null && @cn.hutool.core.util.StrUtil.containsAny(trData.ctPanUrl,"http")){ 133 | 城通网盘 134 | @} 135 | @if(trData.ctPanUrl!=null && !@cn.hutool.core.util.StrUtil.containsAny(trData.ctPanUrl,"http")){ 136 | ${trData.ctPanUrl} 137 | @} 138 | | 139 |140 | @if(trData.bdPanUrl!=null && @cn.hutool.core.util.StrUtil.containsAny(trData.bdPanUrl,"http")){ 141 | 百度网盘 142 | @} 143 | @if(trData.bdPanUrl!=null && !@cn.hutool.core.util.StrUtil.containsAny(trData.bdPanUrl,"http")){ 144 | ${trData.bdPanUrl} 145 | @} 146 | | 147 |${trData.bdPanCode} | 148 |${trData.spiderTime,"yyyy-MM-dd"} | 149 |
18 | * 邮件发送测试类 19 | *
20 | * 21 | * @package: com.xkcoding.shiny.service.impl 22 | * @description: 邮件发送测试类 23 | * @author: yangkai.shen 24 | * @date: Created in 2018/9/6 下午9:06 25 | * @copyright: Copyright (c) 2018 26 | * @version: V1.0 27 | * @modified: yangkai.shen 28 | */ 29 | public class MailServiceImplTest extends ShinyApplicationTests { 30 | @Autowired 31 | private IMailService mailService; 32 | 33 | @Autowired 34 | private ISpiderContentService spiderContentService; 35 | 36 | @Test 37 | public void sendHtmlTemplateMail() throws MessagingException { 38 | SpiderContentPageQuery query = new SpiderContentPageQuery(); 39 | query.setCurrentPage(1); 40 | query.setPageSize(50); 41 | PageResult
23 | * 测试 ChromeDriver
24 | * chromeDriver是谷歌的浏览器驱动,用来适配Selenium,有图形页面存在,在调试爬虫下载运行的功能的时候会相对方便
25 | *
21 | * 测试 PhantomJs
22 | * PhantomJs是一个基于webkit内核的无头浏览器,即没有UI界面,即它就是一个浏览器,只是其内的点击、翻页等人为相关操作需要程序设计实现;
23 | * 因为爬虫如果每次爬取都调用一次谷歌浏览器来实现操作,在性能上会有一定影响,而且连续开启十几个浏览器简直是内存噩梦,
24 | * 因此选用phantomJs来替换chromeDriver
25 | * PhantomJs在本地开发时候还好,如果要部署到服务器,就必须下载linux版本的PhantomJs,相比window操作繁琐
26 | *
20 | * 爬虫测试 21 | *
22 | * 23 | * @package: com.xkcoding.shiny.spider 24 | * @description: 爬虫测试 25 | * @author: yangkai.shen 26 | * @date: Created in 2018/8/15 下午11:44 27 | * @copyright: Copyright (c) 2018 28 | * @version: V1.0 29 | * @modified: yangkai.shen 30 | */ 31 | @Slf4j 32 | public class SpiderTest extends ShinyApplicationTests { 33 | 34 | @Test 35 | public void thingsTest() { 36 | // String url = "http://xclient.info/s/things.html"; 37 | String url = "http://xclient.info/s/vmware-fusion.html"; 38 | Map19 | * xclient.info 采集测试 20 | *
21 | * 22 | * @package: com.xkcoding.shiny.spider 23 | * @description: xclient.info 采集测试 24 | * @author: yangkai.shen 25 | * @date: Created in 2018/8/24 下午6:42 26 | * @copyright: Copyright (c) 2018 27 | * @version: V1.0 28 | * @modified: yangkai.shen 29 | */ 30 | @Slf4j 31 | public class XclientSpiderChromeTest extends ShinyApplicationTests { 32 | @Autowired 33 | private SpiderConfigMapper spiderConfigMapper; 34 | @Autowired 35 | private DriverUtil driverUtil; 36 | 37 | 38 | @Test 39 | public void test() throws InterruptedException { 40 | 41 | long start = System.currentTimeMillis(); 42 | 43 | WebDriver driver = driverUtil.getChromeDriver(); 44 | 45 | SpiderConfigDO spiderConfigDO = spiderConfigMapper.selectByPrimaryKey(20); 46 | 47 | List19 | * xclient.info PhantomJs 采集测试 20 | *
21 | * 22 | * @package: com.xkcoding.shiny.spider 23 | * @description: xclient.info PhantomJs 采集测试 24 | * @author: yangkai.shen 25 | * @date: Created in 2018/8/24 下午6:42 26 | * @copyright: Copyright (c) 2018 27 | * @version: V1.0 28 | * @modified: yangkai.shen 29 | */ 30 | @Slf4j 31 | public class XclientSpiderPhantomJsTest extends ShinyApplicationTests { 32 | @Autowired 33 | private SpiderConfigMapper spiderConfigMapper; 34 | 35 | @Autowired 36 | private DriverUtil driverUtil; 37 | 38 | @Test 39 | public void test() throws InterruptedException { 40 | long start = System.currentTimeMillis(); 41 | 42 | WebDriver driver = driverUtil.getPhantomJSDriver(); 43 | 44 | SpiderConfigDO spiderConfigDO = spiderConfigMapper.selectByPrimaryKey(20); 45 | 46 | List